Compare commits

..

168 Commits

Author SHA1 Message Date
Electron Bot
b27a34eb91 Bump v7.1.0 2019-11-04 16:16:14 -08:00
Samuel Attard
18176b48b4 chore: prepare for 7.1.0 2019-11-04 16:15:24 -08:00
Milan Burda
317f0cec68 fix: cannot access nativeTheme via electron.remote (#20938) (#20961) 2019-11-04 16:11:43 -08:00
Samuel Attard
49009236d9 fix: capture the promise global to avoid userland mutation (#20925) (#20947) 2019-11-04 15:58:55 -08:00
Samuel Attard
976c7d122a feat: add a new contextBridge module (#20789)
* feat: add a new contextBridge module (#20307)

* feat: add a new contextBridge module

* chore: fix docs linting

* feat: add support for function arguments being proxied

* chore: ensure that contextBridge can only be used when contextIsolation is enabled

* docs: getReverseBinding can be null

* docs: fix broken links in md file

* feat: add support for promises in function parameters

* fix: linting failure for explicit constructor

* Update atom_api_context_bridge.cc

* chore: update docs and API design as per feedback

* refactor: remove reverse bindings and handle GC'able functions across the bridge

* chore: only expose debugGC in testing builds

* fix: do not proxy promises as objects

* spec: add complete spec coverage for contextBridge

* spec: add tests for null/undefined and the anti-overwrite logic

* chore: fix linting

* spec: add complex nested back-and-forth function calling

* fix: expose contextBridge in sandboxed renderers

* refactor: improve security of default_app using the new contextBridge module

* s/bindAPIInMainWorld/exposeInMainWorld

* chore: sorry for this commit, its a big one, I fixed like everything and refactored a lot

* chore: remove PassedValueCache as it is unused now

Values transferred from context A to context B are now cachde in the RenderFramePersistenceStore

* chore: move to anonymous namespace

* refactor: remove PassValueToOtherContextWithCache

* chore: remove commented unused code blocks

* chore: remove .only

* chore: remote commented code

* refactor: extract RenderFramePersistenceStore

* spec: ensure it works with numbered keys

* fix: handle number keys correctly

* fix: sort out the linter

* spec: update default_app asar spec for removed file

* refactor: change signatures to return v8 objects directly rather than the mate dictionary handle

* refactor: use the v8 serializer to support cloneable buffers and other object types

* chore: fix linting

* fix: handle hash collisions with a linked list in the map

* fix: enforce a recursion limit on the context bridge

* chore: fix linting

* chore: remove TODO

* chore: adapt for PR feedback

* chore: remove .only

* chore: clean up docs and clean up the proxy map when objects are released

* chore: ensure we cache object values that are cloned through the V8 serializer

* docs: mark contextBridge as experimental (#20638)

* docs: mark contextBridge as experimental

This commit didn't make it to the original PR, quick addition here

* Update context-bridge.md

* chore: update for 7-0-x differences

* chore: update callback header

* chore: add v8 serializer converter, cherry picked from 2fad53e66b

* chore: update for 7-0-x differences
2019-11-04 14:56:03 -08:00
Samuel Attard
ef548b6592 chore: prepare for 7.1.0 2019-11-04 14:35:16 -08:00
trop[bot]
37c1df6ce1 fix: don't copy tray image when it's set (#20935) 2019-11-04 14:17:15 -08:00
Electron Bot
d9068b7175 chore: bump chromium to 78.0.3904.94 (7-0-x) (#20930)
* chore: bump chromium in DEPS to 78.0.3904.93

* chore: bump chromium in DEPS to 78.0.3904.94
2019-11-04 09:35:39 -05:00
Electron Bot
cac0a4fe3c Bump v7.0.1 2019-11-01 09:46:44 -07:00
John Kleinschmidt
e6807b387c ci: Revert CircleCI changes (#20916)
* Revert "build: lengthen wait times and retries for CircleCI releases (#20893)"

This reverts commit 41b32cf5d9.

* Revert "ci: verify CircleCI job number before returning job url (#20864)"

This reverts commit b97c3aca2d.

* Revert "build: run publish jobs in the secure context and enable sccache (#20863)"

This reverts commit 055b5d274e.

* Revert "ci: use CircleCI 2.1 config and v2 APIs (#20852)"

This reverts commit 1841742586.
2019-11-01 12:44:53 -04:00
Electron Bot
f6f73a5a78 Revert "Bump v7.0.1"
This reverts commit 7bad919bee.
2019-11-01 08:28:33 -07:00
Electron Bot
7bad919bee Bump v7.0.1 2019-11-01 08:09:20 -07:00
Electron Bot
667db6fa67 chore: bump chromium in DEPS to 78.0.3904.92 (#20913) 2019-11-01 11:06:43 -04:00
John Kleinschmidt
022ee3793b build: allow CircleCI timeout and retry to be set via env variables (7-0-x) (#20912)
* build: allow circleci timeout and retry to be set via env variables

* check for more statuses and run indefinitely
2019-11-01 11:05:57 -04:00
Electron Bot
5c0e8c5fd3 Revert "Bump v7.0.1"
This reverts commit 961436f300.
2019-11-01 05:09:48 -07:00
Electron Bot
961436f300 Bump v7.0.1 2019-11-01 05:07:26 -07:00
trop[bot]
e2c7e4b1ad fix: use Unicode version of ShellExecute() in OpenExternalOnWorkerThread() (#20905) 2019-11-01 08:05:57 -04:00
Electron Bot
d12b0eefe0 Revert "Bump v7.0.1"
This reverts commit 8dfb8c5589.
2019-10-31 13:22:22 -07:00
Electron Bot
8dfb8c5589 Bump v7.0.1 2019-10-31 13:19:55 -07:00
John Kleinschmidt
57bb08e084 Revert "Bump v7.0.1" (#20895)
This reverts commit 0de78019c8.
2019-10-31 15:11:45 -04:00
Electron Bot
03e0905519 Revert "Bump v7.0.2"
This reverts commit b6717a6644.
2019-10-31 12:07:12 -07:00
Electron Bot
b6717a6644 Bump v7.0.2 2019-10-31 11:57:41 -07:00
trop[bot]
41b32cf5d9 build: lengthen wait times and retries for CircleCI releases (#20893)
* build: lengthen wait times and retries for CircleCI releases

* Review suggestions
2019-10-31 14:53:05 -04:00
trop[bot]
176f4728d7 docs: clean up performance checklist formatting (#20887)
* docs: fix list formatting in performance checklist

* docs: remove unused link ref
2019-10-31 09:52:42 -07:00
Electron Bot
0de78019c8 Bump v7.0.1 2019-10-31 09:02:29 -07:00
trop[bot]
1926169c91 fix: swapped labels on open/save gtkdialog (#20882) 2019-10-31 08:42:35 -07:00
Electron Bot
25b3ee29cf chore: bump chromium in DEPS to 78.0.3904.88 (#20873) 2019-10-31 10:54:20 -04:00
trop[bot]
2228e5ac65 build: do not try to run non existent VSTS release builds (#20877) 2019-10-31 10:04:53 -04:00
Electron Bot
92cace3998 Revert "Bump v7.0.1"
This reverts commit 7dc858be02.
2019-10-30 17:06:52 -07:00
Electron Bot
7dc858be02 Bump v7.0.1 2019-10-30 17:05:00 -07:00
Electron Bot
7ffa127f0f Revert "Bump v7.0.1"
This reverts commit f423312090.
2019-10-30 17:01:39 -07:00
Electron Bot
f423312090 Bump v7.0.1 2019-10-30 17:00:10 -07:00
Electron Bot
4cacd15730 Revert "Bump v7.0.1"
This reverts commit 37eeaf32ad.
2019-10-30 16:45:49 -07:00
Electron Bot
37eeaf32ad Bump v7.0.1 2019-10-30 16:42:36 -07:00
trop[bot]
b97c3aca2d ci: verify CircleCI job number before returning job url (#20864) 2019-10-30 19:40:01 -04:00
Electron Bot
2e07877c28 Revert "Bump v7.0.1"
This reverts commit d8bd7654c6.
2019-10-30 16:05:51 -07:00
Electron Bot
d8bd7654c6 Bump v7.0.1 2019-10-30 16:00:48 -07:00
Electron Bot
f979e0cfbc Revert "Bump v7.0.1"
This reverts commit 1582824d33.
2019-10-30 15:59:42 -07:00
Electron Bot
1582824d33 Bump v7.0.1 2019-10-30 15:50:34 -07:00
John Kleinschmidt
71009fd61e docs: Update the sccache name (#20860)
* docs: Update the sccache name (#20462)

(cherry picked from commit b3e7657159)

* Update sccache name in circleCI
2019-10-30 18:48:55 -04:00
trop[bot]
055b5d274e build: run publish jobs in the secure context and enable sccache (#20863) 2019-10-30 18:45:47 -04:00
trop[bot]
1841742586 ci: use CircleCI 2.1 config and v2 APIs (#20852)
* ci: use circleci 2.1

* Check for pipeline status and add comments
2019-10-30 17:33:50 -04:00
Birunthan Mohanathas
3841ac9b6d fix: Disable compositor recycling only for attached views (7-0-x) (#20846)
Backport of #20829

Notes: Fix flicker when switching between `BrowserView`s
2019-10-30 16:56:49 -04:00
trop[bot]
ed1c2a47f1 build: optimize the CI path where we update the patch files (#20854)
Currently the happy checkout takes 7 minutes and the sad checkout takes
30 minutes.  This updates our CI to run checkout twice for every job to
make the sad checkout take nearer 10 minutes instead.
2019-10-30 15:43:05 -04:00
Electron Bot
bcc4f67784 chore: bump chromium to 78.0.3904.86 (7-0-x) (#20823)
* chore: bump chromium in DEPS to 78.0.3904.83

* chore: bump chromium in DEPS to 78.0.3904.86
2019-10-30 12:17:18 -04:00
Milan Burda
771d4dc374 fix: devtools extensions not loading (#20791) (#20844) 2019-10-30 11:35:50 -04:00
Milan Burda
b1fb7c7bfb fix: properly generate requestID in webContents.printToPDF() (#20769) (#20810) 2019-10-30 14:38:29 +09:00
Milan Burda
725dac35ab fix: pass frameId to v8Util.setRemoteCallbackFreer() (#20732) (#20814) 2019-10-30 14:35:37 +09:00
trop[bot]
6e32da3798 fix: prevent menu gc during popup (#20808) 2019-10-29 16:25:08 +09:00
trop[bot]
32ac551ca5 fix: deprecation warnings in Electron code (#20804) 2019-10-29 15:39:05 +09:00
trop[bot]
b90ac55d2d docs: the ipc main listener being removed can have args (#20806) 2019-10-29 15:35:06 +09:00
Electron Bot
e797639d6d chore: bump chromium to 78.0.3904.82 (7-0-x) (#20758) 2019-10-28 10:46:28 -07:00
trop[bot]
a31d041f03 docs: add the performance doc to the table of contents (#20748) 2019-10-28 10:27:35 -04:00
trop[bot]
6b70f0e8e6 docs: Performance checklist (#20757)
* docs: First draft of perf checklist

* docs: More words

* docs: Use standard in code example

* docs: fix broken link

* Update docs/tutorial/performance.md

Co-Authored-By: Charles Kerr <ckerr@github.com>

* Update docs/tutorial/performance.md

Co-Authored-By: Charles Kerr <ckerr@github.com>

* Update docs/tutorial/performance.md

Co-Authored-By: loc <andy@slack-corp.com>

* Update docs/tutorial/performance.md

Co-Authored-By: loc <andy@slack-corp.com>

* docs: Implement suggestions

* docs: Include VSCode talk

* chore: Pass linter

* Update docs/tutorial/performance.md

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

* Update docs/tutorial/performance.md

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

* Update docs/tutorial/performance.md

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

* Update docs/tutorial/performance.md

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

* Update docs/tutorial/performance.md

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

* Update docs/tutorial/performance.md

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

* Apply suggestions from code review

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

* Update performance.md

* fix: The process link
2019-10-28 09:56:55 -04:00
trop[bot]
b1357ab12b docs: fix process.getSystemVersion() type (#20768) 2019-10-27 11:21:03 -07:00
Electron Bot
ffdec7a661 chore: bump chromium to 78.0.3904.78 (7-0-x) (#20722) 2019-10-25 09:22:52 -07:00
Milan Burda
50822bc8d4 fix: send ELECTRON_BROWSER_CONTEXT_RELEASE asynchronously (#20632) (#20715) 2019-10-24 09:50:48 +09:00
trop[bot]
85164223cb chore: update build_bring_back_node_with_ltcg_configuration.patch (#20708)
* chore: update build_bring_back_node_with_ltcg_configuration.patch

set default value for node_with_ltcg=true

* fix: move ltcg definition to Release configuration
2019-10-23 17:19:16 -07:00
Jeremy Apthorp
5cb6ba2883 chore: bump chromium to 78.0.3904.68 (7-0-x) (#20643)
* chore: bump chromium to 78.0.3904.68

* update chromium patches

* explicitly cancel redirects when the mode is 'error'
2019-10-23 13:53:11 -04:00
Jeremy Apthorp
e23030b69e fix: properly free remote objects (7-0-x) (#20693) 2019-10-23 10:31:48 -07:00
trop[bot]
d417bbdcfd fix: use xib file to construct macOS Menu (#20670)
* fix: use xib file to construct macOS Menu

* add nib files back to zip manifests

* address final review comments
2019-10-22 16:48:36 +09:00
trop[bot]
e6f92f3f30 ci: add macOS debug builds (#20573)
* ci: add macOS debug builds

* Fix mac debug builds

* Fix debug build

* Update comment for desktop_capturer (from #19848)
2019-10-21 16:52:51 -04:00
Robo
3b59f12495 fix: backport libuv patch for fs.mkdir/mkdirSync on invlaid names (#20629)
Backports https://github.com/libuv/libuv/pull/2375
2019-10-21 15:43:47 -04:00
Electron Bot
3083693e67 Bump v7.0.0 2019-10-21 12:36:53 -07:00
Robo
2a2f7e7090 fix: add patch to node for native module size issue on windows (#20614) (#20626) 2019-10-18 14:40:16 -07:00
Milan Burda
f4c697d7a1 test: skip desktopCapturer / remote module tests when the features are disabled (#20576) 2019-10-16 08:09:13 -07:00
Electron Bot
944690e79b Bump v7.0.0-beta.7 2019-10-15 11:08:05 -07:00
trop[bot]
ae303ade7d spec: allow "Yu Gothic" as a Japanese sans-serif font on Windows (#20570) 2019-10-14 12:38:27 -07:00
trop[bot]
19162f4bac fix: append network switches to network service process (#20558) 2019-10-13 21:09:14 -07:00
trop[bot]
ee53f8cef6 fix: do not manually parse content-type (#20544) 2019-10-11 16:03:15 -07:00
trop[bot]
4463715714 fix: properly register custom url evt handling (#20523) 2019-10-10 23:15:53 +02:00
Milan Burda
f6894da715 fix: when building with enable_plugins=false (#20507) 2019-10-10 14:11:17 +02:00
Jaime Bernardo
1657908fa8 build: fix build with Visual Studio 2019 (7-0-x) (#20502)
* fix: build angle dependency with VS 2019

Applies upstream patch to angle, fixing build errors when building
the angle dependency with the STL shipped with Visual Studio 2019.

Can be removed after this commit comes from upstream:
755417dd79

* fix: build v8 dependency with VS 2019

Applies upstream patch to v8, fixing build errors when building
the v8 dependency with the STL shipped with Visual Studio 2019.

Can be removed after this commit comes from upstream:
53e62affd3

* fix: build perfetto dependency with VS 2019

Applies upstream patch to perfetto, fixing build errors when building
the perfetto dependency with the STL shipped with Visual Studio 2019.

Can be removed after this commit comes from upstream:
f10b2053be

* fix: build quiche dependency with VS 2019

Applies upstream patch to quiche, fixing build errors when building
the quiche dependency with the STL shipped with Visual Studio 2019.

Can be removed after this commit comes from upstream:
https://quiche.googlesource.com/quiche/+/c1e9121f16559b084bb80afc6922f0316d082160
2019-10-09 22:32:38 +02:00
Cheng Zhao
26d059b3ea fix: cookies.get should be able to filter domain (#20471) (#20496)
* fix: use GetAllCookies when url is empty

* test: get cookie without url
2019-10-09 11:32:01 -04:00
Electron Bot
49aaa2fe96 Bump v7.0.0-beta.6 2019-10-08 15:19:26 -07:00
Samuel Attard
0a9b201c34 feat: nativeTheme.themeSource and a few nativeTheme fixes (#20486)
* feat: add nativeTheme.themeSource to allow apps to override Chromiums theme choice (#19960)

* feat: add nativeTheme.shouldUseDarkColorsOverride to allow apps to override Chromiums theme choice

* spec: add tests for shouldUseDarkColorsOverride

* chore: add missing forward declarations

* refactor: rename overrideShouldUseDarkColors to themeSource

* chore: only run appLevelAppearance specs on Mojave and up

* chore: update patch with more info and no define

* Update spec-main/api-native-theme-spec.ts

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

* Update api-native-theme-spec.ts

* Update api-native-theme-spec.ts

* Update api-native-theme-spec.ts

* fix: don't expose nativeTheme in the renderer process (#20139)

Exposing these in the renderer didn't make sense as they weren't backed
by the same instance / value store.  This API should be browser only
especially now that we have nativeTheme.themeSource.  Exposing in
//common was a mistake from the beginning.

* fix: emit updated on NativeTheme on the UI thread to avoid DCHECK (#20137)

* fix: emit updated on NativeTheme on the UI thread to avoid DCHECK

* Update atom_api_native_theme.cc

* spec: wait a few ticks for async events to emit so that test events do not leak into each other

* chore: add SetGTKDarkThemeEnabled(enabled) internal helper to allow dynamic theme selection on linux (#19964)

This is just a after-creation setter for the `darkTheme` constructor option.  This is delibrately
a method and not a property as there is no getter.

* spec: remove leftover .only
2019-10-08 18:18:00 -04:00
Shelley Vohr
e17cd837ef fix: enable worker threads in ELECTRON_RUN_AS_NODE (#20456) 2019-10-08 15:08:46 -04:00
trop[bot]
981208b66c fix: properly free IsolateData in node_main (#20476) 2019-10-08 14:30:15 +02:00
Robo
77af675511 fix: fs.watch() behavior change in node >= 10.16.0 (#20430)
This reverts the patch from https://github.com/electron/node/pull/100
which never got merged due to reasons outlined in https://github.com/libuv/libuv/pull/2313

* Adds new patches that backports https://github.com/libuv/libuv/pull/2459
  and https://github.com/libuv/libuv/pull/2460

Based on https://github.com/nodejs/node/issues/29460
2019-10-07 13:06:08 -07:00
trop[bot]
a92ee9443d test: close window before destroying browserView (#20420) 2019-10-04 10:26:32 +02:00
trop[bot]
23a52c02a3 fix: recentDocuments menu role on macOS (#20410) 2019-10-03 09:52:24 +02:00
Milan Burda
8536f62826 fix: allow paths to asar archives to contain the .asar extension in directories (#20342) (#20401) 2019-10-02 18:03:44 +09:00
trop[bot]
312f14ee88 fix: correctly crash when there is no crashReporter (#20395)
* fix: correctly crash when there is no crashReporter

* test: correctly crash when there is crashReporter
2019-10-01 15:23:16 -04:00
Birunthan Mohanathas
1f660c67c6 fix: Make the --disable-color-correct-rendering switch work again (backport) (#20359) 2019-09-30 10:47:05 -07:00
Shelley Vohr
325bdfaf23 fix: free screen capturers after usage ends (#20280)
* fix: free screen and window capturers immediately after we're finished with them (#20156)

fix #17937, #19908

* fix: reset capturers at the very end (#20270)
2019-09-25 10:10:44 -04:00
trop[bot]
e3dcdba2db fix: correct 'Entire screen' to ' Entire Screen' (#20302) 2019-09-20 07:44:43 -07:00
John Kleinschmidt
6b5a2c550a ci: actually kill leftover processes on WOA testing (#20289)
* ci: only kill WOA processes if they are running

(cherry picked from commit 844752cd97)

* ci: actually kill leftover processes on WOA testing

(cherry picked from commit a76d2d8e53)
2019-09-19 14:34:32 -04:00
trop[bot]
21e702a563 docs: improve and add examples for clipboard (#20279)
* docs: improve and add examples for clipboard

* address feedback from jkleinsc review
2019-09-18 16:31:00 -07:00
Electron Bot
f79cfae3c2 Bump v7.0.0-beta.5 2019-09-18 13:43:24 -07:00
trop[bot]
51ffe25f45 build: add WOA node headers to checksum file (#20261) 2019-09-18 16:23:13 -04:00
Electron Bot
0a0d7a8202 chore: bump chromium to 78.0.3905.1 (7-0-x) (#20062)
* chore: bump chromium in DEPS to 78.0.3899.1

* chore: bump chromium in DEPS to 78.0.3900.1

* chore: bump chromium in DEPS to 78.0.3900.2

* chore: bump chromium in DEPS to 78.0.3901.1

* chore: bump chromium in DEPS to 78.0.3902.1

* chore: remove tts.patch

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

* build: disable widevine cdm component

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

* chore: bump chromium in DEPS to 78.0.3903.1

* build: redo network_context.h mojification

187df411f2%5E%21/#F7

* build: disable widevine

Disable widevine, atleast for the moment by deleting the patch and removing
the build argument.

> At the moment its horribly broken, we would have to look into fixing on all
> three platforms now that upstream also supports linux.

* chore: bump chromium in DEPS to 78.0.3904.1

* update pepper_flash.patch

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

* chore: bump chromium in DEPS to 78.0.3905.1

* Update patches

* Convert Web Speech Synthesis API over to Mojo

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

* Update patches

* CookieInclusionStatus: Support warnings and multiple exclusion reasons

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

* Pass request_unadjusted_movement to lock mouse

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

* chore: rename thread_pool to thread_pool_instance

Refs: https://chromium-review.googlesource.com/c/chromium/src/+/1773663
(cherry picked from commit 8547b09de8)

* Remove the typemap from network::mojom::URLResponseHead.

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

* ServiceWorker: Make Extension WebRequestAPI aware of service worker update check script requests

https://chromium-review.googlesource.com/c/chromium/src/+/1782230
(cherry picked from commit 615d33517a)

* Convert CertVerifierClient to new Mojo types

https://bugs.chromium.org/p/chromium/issues/detail?id=955171
(cherry picked from commit ac5e8dbce5)

* Convert DataPipeGetterPtr and DataPipeGetterRequest to new Mojo types

https://chromium-review.googlesource.com/c/chromium/src/+/1787760
https://chromium-review.googlesource.com/c/chromium/src/+/1787659
(cherry picked from commit 8611783898)

* Add tts patch

* build: fix compilation with MSSTL

(cherry picked from commit 4d8cb7de9b)
2019-09-18 16:04:23 -04:00
trop[bot]
421490c6b3 fix: strip chrome-sandbox typo (#20258) 2019-09-18 09:44:02 -07:00
trop[bot]
068e12d909 fix: crash when exiting simple fullscreen on macOS (#20220) 2019-09-17 08:59:32 -07:00
trop[bot]
d251642c83 build: handle arm64 node headers (#20193)
* build: handle arm64 node headers

(cherry picked from commit ff1f224d96)

* node.lib for arm64 needs to go to specific dir
2019-09-11 17:03:49 -04:00
trop[bot]
27ceeb5e94 build: get all the release assets when looking for one to delete (#20164)
* build: get all the release assets when looking for one to delete

yeah we totally have more than 30....

* Update upload-to-github.js
2019-09-09 06:14:57 -07:00
trop[bot]
4ac616b681 fix: resolve crash loading file based serviceworkers (#20142) 2019-09-05 21:15:17 -07:00
trop[bot]
fc677b7cf6 fix: Debug builds on Windows. (#20140) 2019-09-05 18:02:40 -07:00
trop[bot]
d25e511fc0 fix: ensure document.visibilityState aligns with the visibility of the TopLevelWindow (#20134)
* fix: ensure document.visibilityState aligns with the visibility of the TopLevelWindow

* chore: disable the specs on linux on CI
2019-09-05 16:46:35 -07:00
trop[bot]
b4ba2f6d55 build: don't wait until job requests return in case some jobs fail to return (#20136) 2019-09-05 14:01:36 -04:00
John Kleinschmidt
f967d73a13 ci: run tests on WOA hardware (7-0-x) (#20091)
* ci: run tests on WOA hardware (#20031)

* ci: run tests on WOA hardware

* Temporarily disable test until #20008 is resolved

* deterministically run tests in sorted order

(cherry picked from commit bedc5f7da9)

* use request instead of blur to detect openExternal success

* use blur event on mac, sigh

* oh, right, still gotta open an actual url

* Disable test until #20008 is resolved
2019-09-04 19:22:29 -04:00
trop[bot]
c923aa2fde fix: ensure modeL_ exists before calling delegate methods (#20116)
This is a speculative fix for a crash we are seeing in `menuDidClose`.  We
can't repro the crash but the traces have it happening in this method
and just by reading through the impl the only part that jumps out as
Might Crash is this `model_` call.  Other methods in the menu controller
check `model_` before using it so it probably makes sense to do that here
as well.
2019-09-04 15:21:10 -07:00
trop[bot]
dec2078e54 build: add WOA release to list of releases (#20112)
* build: add WOA release to list of releases

* Add job count info for sudowoodo

* Add verification of all assets

* Fix linting and add logic to wait before printing out results
2019-09-04 14:32:46 -07:00
Cheng Zhao
2d16034854 fix: implement ses.getBlobData() for NetworkService (#20041) (#20105)
* pass data pipe to JS

* implement reading buffer

* re-enable ses.getBlobData test

* remove AtomBlobReader
2019-09-04 08:39:06 -07:00
trop[bot]
4ce431829f Revert "fix: make sure that menu bar gets focus even when you click an item to focus it first (#19710)" (#20036)
This reverts commit 27b2747b61.
2019-09-03 23:19:46 -07:00
trop[bot]
430b355258 fix: strip chrome_sandbox executable (#20083) 2019-09-03 09:49:34 -07:00
trop[bot]
638ca05702 fix: ensure that the "top" coordinate of the inner frame is correct (#20053)
On multi-monitor setups where the monitors are not all origined at 0 on
the Y coordinate (E.g. vertical stacked monitors) the maximize
calculation was incorrect as it assumed top was "0".  This instead
adjusts the math to calculate the correct top value.
2019-08-30 17:05:23 -07:00
Electron Bot
9e7cce3d2b Bump v7.0.0-beta.4 2019-08-30 09:59:13 -07:00
Electron Bot
c7a3142bab chore: bump chromium to 78.0.3896.6 (7-0-x) (#19609)
* chore: Bump 78.0.3894.0

* chore: bump chromium to 32e0bab929213da1019992bf31d29 (master) (#19488)

* chore: bump chromium to cbeb16cf544f79c1990f1eae4d4fe (master) (#19610)

Co-authored-by: Erick Zhao <erickzhao@github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
Co-authored-by Micha Hanselmann <DeerMichel@github.com>

* chore: bump chromium to 62327c655093c821aa0fcfc6db53f5fd943e08c7 (master) (#19792)

* chore: bump chromium in DEPS to f3bf493731e868e1f5f48e7e1adc02ea5eccfbbd

* chore: bump chromium in DEPS to 4db0c87d4aa6f27ffa0b5fc77d20e10047962484

* chore: bump chromium in DEPS to d933a504c264dc8fe85267f47aef3588531875b5

* chore: bump chromium in DEPS to 34afdb68980f581ae911b85b727bc17e126cf5f9

* update disable-redraw-lock.patch

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

* update desktop_media_list.patch

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

* update notification_provenance.patch

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

* update printing.patch

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

* update verbose_generate_bpad_syms.patch

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

* update patch metadata

* remove printing_compositor manifests

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

* update for URLLoaderFactoryType enum

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

* remove gin string16 converter

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

* ClearCompositorFrame() has been removed

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

* message_loop -> message_loop_current

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

* include resource_response header

* pdf compositor no longer uses service manager

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

* chore: bump chromium in DEPS to 00d5933101d8d8dc9546eadbe7ee1b41077e6db1

* pane focus fns aren't pure virtual anymore

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

* fix: make std::hash value-non-const

broken by https://chromium-review.googlesource.com/c/chromium/src/+/1711202

* update swiftshader in zip_manifests

https://swiftshader-review.googlesource.com/c/SwiftShader/+/34911

* address feedback from @deepak1556

* don't enable kLegacyWindowsDWriteFontFallback

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

* chore: bump chromium in DEPS to 84497314005e1968da06804f8fde539d9872310e

* update printing.patch

remove bottom diff owing to https://chromium-review.googlesource.com/c/chromium/src/+/1678182 and update for https://chromium-review.googlesource.com/c/chromium/src/+/1678182

* convert CookieChangeListener to new Mojo types

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

* rename ui::ClipboardType -> ui::ClipboardBuffer

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

* logging::LoggingSettings log_file -> log_file_path

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

* roll DEPS to latest lkgr

* fix: override GetFontLookupTableCacheDir()

When Chromium goes to use its fallback font table creation code paths,
it creates the cache directory it uses by calling
GetFontLookupTableCacheDir() with a path that doesn't exist in Electron.
To ensure that a legitimate file path is created, we need to override it
with Electron's DIR_USER_DATA so it doesn't use chrome::DIR_USER_DATA.

* chore: bump chromium in DEPS to 6758a0879931bc4df630a80a36c82d7855ae3155

* update pthread_fchdir patch

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

* update printing patch

* update cookie usage and fn signatures

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

* chore: bump chromium in DEPS to bdaca97e1cc27fb977e56f30f74cdb906da9527e

* remove fix_make_std_hash_value-non-const.patch

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

* Convert enum to enum class for FocusManager::FocusChangeReason

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

* roll DEPS to latest lkgr

* update dom_storage_limits.patch

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

* chore: remove pre network service classes from shell/browser/net (#19644)

* refactor: rm IOThread class

* chore: rm expose-net-observer-api.patch

* chore: rm unused shell/browser/net/ classes

* chore: mv CertVerifierClient to separate header

* chore: rm url_request_context_getter references

* chore: update patches

* Require task posters to specify an explicit destination

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

* chore: Revert "Cleanup: Remove Menu Subtitles/Sublabels"

* chore: Bump chromium 78.0.3896.0

* build: add checkout_openxr=False to DEPS

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

* chore: update patches

* Convert TrustedURLLoaderHeaderClient and TrustedHeaderClient to new mojo types

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

* skia: more rect api simplifications

https://skia-review.googlesource.com/c/skia/+/237038

* iwyu

* test: fix clearAuthCache test (#20015)

* fix: nws13n: make ses.setUserAgent work  (#20014)

* refactor tests to better control window creation

* fix: nws13n: make ses.setUserAgent work

* chore: update v8 patches

* Add enterprise policy for renderer CIG.

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

* Convert enum to enum class for Wigdet::FrameType

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

* [JJI] Convert to use string16 for data from JavaScript/Java

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

* chore: Bump chromium 78.0.3896.6
2019-08-30 12:57:57 -04:00
trop[bot]
b6f5e26eab fix: honor cursor blink rate (#20044)
* fix: honor cursor blink rate on macOS

* fix: honor cursor blink rate on Linux

* fix: honor cursor blink rate on Windows

* refactor: clean up os_win cursor blink logic

* remove unneeded include
2019-08-30 08:41:01 -07:00
Cheng Zhao
3330647834 chore: cache URLLoaderFactory per-session (#19998) (#20021)
* cache the URLLoaderFactory in AtomBrowserContext

* use cached loader factory in AtomURLLoaderFactory
2019-08-29 15:21:09 -07:00
Eugene
bb8c7dfc7e fix: allow unsandboxed renderers to request new privileges (7-0-x) (#19999)
* fix: allow unsandboxed renderers to request new privileges

* add test
2019-08-29 08:27:18 -07:00
trop[bot]
4dea193854 fix: i18n of gtk msgbox buttons (#19982)
* fix: i18n of gtk msgbox buttons

similar to #19756 (12df0e8) but for messageboxes

* refactor: DRY the gtk+ button mnemonics

* fix: don't compile gtk_util on non-Linux platforms

rename from `gtk_util.[cc,h]` to `util_gtk.[cc,h]` so that it gets
picked up by the `extra_source_filters` rule in `BUILD.gn`.

* fix: make linter happy

It really shows that I cannot build locally atm... :P
2019-08-29 16:19:22 +09:00
trop[bot]
080c2c9218 fix: gtk_init() called 2x in AtomBrowserMainParts (#20012)
Fixes #19984.
2019-08-29 15:49:28 +09:00
Heilig Benedek
182f63d3a3 fix: handle WM_GETMINMAXINFO instead of letting chromium do it (#19928) (#20000)
* fix: remove WM_GETMINMAXINFO workaround since it's no longer needed

* fix: handle WM_GETMINMAXINFO ourselves

* fix: remove part of the chromium WM_GETMINMAXINFO handler
2019-08-28 09:31:55 -05:00
Robo
d3e0c461f6 feat: migrate webRequest module to NetworkService (#19979)
* feat: associate InProgressRequest with requests (#19648)

* feat: migrate webRequest module to NetworkService (Part 4) (#19679)

* chore: use gin in WebRequest

* Add stubs for APIs

* feat: migrate webRequest module to NetworkService (Part 5) (#19714)

* Pass WebRequest to ProxyingURLLoaderFactory

* Call WebRequestAPI in InProgressRequest

* Store the listeners

* Pass the request and response

* Add stub to handle the events

* Use extensions::WebRequestInfo

* Make sure webRequest is managed by Session

* chore: make creation of WebRequestNS more clear

* fix: check WebContents for service workers

* feat: migrate webRequest module to NetworkService (Part 6) (#19752)

* Implement OnBeforeSendHeaders

* Pass the request

* Handle simple listeners

* Handle response listeners

* Read responses from listener

* feat: migrate webRequest module to NetworkService (Part 7) (#19820)

* fix: gin treats Function as Dictionary when doing convertions

* fix: check if listener exists

* fix: listener callback should be executed in next tick

* feat: make InProgressRequest work

* test: re-enable protocol test that relies on webRequest

* chore: merge conditions

* feat: migrate webRequest module to NetworkService (Part 8) (#19841)

* fix: fill uploadData property

* fix: requestHeaders in onBeforeSendHeaders

* fix: responseHeaders in onHeadersReceived

* fix: header keys should not be lowercased

* fix: gin::Dictionary::Get succeeds even though key does not exist...

* fix: throw for invalid filters

* test: re-enable api-web-request-spec

* chore: do not use deprecated base::Value API

* feat: migrate webRequest module to NetworkService (Part 9) (#19976)

* no need to get WebContents for URLLoaderFactory

* consult embedder for network_factory created in net module

* set disable_web_security to false

* re-enable webRequest tests in net module
2019-08-27 16:38:15 -04:00
Jeremy Apthorp
b09a1c7607 feat: HTTP preconnect feature minimal for electronjs (#19952)
* feat: HTTP preconnect feature minimal for electronjs

* fix type of PreconnectRequest::PreconnectRequest impl

* roll back past https://chromium-review.googlesource.com/c/chromium/src/+/1713306

* mark docs as experimental

* fix lint
2019-08-27 10:09:31 -05:00
trop[bot]
7cc1efd2e6 fix: don't call SetBounds on restore (#19957) 2019-08-27 07:52:03 -07:00
trop[bot]
324096aa37 fix: ensure that reloads retain modified window background colors (#19974) 2019-08-27 07:50:35 -07:00
Shelley Vohr
d780a16d78 fix: add default media usage strings to info.plist (#19948) 2019-08-27 10:36:05 -04:00
trop[bot]
005ef96ac0 fix: command-line scheme switch values' spillover (#19941)
* fix: command-line scheme switch values' spillover

The value of one of the scheme command-line switches
shouldn't spill over into other switches.

Fixes #19911

* chore: make linter happy
2019-08-26 10:46:35 -07:00
trop[bot]
4f74be084a fix: adjust window size in NCCALCSIZE instead of adding insets (#19942) 2019-08-26 10:07:54 -07:00
trop[bot]
b7c2188d09 fix: crash on input file handler dialog (#19917)
* fix: crash on input file handler dialog

* invert cancellation logic
2019-08-24 18:04:24 -05:00
trop[bot]
192326c7c5 docs: clarify dock.bounce usage (#19907) 2019-08-23 15:24:55 -07:00
Heilig Benedek
1af064a144 feat: enable picture-in-picture mode for video tags (#19914) 2019-08-23 15:24:42 -07:00
trop[bot]
6061fcce40 build: use a lower process count for publish builds with no sccache (#19916) 2019-08-23 14:02:04 -07:00
Samuel Attard
e68a9486da fix: remove white screen flicker by disabling compositor recycling (#19901) 2019-08-23 01:14:36 -07:00
trop[bot]
dd8bcb67ba fix: notify views of content view size change (#19898) 2019-08-22 15:54:39 -07:00
trop[bot]
27661d8e7b fix: extern Parse impl for Windows debug builds (#19895)
* fix: extern Parse impl for Windows debug builds

Applies a patch to node.
Externs node::options_parser::Parse implementation for
node::DebugOptions to fix the Windows Debug build.

* fixup: merge extern parse impl patch
2019-08-22 14:56:01 -07:00
trop[bot]
94ddcc4742 build: start building Windows on Arm builds (#19874) 2019-08-22 08:01:54 -07:00
trop[bot]
2515087322 build: ninja count should be 2*cores + 2 (#19866) 2019-08-21 14:02:59 -05:00
trop[bot]
36a5ba0d4d fix: race condition in NodeStreamLoader (#19869)
* fix: race condition in NodeStreamLoader

* nit: add comments
2019-08-21 10:27:20 -07:00
trop[bot]
241b2a98af fix: trim branch name before comparing to master (#19855) 2019-08-20 19:01:16 -07:00
trop[bot]
9b2e3d1d0b docs: update documentation under tutorials (#19844) 2019-08-20 11:08:39 -07:00
trop[bot]
67cb05b435 chore: bump node to v12.8.1 (7-0-x) (#19835)
* chore: bump node in DEPS to v12.8.1

* test: disable parallel/test-http2-reset-flood

Disabled new Worker test owing to a threading issue where the Worker
segfaults on worker.on('message', () => {}). We've disabled failing
worker tests previously as we don't offer first-class support for them
in Electron.
2019-08-19 19:40:24 -07:00
trop[bot]
3f5222b047 fix: fall back to default logs path in getPath('logs') (#19836) 2019-08-19 19:02:04 -07:00
trop[bot]
28e7e6492d chore: upgrades-wg owns DEPS (#19833) 2019-08-19 14:04:04 -07:00
Pedro Pontes
23f7f63405 fix: always use new site instance for a new navigation (backport). (#19827) 2019-08-19 13:20:18 -07:00
trop[bot]
99eaa0d1bb add missing return desc (#19800) 2019-08-16 13:26:04 -07:00
trop[bot]
543dbaf412 MessageBoxOptions.icon should allow string (#19797) 2019-08-16 13:25:35 -07:00
trop[bot]
5901293628 docs: add exemplary fiddle for launch in fiddle feat (#19785)
* add fit-screen

* new url format

* nit
2019-08-16 08:56:18 -07:00
trop[bot]
30543cec74 fix: use GTK3 stock i18n strings (#19783)
* fix: use GTK3 stock i18n strings

* address feedback from @ckerr
2019-08-15 12:12:56 -07:00
trop[bot]
66aeeac8df fix: ensure child_process.fork() doesn't modify main (#19776) 2019-08-15 10:18:21 -07:00
trop[bot]
b03bc4de83 fix: make sure that menu bar gets focus even when you click an item to focus it first (#19762) 2019-08-14 19:21:51 -07:00
Electron Bot
601c3f97ea Bump v7.0.0-beta.3 2019-08-14 17:54:38 -07:00
trop[bot]
d01a8eaa39 feat: add new nativeTheme API (#19758)
* feat: add new nativeTheme API

* chore: deprecate and clean up old systemPreferences theme APIs in favor of new nativeTheme module

* chore: clean up and deprecate things per feedback

* chore: add tests for deprecate and clean up invert impl

* build: when is a boolean not a boolean???
2019-08-14 17:53:20 -07:00
trop[bot]
54e1c11b2b chore: revert activation of the uv_loop on incoming IPC messages (#19737)
This reverts commit 8028c57b42.
2019-08-13 15:22:55 -07:00
trop[bot]
c1ad66b104 fix: crash in window.print() (#19728)
* fix: crash in window.print()

* add preliminary tests
2019-08-13 08:01:32 -07:00
trop[bot]
a905259646 chore: bump node to v12.8.0 (master) (#19726)
* chore: bump node in DEPS to v12.7.0

* chore: update node patches v12.6 to v12.7

Removed patches that are no longer necessary because we've upstreamed few changes already, and 3 way merge others

* fix: update build gn patch

* chore: bump node in DEPS to v12.8.0

* chore: update node patches v12.7 to v12.8

Removed patches that are no longer necessary because we've upstreamed few changes already, and 3 way merge others

* fix: Add patch to revert crypto createhash changes

The original node commit contains changes/calls to functions that are not supported in boringssl.

* disable node tests

* Remove outdated patch, already merged upstream
2019-08-12 20:53:38 -07:00
trop[bot]
356045ff57 fix: avoid losing focus on inputs when opening menu (Windows/Linux) (#19706)
* remove cause of issue

* remove comment
2019-08-12 19:45:08 -07:00
trop[bot]
a9f69bf732 fix: don't handle browser messages before document element is created (#19722)
* fix: don't handle browser messages before document element is created

* fix: bind ElectronApiServiceImpl later

DidCreateDocumentElement is called before the ElectronApiServiceImpl
gets bound.

* chore: add comment
2019-08-12 19:34:21 -07:00
trop[bot]
3e181b8efc docs: update hasShadow for win and linux (#19691) 2019-08-08 18:52:56 -07:00
trop[bot]
171c76e3cb fix: return correct bounds on will-resize (#19680) 2019-08-08 07:50:11 -07:00
Erick Zhao
0299f69fd1 fix: normalize behavior of win.setOpacity() for invalid number values across operating systems (#19535) (#19673) 2019-08-07 13:11:12 -07:00
Electron Bot
0bdb7b164c Bump v7.0.0-beta.2 2019-08-07 09:03:21 -07:00
trop[bot]
ea9cfc127c fix: crash on print cancellation and silent print settings (#19668)
* fix: crash on print cancellation

* fix: update printing patch for new options

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

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

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

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

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

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

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

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

* Apply suggestions from code review

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

* Update shell/renderer/atom_renderer_client.cc

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

* chore: update patches

* fix geometry.mojom

* Adopt more inclusive language in //net

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

* [mojo] Introduce ServiceFactory API

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

View File

@@ -1,46 +1,3 @@
version: 2.1
parameters:
upload-to-s3:
type: string
default: '1'
run-lint:
type: boolean
default: true
run-build-linux:
type: boolean
default: true
run-build-mac:
type: boolean
default: true
run-linux-x64-publish:
type: boolean
default: false
run-linux-ia32-publish:
type: boolean
default: false
run-linux-arm-publish:
type: boolean
default: false
run-linux-arm64-publish:
type: boolean
default: false
run-osx-publish:
type: boolean
default: false
run-mas-publish:
type: boolean
default: false
# The config expects the following environment variables to be set:
# - "SLACK_WEBHOOK" Slack hook URL to send notifications.
#
@@ -75,7 +32,6 @@ machine-mac-large: &machine-mac-large
# Build configurations options.
env-debug-build: &env-debug-build
GN_CONFIG: //electron/build/args/debug.gn
SKIP_DIST_ZIP: '1'
env-testing-build: &env-testing-build
GN_CONFIG: //electron/build/args/testing.gn
@@ -224,7 +180,7 @@ step-setup-env-for-build: &step-setup-env-for-build
echo 'export SCCACHE_PATH="'"$SCCACHE_PATH"'"' >> $BASH_ENV
if [ "$CIRCLE_PR_NUMBER" != "" ]; then
#if building a fork set readonly access to sccache
echo 'export SCCACHE_BUCKET="electronjs-sccache"' >> $BASH_ENV
echo 'export SCCACHE_BUCKET="electronjs-sccache-ci"' >> $BASH_ENV
echo 'export SCCACHE_TWO_TIER=true' >> $BASH_ENV
fi
fi
@@ -345,30 +301,28 @@ step-electron-dist-build: &step-electron-dist-build
name: Build dist.zip
command: |
cd src
if [ "$SKIP_DIST_ZIP" != "1" ]; then
ninja -C out/Default electron:electron_dist_zip
if [ "$CHECK_DIST_MANIFEST" == "1" ]; then
if [ "`uname`" == "Darwin" ]; then
target_os=mac
target_cpu=x64
if [ x"$MAS_BUILD" == x"true" ]; then
target_os=mac_mas
fi
elif [ "`uname`" == "Linux" ]; then
target_os=linux
if [ x"$TARGET_ARCH" == x ]; then
target_cpu=x64
elif [ "$TARGET_ARCH" == "ia32" ]; then
target_cpu=x86
else
target_cpu="$TARGET_ARCH"
fi
else
echo "Unknown system: `uname`"
exit 1
ninja -C out/Default electron:electron_dist_zip
if [ "$CHECK_DIST_MANIFEST" == "1" ]; then
if [ "`uname`" == "Darwin" ]; then
target_os=mac
target_cpu=x64
if [ x"$MAS_BUILD" == x"true" ]; then
target_os=mac_mas
fi
electron/script/zip_manifests/check-zip-manifest.py out/Default/dist.zip electron/script/zip_manifests/dist_zip.$target_os.$target_cpu.manifest
elif [ "`uname`" == "Linux" ]; then
target_os=linux
if [ x"$TARGET_ARCH" == x ]; then
target_cpu=x64
elif [ "$TARGET_ARCH" == "ia32" ]; then
target_cpu=x86
else
target_cpu="$TARGET_ARCH"
fi
else
echo "Unknown system: `uname`"
exit 1
fi
electron/script/zip_manifests/check-zip-manifest.py out/Default/dist.zip electron/script/zip_manifests/dist_zip.$target_os.$target_cpu.manifest
fi
step-electron-dist-store: &step-electron-dist-store
@@ -424,9 +378,6 @@ step-persist-data-for-tests: &step-persist-data-for-tests
- src/out/Default/mksnapshot.zip
- src/out/Default/gen/node_headers
- src/out/ffmpeg/ffmpeg.zip
- src/electron
- src/third_party/electron_node
- src/third_party/nan
step-electron-dist-unzip: &step-electron-dist-unzip
run:
@@ -514,9 +465,7 @@ step-mksnapshot-build: &step-mksnapshot-build
electron/script/strip-binaries.py --file $PWD/out/Default/mksnapshot
fi
fi
if [ "$SKIP_DIST_ZIP" != "1" ]; then
ninja -C out/Default electron:electron_mksnapshot_zip -j $NUMBER_OF_NINJA_PROCESSES
fi
ninja -C out/Default electron:electron_mksnapshot_zip -j $NUMBER_OF_NINJA_PROCESSES
step-mksnapshot-store: &step-mksnapshot-store
store_artifacts:
@@ -538,8 +487,6 @@ step-maybe-zip-symbols: &step-maybe-zip-symbols
command: |
cd src
export BUILD_PATH="$PWD/out/Default"
ninja -C out/Default electron:licenses
ninja -C out/Default electron:electron_version
electron/script/zip-symbols.py -b $BUILD_PATH
step-maybe-cross-arch-snapshot: &step-maybe-cross-arch-snapshot
@@ -704,7 +651,7 @@ steps-lint: &steps-lint
chromium_revision="$(grep -A1 chromium_version src/electron/DEPS | tr -d '\n' | cut -d\' -f4)"
gn_version="$(curl -sL "https://chromium.googlesource.com/chromium/src/+/${chromium_revision}/DEPS?format=TEXT" | base64 -d | grep gn_version | head -n1 | cut -d\' -f4)"
cipd ensure -ensure-file - -root . \<<-CIPD
cipd ensure -ensure-file - -root . <<-CIPD
\$ServiceURL https://chrome-infra-packages.appspot.com/
@Subdir src/buildtools/linux64
gn/gn/linux-amd64 $gn_version
@@ -808,16 +755,10 @@ steps-electron-build: &steps-electron-build
at: .
- *step-depot-tools-add-to-path
- *step-setup-env-for-build
- *step-restore-brew-cache
- *step-get-more-space-on-mac
- *step-install-npm-deps-on-mac
- *step-fix-sync-on-mac
- *step-gn-gen-default
- *step-delete-git-directories
# Electron app
- *step-electron-build
- *step-maybe-electron-dist-strip
- *step-electron-dist-build
- *step-electron-dist-store
- *step-ninja-summary
@@ -828,54 +769,10 @@ steps-electron-build: &steps-electron-build
- *step-show-sccache-stats
# mksnapshot
- *step-mksnapshot-build
- *step-mksnapshot-store
- *step-maybe-cross-arch-snapshot
- *step-maybe-cross-arch-snapshot-store
# ffmpeg
- *step-ffmpeg-gn-gen
- *step-ffmpeg-build
- *step-ffmpeg-store
# Save all data needed for a further tests run.
- *step-persist-data-for-tests
- *step-maybe-generate-breakpad-symbols
- *step-maybe-zip-symbols
# Trigger tests on arm hardware if needed
- *step-maybe-trigger-arm-test
- *step-maybe-notify-slack-failure
steps-electron-build-with-inline-checkout-for-tests: &steps-electron-build-with-inline-checkout-for-tests
steps-electron-build-for-tests: &steps-electron-build-for-tests
steps:
# Checkout - Copied ffrom steps-checkout
- *step-checkout-electron
- *step-depot-tools-get
- *step-depot-tools-add-to-path
- *step-restore-brew-cache
- *step-get-more-space-on-mac
- *step-install-gnutar-on-mac
- *step-generate-deps-hash
- *step-touch-sync-done
- *step-maybe-restore-src-cache
- *step-maybe-restore-git-cache
- *step-set-git-cache-path
# This sync call only runs if .circle-sync-done is an EMPTY file
- *step-gclient-sync
# These next few steps reset Electron to the correct commit regardless of which cache was restored
- run:
name: Wipe Electron
command: rm -rf src/electron
- *step-checkout-electron
- *step-run-electron-only-hooks
- *step-generate-deps-hash-cleanly
- *step-mark-sync-done
- *step-minimize-workspace-size-from-checkout
- attach_workspace:
at: .
- *step-depot-tools-add-to-path
- *step-setup-env-for-build
- *step-restore-brew-cache
@@ -1111,6 +1008,7 @@ chromium-upgrade-branches: &chromium-upgrade-branches
/chromium\-upgrade\/[0-9]+/
# List of all jobs.
version: 2
jobs:
# Layer 0: Lint. Standalone.
lint:
@@ -1170,8 +1068,7 @@ jobs:
<<: *env-debug-build
<<: *env-enable-sccache
<<: *env-ninja-status
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_arm=True --custom-var=checkout_arm64=True'
<<: *steps-electron-build-with-inline-checkout-for-tests
<<: *steps-electron-build
linux-x64-debug-gn-check:
<<: *machine-linux-medium
@@ -1187,8 +1084,7 @@ jobs:
<<: *env-testing-build
<<: *env-enable-sccache
<<: *env-ninja-status
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_arm=True --custom-var=checkout_arm64=True'
<<: *steps-electron-build-with-inline-checkout-for-tests
<<: *steps-electron-build-for-tests
linux-x64-testing-no-run-as-node:
<<: *machine-linux-2xlarge
@@ -1198,8 +1094,7 @@ jobs:
<<: *env-enable-sccache
<<: *env-ninja-status
<<: *env-disable-run-as-node
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_arm=True --custom-var=checkout_arm64=True'
<<: *steps-electron-build-with-inline-checkout-for-tests
<<: *steps-electron-build-for-tests
linux-x64-testing-gn-check:
<<: *machine-linux-medium
@@ -1220,12 +1115,12 @@ jobs:
linux-x64-release:
<<: *machine-linux-2xlarge
environment:
<<: *env-linux-2xlarge-release
<<: *env-linux-2xlarge
<<: *env-release-build
<<: *env-enable-sccache
<<: *env-send-slack-notifications
<<: *env-ninja-status
<<: *steps-electron-build
<<: *steps-electron-build-for-tests
linux-x64-publish:
<<: *machine-linux-2xlarge
@@ -1233,8 +1128,6 @@ jobs:
<<: *env-linux-2xlarge-release
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_boto=True --custom-var=checkout_requests=True'
<<: *env-release-build
<<: *env-enable-sccache
UPLOAD_TO_S3: << pipeline.parameters.upload-to-s3 >>
<<: *steps-electron-build-for-publish
linux-ia32-debug:
@@ -1245,8 +1138,7 @@ jobs:
<<: *env-debug-build
<<: *env-enable-sccache
<<: *env-ninja-status
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_arm=True --custom-var=checkout_arm64=True'
<<: *steps-electron-build-with-inline-checkout-for-tests
<<: *steps-electron-build
linux-ia32-testing:
<<: *machine-linux-2xlarge
@@ -1256,8 +1148,7 @@ jobs:
<<: *env-testing-build
<<: *env-enable-sccache
<<: *env-ninja-status
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_arm=True --custom-var=checkout_arm64=True'
<<: *steps-electron-build-with-inline-checkout-for-tests
<<: *steps-electron-build-for-tests
linux-ia32-chromedriver:
<<: *machine-linux-medium
@@ -1272,13 +1163,13 @@ jobs:
linux-ia32-release:
<<: *machine-linux-2xlarge
environment:
<<: *env-linux-2xlarge-release
<<: *env-linux-2xlarge
<<: *env-ia32
<<: *env-release-build
<<: *env-enable-sccache
<<: *env-send-slack-notifications
<<: *env-ninja-status
<<: *steps-electron-build
<<: *steps-electron-build-for-tests
linux-ia32-publish:
<<: *machine-linux-2xlarge
@@ -1287,8 +1178,6 @@ jobs:
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_boto=True --custom-var=checkout_requests=True'
<<: *env-ia32
<<: *env-release-build
<<: *env-enable-sccache
UPLOAD_TO_S3: << pipeline.parameters.upload-to-s3 >>
<<: *steps-electron-build-for-publish
linux-arm-debug:
@@ -1299,8 +1188,7 @@ jobs:
<<: *env-debug-build
<<: *env-enable-sccache
<<: *env-ninja-status
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_arm=True --custom-var=checkout_arm64=True'
<<: *steps-electron-build-with-inline-checkout-for-tests
<<: *steps-electron-build
linux-arm-testing:
<<: *machine-linux-2xlarge
@@ -1311,8 +1199,7 @@ jobs:
<<: *env-enable-sccache
<<: *env-ninja-status
TRIGGER_ARM_TEST: true
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_arm=True --custom-var=checkout_arm64=True'
<<: *steps-electron-build-with-inline-checkout-for-tests
<<: *steps-electron-build-for-tests
linux-arm-chromedriver:
<<: *machine-linux-medium
@@ -1327,13 +1214,13 @@ jobs:
linux-arm-release:
<<: *machine-linux-2xlarge
environment:
<<: *env-linux-2xlarge-release
<<: *env-linux-2xlarge
<<: *env-arm
<<: *env-release-build
<<: *env-enable-sccache
<<: *env-send-slack-notifications
<<: *env-ninja-status
<<: *steps-electron-build
<<: *steps-electron-build-for-tests
linux-arm-publish:
<<: *machine-linux-2xlarge
@@ -1341,9 +1228,7 @@ jobs:
<<: *env-linux-2xlarge-release
<<: *env-arm
<<: *env-release-build
<<: *env-enable-sccache
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_arm=True --custom-var=checkout_boto=True --custom-var=checkout_requests=True'
UPLOAD_TO_S3: << pipeline.parameters.upload-to-s3 >>
<<: *steps-electron-build-for-publish
linux-arm64-debug:
@@ -1354,8 +1239,7 @@ jobs:
<<: *env-debug-build
<<: *env-enable-sccache
<<: *env-ninja-status
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_arm=True --custom-var=checkout_arm64=True'
<<: *steps-electron-build-with-inline-checkout-for-tests
<<: *steps-electron-build
linux-arm64-debug-gn-check:
<<: *machine-linux-medium
@@ -1374,8 +1258,7 @@ jobs:
<<: *env-enable-sccache
<<: *env-ninja-status
TRIGGER_ARM_TEST: true
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_arm=True --custom-var=checkout_arm64=True'
<<: *steps-electron-build-with-inline-checkout-for-tests
<<: *steps-electron-build-for-tests
linux-arm64-testing-gn-check:
<<: *machine-linux-medium
@@ -1398,13 +1281,13 @@ jobs:
linux-arm64-release:
<<: *machine-linux-2xlarge
environment:
<<: *env-linux-2xlarge-release
<<: *env-linux-2xlarge
<<: *env-arm64
<<: *env-release-build
<<: *env-enable-sccache
<<: *env-send-slack-notifications
<<: *env-ninja-status
<<: *steps-electron-build
<<: *steps-electron-build-for-tests
linux-arm64-publish:
<<: *machine-linux-2xlarge
@@ -1412,9 +1295,7 @@ jobs:
<<: *env-linux-2xlarge-release
<<: *env-arm64
<<: *env-release-build
<<: *env-enable-sccache
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_arm64=True --custom-var=checkout_boto=True --custom-var=checkout_requests=True'
UPLOAD_TO_S3: << pipeline.parameters.upload-to-s3 >>
<<: *steps-electron-build-for-publish
osx-testing:
@@ -1424,7 +1305,7 @@ jobs:
<<: *env-testing-build
<<: *env-enable-sccache
<<: *env-ninja-status
<<: *steps-electron-build
<<: *steps-electron-build-for-tests
osx-debug:
<<: *machine-mac-large
@@ -1433,7 +1314,7 @@ jobs:
<<: *env-debug-build
<<: *env-enable-sccache
<<: *env-ninja-status
<<: *steps-electron-build
<<: *steps-electron-build-for-tests
osx-debug-gn-check:
<<: *machine-mac
@@ -1465,16 +1346,14 @@ jobs:
<<: *env-release-build
<<: *env-enable-sccache
<<: *env-ninja-status
<<: *steps-electron-build
<<: *steps-electron-build-for-tests
osx-publish:
<<: *machine-mac-large
environment:
<<: *env-mac-large-release
<<: *env-release-build
<<: *env-enable-sccache
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_boto=True --custom-var=checkout_requests=True'
UPLOAD_TO_S3: << pipeline.parameters.upload-to-s3 >>
<<: *steps-electron-build-for-publish
mas-testing:
@@ -1485,7 +1364,7 @@ jobs:
<<: *env-testing-build
<<: *env-enable-sccache
<<: *env-ninja-status
<<: *steps-electron-build
<<: *steps-electron-build-for-tests
mas-debug:
<<: *machine-mac-large
@@ -1495,7 +1374,7 @@ jobs:
<<: *env-debug-build
<<: *env-enable-sccache
<<: *env-ninja-status
<<: *steps-electron-build
<<: *steps-electron-build-for-tests
mas-debug-gn-check:
<<: *machine-mac
@@ -1530,7 +1409,7 @@ jobs:
<<: *env-release-build
<<: *env-enable-sccache
<<: *env-ninja-status
<<: *steps-electron-build
<<: *steps-electron-build-for-tests
mas-publish:
<<: *machine-mac-large
@@ -1538,9 +1417,7 @@ jobs:
<<: *env-mac-large-release
<<: *env-mas
<<: *env-release-build
<<: *env-enable-sccache
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_boto=True --custom-var=checkout_requests=True'
UPLOAD_TO_S3: << pipeline.parameters.upload-to-s3 >>
<<: *steps-electron-build-for-publish
# Layer 3: Tests.
@@ -1795,67 +1672,28 @@ jobs:
- *step-maybe-notify-slack-success
workflows:
version: 2.1
# The publish workflows below each contain one job so that they are
# compatible with how sudowoodo works today. If these workflows are
# changed to have multiple jobs, then scripts/release/ci-release-build.js
# will need to be updated and there will most likely need to be changes to
# sudowoodo
publish-x64-linux:
when: << pipeline.parameters.run-linux-x64-publish >>
jobs:
- linux-x64-publish:
context: release-env
publish-ia32-linux:
when: << pipeline.parameters.run-linux-ia32-publish >>
jobs:
- linux-ia32-publish:
context: release-env
publish-arm-linux:
when: << pipeline.parameters.run-linux-arm-publish >>
jobs:
- linux-arm-publish:
context: release-env
publish-arm64-linux:
when: << pipeline.parameters.run-linux-arm64-publish >>
jobs:
- linux-arm64-publish:
context: release-env
publish-osx:
when: << pipeline.parameters.run-osx-publish >>
jobs:
- osx-publish:
context: release-env
publish-mas:
when: << pipeline.parameters.run-mas-publish >>
jobs:
- mas-publish:
context: release-env
version: 2
lint:
when: << pipeline.parameters.run-lint >>
jobs:
- lint
build-linux:
when: << pipeline.parameters.run-build-linux >>
jobs:
- linux-checkout-fast
- linux-checkout-and-save-cache
- linux-x64-debug
- linux-x64-debug:
requires:
- linux-checkout-fast
- linux-x64-debug-gn-check:
requires:
- linux-checkout-fast
- linux-x64-testing
- linux-x64-testing-no-run-as-node
- linux-x64-testing:
requires:
- linux-checkout-fast
- linux-x64-testing-no-run-as-node:
requires:
- linux-checkout-fast
- linux-x64-testing-gn-check:
requires:
- linux-checkout-fast
@@ -1869,8 +1707,12 @@ workflows:
requires:
- linux-x64-testing
- linux-ia32-debug
- linux-ia32-testing
- linux-ia32-debug:
requires:
- linux-checkout-fast
- linux-ia32-testing:
requires:
- linux-checkout-fast
- linux-ia32-testing-tests:
requires:
- linux-ia32-testing
@@ -1881,20 +1723,27 @@ workflows:
requires:
- linux-ia32-testing
- linux-arm-debug
- linux-arm-testing
- linux-arm-debug:
requires:
- linux-checkout-fast
- linux-arm-testing:
requires:
- linux-checkout-fast
- linux-arm64-debug
- linux-arm64-debug:
requires:
- linux-checkout-fast
- linux-arm64-debug-gn-check:
requires:
- linux-checkout-fast
- linux-arm64-testing
- linux-arm64-testing:
requires:
- linux-checkout-fast
- linux-arm64-testing-gn-check:
requires:
- linux-checkout-fast
build-mac:
when: << pipeline.parameters.run-build-mac >>
jobs:
- mac-checkout-fast
- mac-checkout-and-save-cache
@@ -1949,11 +1798,11 @@ workflows:
- master
- *chromium-upgrade-branches
jobs:
- linux-checkout-fast
- linux-checkout
- linux-x64-release:
requires:
- linux-checkout-fast
- linux-checkout
- linux-x64-release-tests:
requires:
- linux-x64-release
@@ -1965,7 +1814,7 @@ workflows:
- linux-x64-release
- linux-x64-chromedriver:
requires:
- linux-checkout-fast
- linux-checkout
- linux-x64-release-summary:
requires:
- linux-x64-release
@@ -1975,7 +1824,7 @@ workflows:
- linux-ia32-release:
requires:
- linux-checkout-fast
- linux-checkout
- linux-ia32-release-tests:
requires:
- linux-ia32-release
@@ -1987,7 +1836,7 @@ workflows:
- linux-ia32-release
- linux-ia32-chromedriver:
requires:
- linux-checkout-fast
- linux-checkout
- linux-ia32-release-summary:
requires:
- linux-ia32-release
@@ -1997,10 +1846,10 @@ workflows:
- linux-arm-release:
requires:
- linux-checkout-fast
- linux-checkout
- linux-arm-chromedriver:
requires:
- linux-checkout-fast
- linux-checkout
- linux-arm-release-summary:
requires:
- linux-arm-release
@@ -2009,10 +1858,10 @@ workflows:
- linux-arm64-release:
requires:
- linux-checkout-fast
- linux-checkout
- linux-arm64-chromedriver:
requires:
- linux-checkout-fast
- linux-checkout
- linux-arm64-release-summary:
requires:
- linux-arm64-release
@@ -2028,11 +1877,11 @@ workflows:
- master
- *chromium-upgrade-branches
jobs:
- mac-checkout-fast
- mac-checkout
- osx-release:
requires:
- mac-checkout-fast
- mac-checkout
- osx-release-tests:
requires:
- osx-release
@@ -2044,7 +1893,7 @@ workflows:
- osx-release
- osx-chromedriver:
requires:
- mac-checkout-fast
- mac-checkout
- osx-release-summary:
requires:
- osx-release
@@ -2054,7 +1903,7 @@ workflows:
- mas-release:
requires:
- mac-checkout-fast
- mac-checkout
- mas-release-tests:
requires:
- mas-release
@@ -2066,7 +1915,7 @@ workflows:
- mas-release
- mas-chromedriver:
requires:
- mac-checkout-fast
- mac-checkout
- mas-release-summary:
requires:
- mas-release

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

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

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

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

View File

@@ -26,6 +26,7 @@ if (is_mac) {
import("//third_party/icu/config.gni")
import("//ui/gl/features.gni")
import("//v8/gni/v8.gni")
import("build/rules.gni")
}
if (is_linux) {
@@ -280,7 +281,6 @@ if (is_linux) {
"notify_notification_add_action",
"notify_notification_set_image_from_pixbuf",
"notify_notification_set_timeout",
"notify_notification_set_urgency",
"notify_notification_set_hint_string",
"notify_notification_show",
"notify_notification_close",
@@ -580,17 +580,6 @@ source_set("electron_lib") {
]
}
if (enable_remote_module) {
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.h",
"shell/common/api/remote/remote_object_freer.cc",
"shell/common/api/remote/remote_object_freer.h",
]
}
if (enable_desktop_capturer) {
if (is_component_build && !is_linux) {
# On windows the implementation relies on unexported
@@ -667,6 +656,12 @@ if (is_mac) {
electron_framework_version = "A"
electron_version = read_file("ELECTRON_VERSION", "trim string")
mac_xib_bundle_data("electron_xibs") {
sources = [
"shell/common/resources/mac/MainMenu.xib",
]
}
bundle_data("electron_framework_resources") {
public_deps = [
":packed_resources",
@@ -781,6 +776,7 @@ if (is_mac) {
":electron_framework_libraries",
":electron_framework_resources",
":electron_swiftshader_library",
":electron_xibs",
]
if (!is_mas_build) {
deps += [ ":electron_crashpad_helper" ]

4
DEPS
View File

@@ -11,9 +11,9 @@ gclient_gn_args = [
vars = {
'chromium_version':
'6c775c358b709f4353bc693623bf58820adf3918',
'78.0.3904.94',
'node_version':
'v12.9.1',
'v12.8.1',
'nan_version':
'2ee313aaca52e2b478965ac50eb5082520380d1b',

View File

@@ -1 +1 @@
8.0.0-nightly.20190930
7.1.0

View File

@@ -3,7 +3,7 @@ use_jumbo_build = true
root_extra_deps = [ "//electron" ]
# Registry of NMVs --> https://github.com/nodejs/node/blob/master/doc/abi_version_registry.json
node_module_version = 76
node_module_version = 75
v8_promise_internal_field_count = 1
v8_typed_array_max_size_in_heap = 0
@@ -24,6 +24,3 @@ is_cfi = false
# TODO: Remove this and update CI to contain 10.14 SDK once
# crbug.com/986701 is fixed.
mac_sdk_min = "10.13"
# TODO: disabled due to crashes. re-enable.
enable_osr = false

57
build/rules.gni Normal file
View File

@@ -0,0 +1,57 @@
import("//build/config/mac/mac_sdk.gni")
# This is imported from /ios becuase this functionality was moved
# after Chromium stopped using xib files for macOS menu functionality
# See https://chromium-review.googlesource.com/c/chromium/src/+/1648695
import("//build/config/ios/rules.gni")
# Template is copied here from Chromium but was removed in
# https://chromium-review.googlesource.com/c/chromium/src/+/1637981
# Template to compile and package Mac XIB files as bundle data.
# Arguments
# sources:
# list of string, sources to comiple
# output_path:
# (optional) string, the path to use for the outputs list in the
# bundle_data step. If unspecified, defaults to bundle_resources_dir.
template("mac_xib_bundle_data") {
_target_name = target_name
_compile_target_name = _target_name + "_compile_ibtool"
compile_ib_files(_compile_target_name) {
forward_variables_from(invoker, [ "testonly" ])
visibility = [ ":$_target_name" ]
sources = invoker.sources
output_extension = "nib"
ibtool_flags = [
"--minimum-deployment-target",
mac_deployment_target,
# TODO(rsesek): Enable this once all the bots are on Xcode 7+.
# "--target-device",
# "mac",
]
}
bundle_data(_target_name) {
forward_variables_from(invoker,
[
"testonly",
"visibility",
])
public_deps = [
":$_compile_target_name",
]
sources = get_target_outputs(":$_compile_target_name")
_output_path = "{{bundle_resources_dir}}"
if (defined(invoker.output_path)) {
_output_path = invoker.output_path
}
outputs = [
"$_output_path/{{source_file_part}}",
]
}
}

View File

@@ -42,7 +42,7 @@ module.exports = ({
resolve: {
alias: {
'@electron/internal': path.resolve(electronRoot, 'lib'),
'electron': path.resolve(electronRoot, 'lib', loadElectronFromAlternateTarget || target, 'api', 'exports', 'electron.ts'),
'electron': path.resolve(electronRoot, 'lib', loadElectronFromAlternateTarget || target, 'api', 'exports', 'electron.js'),
// Force timers to resolve to our dependency that doens't use window.postMessage
'timers': path.resolve(electronRoot, 'node_modules', 'timers-browserify', 'main.js')
},
@@ -74,7 +74,10 @@ module.exports = ({
global: ['@electron/internal/renderer/webpack-provider', '_global'],
Buffer: ['@electron/internal/renderer/webpack-provider', 'Buffer'],
})
] : [])
] : []),
new webpack.ProvidePlugin({
Promise: ['@electron/internal/common/webpack-globals-provider', 'Promise'],
}),
]
})
}
}

View File

@@ -12,7 +12,6 @@ buildflag_header("buildflags") {
"ENABLE_DESKTOP_CAPTURER=$enable_desktop_capturer",
"ENABLE_RUN_AS_NODE=$enable_run_as_node",
"ENABLE_OSR=$enable_osr",
"ENABLE_REMOTE_MODULE=$enable_remote_module",
"ENABLE_VIEW_API=$enable_view_api",
"ENABLE_PEPPER_FLASH=$enable_pepper_flash",
"ENABLE_PDF_VIEWER=$enable_pdf_viewer",

View File

@@ -10,8 +10,6 @@ declare_args() {
enable_osr = true
enable_remote_module = true
enable_view_api = false
enable_pdf_viewer = false

View File

@@ -43,8 +43,6 @@ static_library("chrome") {
"//chrome/browser/predictors/proxy_lookup_client_impl.h",
"//chrome/browser/predictors/resolve_host_client_impl.cc",
"//chrome/browser/predictors/resolve_host_client_impl.h",
"//chrome/browser/printing/printing_service.cc",
"//chrome/browser/printing/printing_service.h",
"//chrome/browser/ssl/security_state_tab_helper.cc",
"//chrome/browser/ssl/security_state_tab_helper.h",
"//chrome/browser/ui/autofill/popup_view_common.cc",
@@ -164,6 +162,8 @@ static_library("chrome") {
"//chrome/browser/printing/printer_query.h",
"//chrome/browser/printing/printing_message_filter.cc",
"//chrome/browser/printing/printing_message_filter.h",
"//chrome/browser/printing/printing_service.cc",
"//chrome/browser/printing/printing_service.h",
]
public_deps += [

View File

@@ -73,7 +73,7 @@ net::NSSCertDatabase* GetNSSCertDatabaseForResourceContext(
void CertificateManagerModel::Create(content::BrowserContext* browser_context,
const CreationCallback& callback) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
base::PostTask(
base::PostTaskWithTraits(
FROM_HERE, {BrowserThread::IO},
base::BindOnce(&CertificateManagerModel::GetCertDBOnIOThread,
browser_context->GetResourceContext(), callback));
@@ -86,7 +86,7 @@ CertificateManagerModel::CertificateManagerModel(
DCHECK_CURRENTLY_ON(BrowserThread::UI);
}
CertificateManagerModel::~CertificateManagerModel() = default;
CertificateManagerModel::~CertificateManagerModel() {}
int CertificateManagerModel::ImportFromPKCS12(
PK11SlotInfo* slot_info,
@@ -146,7 +146,7 @@ void CertificateManagerModel::DidGetCertDBOnIOThread(
DCHECK_CURRENTLY_ON(BrowserThread::IO);
bool is_user_db_available = !!cert_db->GetPublicSlot();
base::PostTask(
base::PostTaskWithTraits(
FROM_HERE, {BrowserThread::UI},
base::BindOnce(&CertificateManagerModel::DidGetCertDBOnUIThread, cert_db,
is_user_db_available, callback));

View File

@@ -185,7 +185,7 @@ int WaitSocketForRead(int fd, const base::TimeDelta& timeout) {
FD_ZERO(&read_fds);
FD_SET(fd, &read_fds);
return HANDLE_EINTR(select(fd + 1, &read_fds, nullptr, nullptr, &tv));
return HANDLE_EINTR(select(fd + 1, &read_fds, NULL, NULL, &tv));
}
// Read a message from a socket fd, with an optional timeout.
@@ -705,7 +705,7 @@ void ProcessSingleton::LinuxWatcher::SocketReader::FinishWithACK(
if (shutdown(fd_, SHUT_WR) < 0)
PLOG(ERROR) << "shutdown() failed";
base::PostTask(
base::PostTaskWithTraits(
FROM_HERE, {BrowserThread::IO},
base::BindOnce(&ProcessSingleton::LinuxWatcher::RemoveSocketReader,
parent_, this));
@@ -885,9 +885,10 @@ ProcessSingleton::NotifyResult ProcessSingleton::NotifyOtherProcessOrCreate() {
void ProcessSingleton::StartListeningOnSocket() {
watcher_ = new LinuxWatcher(this);
base::PostTask(FROM_HERE, {BrowserThread::IO},
base::BindOnce(&ProcessSingleton::LinuxWatcher::StartListening,
watcher_, sock_));
base::PostTaskWithTraits(
FROM_HERE, {BrowserThread::IO},
base::BindOnce(&ProcessSingleton::LinuxWatcher::StartListening, watcher_,
sock_));
}
void ProcessSingleton::OnBrowserReady() {

View File

@@ -2,10 +2,9 @@
<head>
<title>Electron</title>
<meta http-equiv="Content-Security-Policy" content="default-src 'none'; script-src 'self'; style-src 'self'; img-src 'self'; connect-src 'self'" />
<meta http-equiv="Content-Security-Policy" content="default-src 'none'; script-src 'sha256-6PH54BfkNq/EMMhUY7nhHf3c+AxloOwfy7hWyT01CM8='; style-src 'self'; img-src 'self'; connect-src 'self'" />
<link href="./styles.css" type="text/css" rel="stylesheet" />
<link href="./octicon/build.css" type="text/css" rel="stylesheet" />
<script defer src="./index.js"></script>
</head>
<body>
@@ -84,6 +83,9 @@
</div>
</div>
</nav>
<script>
window.electronDefaultApp.initialize()
</script>
</body>
</html>

View File

@@ -1,30 +0,0 @@
async function getOcticonSvg (name: string) {
try {
const response = await fetch(`octicon/${name}.svg`)
const div = document.createElement('div')
div.innerHTML = await response.text()
return div
} catch {
return null
}
}
async function loadSVG (element: HTMLSpanElement) {
for (const cssClass of element.classList) {
if (cssClass.startsWith('octicon-')) {
const icon = await getOcticonSvg(cssClass.substr(8))
if (icon) {
for (const elemClass of element.classList) {
icon.classList.add(elemClass)
}
element.before(icon)
element.remove()
break
}
}
}
}
for (const element of document.querySelectorAll<HTMLSpanElement>('.octicon')) {
loadSVG(element)
}

View File

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

View File

@@ -39,6 +39,7 @@ an issue:
* [Using Electron's APIs](tutorial/application-architecture.md#using-electron-apis)
* [Using Node.js APIs](tutorial/application-architecture.md#using-nodejs-apis)
* [Using Native Node.js Modules](tutorial/using-native-node-modules.md)
* [Performance Strategies](tutorial/performance.md)
* Adding Features to Your App
* [Notifications](tutorial/notifications.md)
* [Recent Documents](tutorial/recent-documents.md)
@@ -134,7 +135,6 @@ These individual tutorials expand on topics discussed in the guide above.
* [MenuItem](api/menu-item.md)
* [net](api/net.md)
* [netLog](api/net-log.md)
* [Notification](api/notification.md)
* [powerMonitor](api/power-monitor.md)
* [powerSaveBlocker](api/power-save-blocker.md)
* [protocol](api/protocol.md)

View File

@@ -390,7 +390,7 @@ Emitted when Electron has created a new `session`.
```javascript
const { app } = require('electron')
app.on('session-created', (session) => {
app.on('session-created', (event, session) => {
console.log(session)
})
```
@@ -675,8 +675,6 @@ preferred over `name` by Electron.
Overrides the current application's name.
**Note:** This function overrides the name used internally by Electron; it does not affect the name that the OS uses.
**[Deprecated](modernization/property-updates.md)**
### `app.getLocale()`
@@ -1170,21 +1168,21 @@ This API must be called after the `ready` event is emitted.
**[Deprecated](modernization/property-updates.md)**
### `app.showAboutPanel()`
### `app.showAboutPanel()` _macOS_ _Linux_
Show the app's about panel options. These options can be overridden with `app.setAboutPanelOptions(options)`.
### `app.setAboutPanelOptions(options)`
### `app.setAboutPanelOptions(options)` _macOS_ _Linux_
* `options` Object
* `applicationName` String (optional) - The app's name.
* `applicationVersion` String (optional) - The app's version.
* `copyright` String (optional) - Copyright information.
* `version` String (optional) _macOS_ - The app's build version number.
* `credits` String (optional) _macOS_ _Windows_ - Credit information.
* `credits` String (optional) _macOS_ - Credit information.
* `authors` String[] (optional) _Linux_ - List of app authors.
* `website` String (optional) _Linux_ - The app's website.
* `iconPath` String (optional) _Linux_ _Windows_ - Path to the app's icon. On Linux, will be shown as 64x64 pixels while retaining aspect ratio.
* `iconPath` String (optional) _Linux_ - Path to the app's icon. Will be shown as 64x64 pixels while retaining aspect ratio.
Set the about panel options. This will override the values defined in the app's
`.plist` file on MacOS. See the [Apple docs][about-panel-options] for more details. On Linux, values must be set in order to be shown; there are no defaults.

View File

@@ -206,7 +206,8 @@ It creates a new `BrowserWindow` with native properties as set by the `options`.
* `backgroundColor` String (optional) - Window's background color as a hexadecimal value,
like `#66CD00` or `#FFF` or `#80FFFFFF` (alpha in #AARRGGBB format is supported if
`transparent` is set to `true`). Default is `#FFF` (white).
* `hasShadow` Boolean (optional) - Whether window should have a shadow. Default is `true`.
* `hasShadow` Boolean (optional) - Whether window should have a shadow. This is only
implemented on macOS. Default is `true`.
* `opacity` Number (optional) - Set the initial opacity of the window, between 0.0 (fully
transparent) and 1.0 (fully opaque). This is only implemented on Windows and macOS.
* `darkTheme` Boolean (optional) - Forces using dark theme for the window, only works on
@@ -382,9 +383,6 @@ It creates a new `BrowserWindow` with native properties as set by the `options`.
* `disableHtmlFullscreenWindowResize` Boolean (optional) - Whether to
prevent the window from resizing when entering HTML Fullscreen. Default
is `false`.
* `accessibleTitle` String (optional) - An alternative title string provided only
to accessibility tools such as screen readers. This string is not directly
visible to users.
When setting minimum or maximum window size with `minWidth`/`maxWidth`/
`minHeight`/`maxHeight`, it only constrains the users. It won't prevent you from
@@ -525,14 +523,14 @@ Note that this is only emitted when the window is being resized manually. Resizi
Emitted after the window has been resized.
#### Event: 'will-move' _macOS_ _Windows_
#### Event: 'will-move' _Windows_
Returns:
* `event` Event
* `newBounds` [`Rectangle`](structures/rectangle.md) - Location the window is being moved to.
Emitted before the window is moved. On Windows, calling `event.preventDefault()` will prevent the window from being moved.
Emitted before the window is moved. Calling `event.preventDefault()` will prevent the window from being moved.
Note that this is only emitted when the window is being resized manually. Resizing the window with `setBounds`/`setSize` will not emit this event.
@@ -664,8 +662,7 @@ Returns `BrowserWindow | null` - The window that is focused in this application,
* `webContents` [WebContents](web-contents.md)
Returns `BrowserWindow | null` - The window that owns the given `webContents`
or `null` if the contents are not owned by a window.
Returns `BrowserWindow` - The window that owns the given `webContents`.
#### `BrowserWindow.fromBrowserView(browserView)`
@@ -831,12 +828,6 @@ const menu = Menu.buildFromTemplate(template)
Menu.setApplicationMenu(menu)
```
#### `win.accessibleTitle`
A `String` property that defines an alternative title provided only to
accessibility tools such as screen readers. This string is not directly
visible to users.
### Instance Methods
Objects created with `new BrowserWindow` have the following instance methods:
@@ -1210,14 +1201,6 @@ can not be focused on.
Returns `Boolean` - Whether the window is always on top of other windows.
#### `win.moveAbove(mediaSourceId)`
* `mediaSourceId` String - Window id in the format of DesktopCapturerSource's id. For example "window:1869:0".
Moves window above the source window in the sense of z-order. If the
`mediaSourceId` is not of type window or if the window does not exist then
this method throws an error.
#### `win.moveTop()`
Moves window to top(z-order) regardless of focus
@@ -1290,15 +1273,6 @@ Enters or leaves the kiosk mode.
Returns `Boolean` - Whether the window is in kiosk mode.
#### `win.getMediaSourceId()`
Returns `String` - Window id in the format of DesktopCapturerSource's id. For example "window:1234:0".
More precisely the format is `window:id:other_id` where `id` is `HWND` on
Windows, `CGWindowID` (`uint64_t`) on macOS and `Window` (`unsigned long`) on
Linux. `other_id` is used to identify web contents (tabs) so within the same
top level window.
#### `win.getNativeWindowHandle()`
Returns `Buffer` - The platform-specific handle of the window.
@@ -1746,14 +1720,14 @@ removed in future Electron releases.
#### `win.setBrowserView(browserView)` _Experimental_
* `browserView` [BrowserView](browser-view.md) | null - Attach `browserView` to `win`.
If there are other `BrowserView`s attached, they will be removed from
* `browserView` [BrowserView](browser-view.md) | null - Attach browserView to win.
If there is some other browserViews was attached they will be removed from
this window.
#### `win.getBrowserView()` _Experimental_
Returns `BrowserView | null` - The `BrowserView` attached to `win`. Returns `null`
if one is not attached. Throws an error if multiple `BrowserView`s are attached.
Returns `BrowserView | null` - an BrowserView what is attached. Returns `null`
if none is attached. Throw error if multiple BrowserViews is attached.
#### `win.addBrowserView(browserView)` _Experimental_

111
docs/api/context-bridge.md Normal file
View File

@@ -0,0 +1,111 @@
# contextBridge
> Create a safe, bi-directional, synchronous bridge across isolated contexts
Process: [Renderer](../glossary.md#renderer-process)
An example of exposing an API to a renderer from an isolated preload script is given below:
```javascript
// Preload (Isolated World)
const { contextBridge, ipcRenderer } = require('electron')
contextBridge.exposeInMainWorld(
'electron',
{
doThing: () => ipcRenderer.send('do-a-thing')
}
)
```
```javascript
// Renderer (Main World)
window.electron.doThing()
```
## Glossary
### Main World
The "Main World" is the javascript context that your main renderer code runs in. By default the page you load in your renderer
executes code in this world.
### Isolated World
When `contextIsolation` is enabled in your `webPreferences` your `preload` scripts run in an "Isolated World". You can read more about
context isolation and what it affects in the [BrowserWindow](browser-window.md) docs.
## Methods
The `contextBridge` module has the following methods:
### `contextBridge.exposeInMainWorld(apiKey, api)` _Experimental_
* `apiKey` String - The key to inject the API onto `window` with. The API will be accessible on `window[apiKey]`.
* `api` Record<String, any> - Your API object, more information on what this API can be and how it works is available below.
## Usage
### API Objects
The `api` object provided to [`exposeInMainWorld`](#contextbridgeexposeinmainworldapikey-api-experimental) must be an object
whose keys are strings and values are a `Function`, `String`, `Number`, `Array`, `Boolean` or another nested object that meets the same conditions.
`Function` values are proxied to the other context and all other values are **copied** and **frozen**. I.e. Any data / primitives sent in
the API object become immutable and updates on either side of the bridge do not result in an update on the other side.
An example of a complex API object is shown below.
```javascript
const { contextBridge } = require('electron')
contextBridge.exposeInMainWorld(
'electron',
{
doThing: () => ipcRenderer.send('do-a-thing'),
myPromises: [Promise.resolve(), Promise.reject(new Error('whoops'))],
anAsyncFunction: async () => 123,
data: {
myFlags: ['a', 'b', 'c'],
bootTime: 1234
},
nestedAPI: {
evenDeeper: {
youCanDoThisAsMuchAsYouWant: {
fn: () => ({
returnData: 123
})
}
}
}
}
)
```
### API Functions
`Function` values that you bind through the `contextBridge` are proxied through Electron to ensure that contexts remain isolated. This
results in some key limitations that we've outlined below.
#### Parameter / Error / Return Type support
Because parameters, errors and return values are **copied** when they are sent over the bridge there are only certain types that can be used.
At a high level if the type you want to use can be serialized and un-serialized into the same object it will work. A table of type support
has been included below for completeness.
| Type | Complexity | Parameter Support | Return Value Support | Limitations |
| ---- | ---------- | ----------------- | -------------------- | ----------- |
| `String` | Simple | ✅ | ✅ | N/A |
| `Number` | Simple | ✅ | ✅ | N/A |
| `Boolean` | Simple | ✅ | ✅ | N/A |
| `Object` | Complex | ✅ | ✅ | Keys must be supported "Simple" types in this table. Values must be supported in this table. Prototype modifications are dropped. Sending custom classes will copy values but not the prototype. |
| `Array` | Complex | ✅ | ✅ | Same limitations as the `Object` type |
| `Error` | Complex | ✅ | ✅ | Errors that are thrown are also copied, this can result in the message and stack trace of the error changing slightly due to being thrown in a different context |
| `Promise` | Complex | ✅ | ✅ | Promises are only proxied if they are a the return value or exact parameter. Promises nested in arrays or obejcts will be dropped. |
| `Function` | Complex | ✅ | ✅ | Prototype modifications are dropped. Sending classes or constructors will not work. |
| [Cloneable Types](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Structured_clone_algorithm) | Simple | ✅ | ✅ | See the linked document on cloneable types |
| `Symbol` | N/A | ❌ | ❌ | Symbols cannot be copied across contexts so they are dropped |
If the type you care about is not in the above table it is probably not supported.

View File

@@ -48,7 +48,6 @@ The `dialog` module has the following methods:
their target path.
* `treatPackageAsDirectory` _macOS_ - Treat packages, such as `.app` folders,
as a directory instead of a file.
* `dontAddToRecent` _Windows_ - Do not add the item being opened to the recent documents list.
* `message` String (optional) _macOS_ - Message to display above input
boxes.
* `securityScopedBookmarks` Boolean (optional) _macOS_ _mas_ - Create [security scoped bookmarks](https://developer.apple.com/library/content/documentation/Security/Conceptual/AppSandboxDesignGuide/AppSandboxInDepth/AppSandboxInDepth.html#//apple_ref/doc/uid/TP40011183-CH3-SW16) when packaged for the Mac App Store.
@@ -111,7 +110,6 @@ dialog.showOpenDialogSync(mainWindow, {
their target path.
* `treatPackageAsDirectory` _macOS_ - Treat packages, such as `.app` folders,
as a directory instead of a file.
* `dontAddToRecent` _Windows_ - Do not add the item being opened to the recent documents list.
* `message` String (optional) _macOS_ - Message to display above input
boxes.
* `securityScopedBookmarks` Boolean (optional) _macOS_ _mas_ - Create [security scoped bookmarks](https://developer.apple.com/library/content/documentation/Security/Conceptual/AppSandboxDesignGuide/AppSandboxInDepth/AppSandboxInDepth.html#//apple_ref/doc/uid/TP40011183-CH3-SW16) when packaged for the Mac App Store.
@@ -173,13 +171,6 @@ dialog.showOpenDialog(mainWindow, {
displayed in front of the filename text field.
* `showsTagField` Boolean (optional) _macOS_ - Show the tags input box,
defaults to `true`.
* `properties` String[] (optional)
* `showHiddenFiles` - Show hidden files in dialog.
* `createDirectory` _macOS_ - Allow creating new directories from dialog.
* `treatPackageAsDirectory` _macOS_ - Treat packages, such as `.app` folders,
as a directory instead of a file.
* `showOverwriteConfirmation` _Linux_ - Sets whether the user will be presented a confirmation dialog if the user types a file name that already exists.
* `dontAddToRecent` _Windows_ - Do not add the item being saved to the recent documents list.
* `securityScopedBookmarks` Boolean (optional) _macOS_ _mas_ - Create a [security scoped bookmark](https://developer.apple.com/library/content/documentation/Security/Conceptual/AppSandboxDesignGuide/AppSandboxInDepth/AppSandboxInDepth.html#//apple_ref/doc/uid/TP40011183-CH3-SW16) when packaged for the Mac App Store. If this option is enabled and the file doesn't already exist a blank file will be created at the chosen path.
Returns `String | undefined`, the path of the file chosen by the user; if the dialog is cancelled it returns `undefined`.
@@ -202,14 +193,8 @@ The `filters` specifies an array of file types that can be displayed, see
* `message` String (optional) _macOS_ - Message to display above text fields.
* `nameFieldLabel` String (optional) _macOS_ - Custom label for the text
displayed in front of the filename text field.
* `showsTagField` Boolean (optional) _macOS_ - Show the tags input box, defaults to `true`.
* `properties` String[] (optional)
* `showHiddenFiles` - Show hidden files in dialog.
* `createDirectory` _macOS_ - Allow creating new directories from dialog.
* `treatPackageAsDirectory` _macOS_ - Treat packages, such as `.app` folders,
as a directory instead of a file.
* `showOverwriteConfirmation` _Linux_ - Sets whether the user will be presented a confirmation dialog if the user types a file name that already exists.
* `dontAddToRecent` _Windows_ - Do not add the item being saved to the recent documents list.
* `showsTagField` Boolean (optional) _macOS_ - Show the tags input box,
defaults to `true`.
* `securityScopedBookmarks` Boolean (optional) _macOS_ _mas_ - Create a [security scoped bookmark](https://developer.apple.com/library/content/documentation/Security/Conceptual/AppSandboxDesignGuide/AppSandboxInDepth/AppSandboxInDepth.html#//apple_ref/doc/uid/TP40011183-CH3-SW16) when packaged for the Mac App Store. If this option is enabled and the file doesn't already exist a blank file will be created at the chosen path.
Returns `Promise<Object>` - Resolve with an object containing the following:

View File

@@ -77,6 +77,7 @@ only the next time a message is sent to `channel`, after which it is removed.
* `channel` String
* `listener` Function
* `...args` any[]
Removes the specified `listener` from the listener array for the specified
`channel`.
@@ -147,4 +148,4 @@ found in the [`ipc-main-invoke-event`](structures/ipc-main-invoke-event.md)
structure docs.
[event-emitter]: https://nodejs.org/api/events.html#events_class_eventemitter
[web-contents-send]: web-contents.md#contentssendchannel-arg1-arg2-
[web-contents-send]: web-contents.md#contentssendchannel-args

View File

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

View File

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

View File

@@ -37,7 +37,6 @@ Returns `Boolean` - Whether or not desktop notifications are supported on the cu
* `hasReply` Boolean (optional) _macOS_ - Whether or not to add an inline reply option to the notification.
* `replyPlaceholder` String (optional) _macOS_ - The placeholder to write in the inline reply input field.
* `sound` String (optional) _macOS_ - The name of the sound file to play when the notification is shown.
* `urgency` String (optional) _Linux_ - The urgency level of the notification. Can be 'normal', 'critical', or 'low'.
* `actions` [NotificationAction[]](structures/notification-action.md) (optional) _macOS_ - Actions to add to the notification. Please read the available actions and limitations in the `NotificationAction` documentation.
* `closeButtonText` String (optional) _macOS_ - A custom title for the close button of an alert. An empty string will cause the default localized text to be used.
@@ -145,12 +144,6 @@ A `Boolean` property representing whether the notification is silent.
A `Boolean` property representing whether the notification has a reply action.
#### `notification.urgency` _Linux_
A `String` property representing the urgency level of the notification. Can be 'normal', 'critical', or 'low'.
Default is 'low' - see [NotifyUrgency](https://developer.gnome.org/notification-spec/#urgency-levels) for more information.
#### `notification.actions`
A [`NotificationAction[]`](structures/notification-action.md) property representing the actions of the notification.

View File

@@ -217,11 +217,15 @@ that all statistics are reported in Kilobytes.
Returns `String` - The version of the host operating system.
Examples:
Example:
* `macOS` -> `10.13.6`
* `Windows` -> `10.0.17763`
* `Linux` -> `4.15.0-45-generic`
```js
const version = process.getSystemVersion()
console.log(version)
// On macOS -> '10.13.6'
// On Windows -> '10.0.17763'
// On Linux -> '4.15.0-45-generic'
```
**Note:** It returns the actual operating system version instead of kernel version on macOS unlike `os.release()`.

View File

@@ -91,7 +91,7 @@ session.defaultSession.on('will-download', (event, item, webContents) => {
})
```
#### Event: 'preconnect'
#### Event: 'preconnect' _Experimental_
Returns:
@@ -139,9 +139,9 @@ Writes any unwritten DOMStorage data to disk.
#### `ses.setProxy(config)`
* `config` Object
* `pacScript` String (optional) - The URL associated with the PAC file.
* `proxyRules` String (optional) - Rules indicating which proxies to use.
* `proxyBypassRules` String (optional) - Rules indicating which URLs should
* `pacScript` String - The URL associated with the PAC file.
* `proxyRules` String - Rules indicating which proxies to use.
* `proxyBypassRules` String - Rules indicating which URLs should
bypass the proxy settings.
Returns `Promise<void>` - Resolves when the proxy setting process is complete.
@@ -252,7 +252,7 @@ window.webContents.session.enableNetworkEmulation({
window.webContents.session.enableNetworkEmulation({ offline: true })
```
#### `ses.preconnect(options)`
#### `ses.preconnect(options)` _Experimental_
* `options` Object
* `url` String - URL for preconnect. Only the origin is relevant for opening the socket.
@@ -267,7 +267,7 @@ the original network configuration.
#### `ses.setCertificateVerifyProc(proc)`
* `proc` Function | null
* `proc` Function
* `request` Object
* `hostname` String
* `certificate` [Certificate](structures/certificate.md)
@@ -408,17 +408,6 @@ Returns `String` - The user agent for this session.
Returns `Promise<Buffer>` - resolves with blob data.
#### `ses.downloadURL(url)`
* `url` String
Initiates a download of the resource at `url`.
The API will generate a [DownloadItem](download-item.md) that can be accessed
with the [will-download](#event-will-download) event.
**Note:** This does not perform any security checks that relate to a page's origin,
unlike [`webContents.downloadURL`](web-contents.md#contentsdownloadurlurl).
#### `ses.createInterruptedDownload(options)`
* `options` Object
@@ -427,8 +416,8 @@ unlike [`webContents.downloadURL`](web-contents.md#contentsdownloadurlurl).
* `mimeType` String (optional)
* `offset` Integer - Start range for the download.
* `length` Integer - Total length of the download.
* `lastModified` String (optional) - Last-Modified header value.
* `eTag` String (optional) - ETag header value.
* `lastModified` String - Last-Modified header value.
* `eTag` String - ETag header value.
* `startTime` Double (optional) - Time when download was started in
number of seconds since UNIX epoch.

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -8,6 +8,6 @@ Process: [Main](../tutorial/application-architecture.md#main-and-renderer-proces
* `options` Object
* `size` String (optional) - Size of spacer, possible values are:
* `small` - Small space between items. Maps to `NSTouchBarItemIdentifierFixedSpaceSmall`. This is the default.
* `large` - Large space between items. Maps to `NSTouchBarItemIdentifierFixedSpaceLarge`.
* `flexible` - Take up all available space. Maps to `NSTouchBarItemIdentifierFlexibleSpace`.
* `small` - Small space between items.
* `large` - Large space between items.
* `flexible` - Take up all available space.

View File

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

View File

@@ -1264,8 +1264,6 @@ Returns [`PrinterInfo[]`](structures/printer-info.md).
* `dpi` Object (optional)
* `horizontal` Number (optional) - The horizontal dpi.
* `vertical` Number (optional) - The vertical dpi.
* `header` String (optional) - String to be printed as page header.
* `footer` String (optional) - String to be printed as page footer.
* `callback` Function (optional)
* `success` Boolean - Indicates success of the print call.
* `failureReason` String - Called back if the print fails; can be `cancelled` or `failed`.
@@ -1593,8 +1591,8 @@ End subscribing for frame presentation events.
* `item` Object
* `file` String[] | String - The path(s) to the file(s) being dragged.
* `icon` [NativeImage](native-image.md) | String - The image must be
non-empty on macOS.
* `icon` [NativeImage](native-image.md) - The image must be non-empty on
macOS.
Sets the `item` as dragging item for current drag-drop operation, `file` is the
absolute path of the file to be dragged, and `icon` is the image showing under

View File

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

View File

@@ -46,7 +46,7 @@ You can avoid much of the wait by reusing Electron CI's build output via
optional steps (listed below) and these two environment variables:
```sh
export SCCACHE_BUCKET="electronjs-sccache"
export SCCACHE_BUCKET="electronjs-sccache-ci"
export SCCACHE_TWO_TIER=true
```

View File

@@ -5,15 +5,8 @@ Follow the guidelines below for building Electron on Windows.
## Prerequisites
* Windows 10 / Server 2012 R2 or higher
* Visual Studio 2017 15.7.2 or higher - [download VS 2019 Community Edition for
* Visual Studio 2017 15.7.2 or higher - [download VS 2017 Community Edition for
free](https://www.visualstudio.com/vs/)
* See [the Chromium build documentation](https://chromium.googlesource.com/chromium/src/+/master/docs/windows_build_instructions.md#visual-studio) for more details on which Visual Studio
components are required.
* If your Visual Studio is installed in a directory other than the default, you'll need to
set a few environment variables to point the toolchains to your installation path.
* `vs2019_install = DRIVE:\path\to\Microsoft Visual Studio\2019\Community`
(replace `2019` and `Community` with your installed versions)
* `WINDOWSSDKDIR = DRIVE:\path\to\Windows Kits\10`
* [Python 2.7.10 or higher](http://www.python.org/download/releases/2.7/)
* Contrary to the `depot_tools` setup instructions linked below, you will need
to use your locally installed Python with at least version 2.7.10 (with
@@ -120,10 +113,3 @@ This can happen during build, when Debugging Tools for Windows has been installe
### ImportError: No module named win32file
Make sure you have installed `pywin32` with `pip install pywin32`.
### Build Scripts Hang Until Keypress
This bug is a "feature" of Windows' command prompt. It happens when clicking inside the prompt window with
`QuickEdit` enabled and is intended to allow selecting and copying output text easily.
Since each accidental click will pause the build process, you might want to disable this
feature in the command prompt properties.

View File

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 868 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

View File

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

View File

@@ -17,10 +17,10 @@ $ code electron-quick-start
"name": "Debug Main Process",
"type": "node",
"request": "launch",
"cwd": "${workspaceFolder}",
"runtimeExecutable": "${workspaceFolder}/node_modules/.bin/electron",
"cwd": "${workspaceRoot}",
"runtimeExecutable": "${workspaceRoot}/node_modules/.bin/electron",
"windows": {
"runtimeExecutable": "${workspaceFolder}/node_modules/.bin/electron.cmd"
"runtimeExecutable": "${workspaceRoot}/node_modules/.bin/electron.cmd"
},
"args" : ["."],
"outputCapture": "std"

View File

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

View File

@@ -0,0 +1,431 @@
# Performance
Developers frequently ask about strategies to optimize the performance of
Electron applications. Software engineers, consumers, and framework developers
do not always agree on one single definition of what "performance" means. This
document outlines some of the Electron maintainers' favorite ways to reduce the
amount of memory, CPU, and disk resources being used while ensuring that your
app is responsive to user input and completes operations as quickly as
possible. Furthermore, we want all performance strategies to maintain a high
standard for your app's security.
Wisdom and information about how to build performant websites with JavaScript
generally applies to Electron apps, too. To a certain extent, resources
discussing how to build performant Node.js applications also apply, but be
careful to understand that the term "performance" means different things for
a Node.js backend than it does for an application running on a client.
This list is provided for your convenience and is, much like our
[security checklist][security] not meant to exhaustive. It is probably possible
to build a slow Electron app that follows all the steps outlined below. Electron
is a powerful development platform that enables you, the developer, to do more
or less whatever you want. All that freedom means that performance is largely
your responsibility.
## Measure, Measure, Measure
The list below contains a number of steps that are fairly straightforward and
easy to implement. However, building the most performant version of your app
will require you to go beyond a number of steps. Instead, you will have to
closely examine all the code running in your app by carefully profiling and
measuring. Where are the bottlenecks? When the user clicks a button, what
operations take up the brunt of the time? While the app is simply idling, which
objects take up the most memory?
Time and time again, we have seen that the most successful strategy for building
a performant Electron app is to profile the running code, find the most
resource-hungry piece of it, and to optimize it. Repeating this seemingly
laborious process over and over again will dramatically increase your app's
performance. Experience from working with major apps like Visual Studio Code or
Slack has shown that this practice is by far the most reliable strategy to
improve performance.
To learn more about how to profile your app's code, familiarize yourself with
the Chrome Developer Tools. For advanced analysis looking at multiple processes
at once, consider the [Chrome Tracing] tool.
### Recommended Reading
* [Get Started With Analyzing Runtime Performance][chrome-devtools-tutorial]
* [Talk: "Visual Studio Code - The First Second"][vscode-first-second]
## Checklist
Chances are that your app could be a little leaner, faster, and generally less
resource-hungry if you attempt these steps.
1. [Carelessly including modules](#1-carelessly-including-modules)
2. [Loading and running code too soon](#2-loading-and-running-code-too-soon)
3. [Blocking the main process](#3-blocking-the-main-process)
4. [Blocking the renderer process](#4-blocking-the-renderer-process)
5. [Unnecessary polyfills](#5-unnecessary-polyfills)
6. [Unnecessary or blocking network requests](#6-unnecessary-or-blocking-network-requests)
7. [Bundle your code](#7-bundle-your-code)
## 1) Carelessly including modules
Before adding a Node.js module to your application, examine said module. How
many dependencies does that module include? What kind of resources does
it need to simply be called in a `require()` statement? You might find
that the module with the most downloads on the NPM package registry or the most stars on GitHub
is not in fact the leanest or smallest one available.
### Why?
The reasoning behind this recommendation is best illustrated with a real-world
example. During the early days of Electron, reliable detection of network
connectivity was a problem, resulting many apps to use a module that exposed a
simple `isOnline()` method.
That module detected your network connectivity by attempting to reach out to a
number of well-known endpoints. For the list of those endpoints, it depended on
a different module, which also contained a list of well-known ports. This
dependency itself relied on a module containing information about ports, which
came in the form of a JSON file with more than 100,000 lines of content.
Whenever the module was loaded (usually in a `require('module')` statement),
it would load all its dependencies and eventually read and parse this JSON
file. Parsing many thousands lines of JSON is a very expensive operation. On
a slow machine it can take up whole seconds of time.
In many server contexts, startup time is virtually irrelevant. A Node.js server
that requires information about all ports is likely actually "more performant"
if it loads all required information into memory whenever the server boots at
the benefit of serving requests faster. The module discussed in this example is
not a "bad" module. Electron apps, however, should not be loading, parsing, and
storing in memory information that it does not actually need.
In short, a seemingly excellent module written primarily for Node.js servers
running Linux might be bad news for your app's performance. In this particular
example, the correct solution was to use no module at all, and to instead use
connectivity checks included in later versions of Chromium.
### How?
When considering a module, we recommend that you check:
1. the size of dependencies included
2) the resources required to load (`require()`) it
3. the resources required to perform the action you're interested in
Generating a CPU profile and a heap memory profile for loading a module can be done
with a single command on the command line. In the example below, we're looking at
the popular module `request`.
```sh
node --cpu-prof --heap-prof -e "require('request')"
```
Executing this command results in a `.cpuprofile` file and a `.heapprofile`
file in the directory you executed it in. Both files can be analyzed using
the Chrome Developer Tools, using the `Performance` and `Memory` tabs
respectively.
![performance-cpu-prof]
![performance-heap-prof]
In this example, on the author's machine, we saw that loading `request` took
almost half a second, whereas `node-fetch` took dramatically less memory
and less than 50ms.
## 2) Loading and running code too soon
If you have expensive setup operations, consider deferring those. Inspect all
the work being executed right after the application starts. Instead of firing
off all operations right away, consider staggering them in a sequence more
closely aligned with the user's journey.
In traditional Node.js development, we're used to putting all our `require()`
statements at the top. If you're currently writing your Electron application
using the same strategy _and_ are using sizable modules that you do not
immediately need, apply the same strategy and defer loading to a more
opportune time.
### Why?
Loading modules is a surprisingly expensive operation, especially on Windows.
When your app starts, it should not make users wait for operations that are
currently not necessary.
This might seem obvious, but many applications tend to do a large amount of
work immediately after the app has launched - like checking for updates,
downloading content used in a later flow, or performing heavy disk I/O
operations.
Let's consider Visual Studio Code as an example. When you open a file, it will
immediately display the file to you without any code highlighting, prioritizing
your ability to interact with the text. Once it has done that work, it will
move on to code highlighting.
### How?
Let's consider an example and assume that your application is parsing files
in the fictitious `.foo` format. In order to do that, it relies on the
equally fictitious `foo-parser` module. In traditional Node.js development,
you might write code that eagerly loads dependencies:
```js
const fs = require('fs')
const fooParser = require('foo-parser')
class Parser {
constructor () {
this.files = fs.readdirSync('.')
}
getParsedFiles () {
return fooParser.parse(this.files)
}
}
const parser = new Parser()
module.exports = { parser }
```
In the above example, we're doing a lot of work that's being executed as soon
as the file is loaded. Do we need to get parsed files right away? Could we
do this work a little later, when `getParsedFiles()` is actually called?
```js
// "fs" is likely already being loaded, so the `require()` call is cheap
const fs = require('fs')
class Parser {
async getFiles () {
// Touch the disk as soon as `getFiles` is called, not sooner.
// Also, ensure that we're not blocking other operations by using
// the asynchronous version.
this.files = this.files || await fs.readdir('.')
return this.files
}
async getParsedFiles () {
// Our fictitious foo-parser is a big and expensive module to load, so
// defer that work until we actually need to parse files.
// Since `require()` comes with a module cache, the `require()` call
// will only be expensive once - subsequent calls of `getParsedFiles()`
// will be faster.
const fooParser = require('foo-parser')
const files = await this.getFiles()
return fooParser.parse(files)
}
}
// This operation is now a lot cheaper than in our previous example
const parser = new Parser()
module.exports = { parser }
```
In short, allocate resources "just in time" rather than allocating them all
when your app starts.
## 3) Blocking the main process
Electron's main process (sometimes called "browser process") is special: It is
the parent process to all your app's other processes and the primary process
the operating system interacts with. It handles windows, interactions, and the
communication between various components inside your app. It also houses the
UI thread.
Under no circumstances should you block this process and the UI thread with
long-running operations. Blocking the UI thread means that your entire app
will freeze until the main process is ready to continue processing.
### Why?
The main process and its UI thread are essentially the control tower for major
operations inside your app. When the operating system tells your app about a
mouse click, it'll go through the main process before it reaches your window.
If your window is rendering a buttery-smooth animation, it'll need to talk to
the GPU process about that once again going through the main process.
Electron and Chromium are careful to put heavy disk I/O and CPU-bound operations
onto new threads to avoid blocking the UI thread. You should do the same.
### How?
Electron's powerful multi-process architecture stands ready to assist you with
your long-running tasks, but also includes a small number of performance traps.
1) For long running CPU-heavy tasks, make use of
[worker threads][worker-threads], consider moving them to the BrowserWindow, or
(as a last resort) spawn a dedicated process.
2) Avoid using the synchronous IPC and the `remote` module as much as possible.
While there are legitimate use cases, it is far too easy to unknowingly block
the UI thread using the `remote` module.
3) Avoid using blocking I/O operations in the main process. In short, whenever
core Node.js modules (like `fs` or `child_process`) offer a synchronous or an
asynchronous version, you should prefer the asynchronous and non-blocking
variant.
## 4) Blocking the renderer process
Since Electron ships with a current version of Chrome, you can make use of the
latest and greatest features the Web Platform offers to defer or offload heavy
operations in a way that keeps your app smooth and responsive.
### Why?
Your app probably has a lot of JavaScript to run in the renderer process. The
trick is to execute operations as quickly as possible without taking away
resources needed to keep scrolling smooth, respond to user input, or animations
at 60fps.
Orchestrating the flow of operations in your renderer's code is
particularly useful if users complain about your app sometimes "stuttering".
### How?
Generally speaking, all advice for building performant web apps for modern
browsers apply to Electron's renderers, too. The two primary tools at your
disposal are currently `requestIdleCallback()` for small operations and
`Web Workers` for long-running operations.
*`requestIdleCallback()`* allows developers to queue up a function to be
executed as soon as the process is entering an idle period. It enables you to
perform low-priority or background work without impacting the user experience.
For more information about how to use it,
[check out its documentation on MDN][request-idle-callback].
*Web Workers* are a powerful tool to run code on a separate thread. There are
some caveats to consider  consult Electron's
[multithreading documentation][multithreading] and the
[MDN documentation for Web Workers][web-workers]. They're an ideal solution
for any operation that requires a lot of CPU power for an extended period of
time.
## 5) Unnecessary polyfills
One of Electron's great benefits is that you know exactly which engine will
parse your JavaScript, HTML, and CSS. If you're re-purposing code that was
written for the web at large, make sure to not polyfill features included in
Electron.
### Why?
When building a web application for today's Internet, the oldest environments
dictate what features you can and cannot use. Even though Electron supports
well-performing CSS filters and animations, an older browser might not. Where
you could use WebGL, your developers may have chosen a more resource-hungry
solution to support older phones.
When it comes to JavaScript, you may have included toolkit libraries like
jQuery for DOM selectors or polyfills like the `regenerator-runtime` to support
`async/await`.
It is rare for a JavaScript-based polyfill to be faster than the equivalent
native feature in Electron. Do not slow down your Electron app by shipping your
own version of standard web platform features.
### How?
Operate under the assumption that polyfills in current versions of Electron
are unnecessary. If you have doubts, check [caniuse.com][https://caniuse.com/]
and check if the [version of Chromium used in your Electron version](../api/process.md#processversionschrome-readonly)
supports the feature you desire.
In addition, carefully examine the libraries you use. Are they really necessary?
`jQuery`, for example, was such a success that many of its features are now part
of the [standard JavaScript feature set available][jquery-need].
If you're using a transpiler/compiler like TypeScript, examine its configuration
and ensure that you're targeting the latest ECMAScript version supported by
Electron.
## 6) Unnecessary or blocking network requests
Avoid fetching rarely changing resources from the internet if they could easily
be bundled with your application.
### Why?
Many users of Electron start with an entirely web-based app that they're
turning into a desktop application. As web developers, we are used to loading
resources from a variety of content delivery networks. Now that you are
shipping a proper desktop application, attempt to "cut the cord" where possible
- and avoid letting your users wait for resources that never change and could
easily be included in your app.
A typical example is Google Fonts. Many developers make use of Google's
impressive collection of free fonts, which comes with a content delivery
network. The pitch is straightforward: Include a few lines of CSS and Google
will take care of the rest.
When building an Electron app, your users are better served if you download
the fonts and include them in your app's bundle.
### How?
In an ideal world, your application wouldn't need the network to operate at
all. To get there, you must understand what resources your app is downloading
\- and how large those resources are.
To do so, open up the developer tools. Navigate to the `Network` tab and check
the `Disable cache` option. Then, reload your renderer. Unless your app
prohibits such reloads, you can usually trigger a reload by hitting `Cmd + R`
or `Ctrl + R` with the developer tools in focus.
The tools will now meticulously record all network requests. In a first pass,
take stock of all the resources being downloaded, focusing on the larger files
first. Are any of them images, fonts, or media files that don't change and
could be included with your bundle? If so, include them.
As a next step, enable `Network Throttling`. Find the drop-down that currently
reads `Online` and select a slower speed such as `Fast 3G`. Reload your
renderer and see if there are any resources that your app is unnecessarily
waiting for. In many cases, an app will wait for a network request to complete
despite not actually needing the involved resource.
As a tip, loading resources from the Internet that you might want to change
without shipping an application update is a powerful strategy. For advanced
control over how resources are being loaded, consider investing in
[Service Workers][service-workers].
## 7) Bundle your code
As already pointed out in
"[Loading and running code too soon](#2-loading-and-running-code-too-soon)",
calling `require()` is an expensive operation. If you are able to do so,
bundle your application's code into a single file.
### Why?
Modern JavaScript development usually involves many files and modules. While
that's perfectly fine for developing with Electron, we heavily recommend that
you bundle all your code into one single file to ensure that the overhead
included in calling `require()` is only paid once when your application loads.
### How?
There are numerous JavaScript bundlers out there and we know better than to
anger the community by recommending one tool over another. We do however
recommend that you use a bundler that is able to handle Electron's unique
environment that needs to handle both Node.js and browser environments.
As of writing this article, the popular choices include [Webpack][webpack],
[Parcel][parcel], and [rollup.js][rollup].
[security]: ./security.md
[performance-cpu-prof]: ../images/performance-cpu-prof.png
[performance-heap-prof]: ../images/performance-heap-prof.png
[chrome-devtools-tutorial]: https://developers.google.com/web/tools/chrome-devtools/evaluate-performance/
[worker-threads]: https://nodejs.org/api/worker_threads.html
[web-workers]: https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Using_web_workers
[request-idle-callback]: https://developer.mozilla.org/en-US/docs/Web/API/Window/requestIdleCallback
[multithreading]: ./multithreading.md
[caniuse]: https://caniuse.com/
[jquery-need]: http://youmightnotneedjquery.com/
[service-workers]: https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API
[webpack]: https://webpack.js.org/
[parcel]: https://parceljs.org/
[rollup]: https://rollupjs.org/
[vscode-first-second]: https://www.youtube.com/watch?v=r0OeHRUCCb4

View File

@@ -43,8 +43,7 @@ When releasing your product, youre also shipping a bundle composed of Electro
Chromium shared library and Node.js. Vulnerabilities affecting these components
may impact the security of your application. By updating Electron to the latest
version, you ensure that critical vulnerabilities (such as *nodeIntegration bypasses*)
are already patched and cannot be exploited in your application. For more information,
see "[Use a current version of Electron](#17-use-a-current-version-of-electron)".
are already patched and cannot be exploited in your application.
* **Evaluate your dependencies.** While NPM provides half a million reusable packages,
it is your responsibility to choose trusted 3rd-party libraries. If you use outdated
@@ -102,7 +101,6 @@ You should at least follow these steps to improve the security of your applicati
14. [Do not use `openExternal` with untrusted content](#14-do-not-use-openexternal-with-untrusted-content)
15. [Disable the `remote` module](#15-disable-the-remote-module)
16. [Filter the `remote` module](#16-filter-the-remote-module)
17. [Use a current version of Electron](#17-use-a-current-version-of-electron)
To automate the detection of misconfigurations and insecure patterns, it is
possible to use
@@ -513,7 +511,7 @@ no circumstances should you enable features speculatively.
// Bad
const mainWindow = new BrowserWindow({
webPreferences: {
enableBlinkFeatures: 'ExecCommandInJavaScript'
enableBlinkFeatures: ['ExecCommandInJavaScript']
}
})
```
@@ -832,29 +830,6 @@ app.on('remote-get-guest-web-contents', (event, webContents, guestWebContents) =
})
```
## 17) Use a current version of Electron
You should strive for always using the latest available version of Electron.
Whenever a new major version is released, you should attempt to update your
app as quickly as possible.
### Why?
An application built with an older version of Electron, Chromium, and Node.js
is an easier target than an application that is using more recent versions of
those components. Generally speaking, security issues and exploits for older
versions of Chromium and Node.js are more widely available.
Both Chromium and Node.js are impressive feats of engineering built by
thousands of talented developers. Given their popularity, their security is
carefully tested and analyzed by equally skilled security researchers. Many of
those researchers [disclose vulnerabilities responsibly][responsible-disclosure],
which generally means that researchers will give Chromium and Node.js some time
to fix issues before publishing them. Your application will be more secure if
it is running a recent version of Electron (and thus, Chromium and Node.js) for
which potential security issues are not as widely known.
[browser-window]: ../api/browser-window.md
[browser-view]: ../api/browser-view.md
[webview-tag]: ../api/webview-tag.md
@@ -863,4 +838,3 @@ which potential security issues are not as widely known.
[will-navigate]: ../api/web-contents.md#event-will-navigate
[open-external]: ../api/shell.md#shellopenexternalurl-options-callback
[sandbox]: ../api/sandbox-option.md
[responsible-disclosure]: https://en.wikipedia.org/wiki/Responsible_disclosure

View File

@@ -139,7 +139,7 @@ const options = {
port: 9515, // "9515" is the port opened by chrome driver.
desiredCapabilities: {
browserName: 'chrome',
'goog:chromeOptions': {
chromeOptions: {
binary: '/Path-to-Your-App/electron', // Path to your Electron binary.
args: [/* cli arguments */] // Optional, perhaps 'app=' + /path/to/your/app/
}

View File

@@ -147,7 +147,7 @@ template("electron_paks") {
source_patterns = [
"${root_gen_dir}/chrome/platform_locale_settings_",
"${root_gen_dir}/components/strings/components_strings_",
"${root_gen_dir}/third_party/blink/public/strings/blink_strings_",
"${root_gen_dir}/content/app/strings/content_strings_",
"${root_gen_dir}/device/bluetooth/strings/bluetooth_strings_",
"${root_gen_dir}/services/strings/services_strings_",
"${root_gen_dir}/ui/strings/app_locale_settings_",
@@ -156,9 +156,9 @@ template("electron_paks") {
deps = [
"//chrome/app/resources:platform_locale_settings",
"//components/strings:components_strings",
"//content/app/strings",
"//device/bluetooth/strings",
"//services/strings",
"//third_party/blink/public/strings",
"//ui/strings:app_locale_settings",
"//ui/strings:ui_strings",
]

View File

@@ -14,6 +14,7 @@ auto_filenames = {
"docs/api/clipboard.md",
"docs/api/command-line.md",
"docs/api/content-tracing.md",
"docs/api/context-bridge.md",
"docs/api/cookies.md",
"docs/api/crash-reporter.md",
"docs/api/debugger.md",
@@ -130,22 +131,24 @@ auto_filenames = {
"lib/browser/api/module-keys.js",
"lib/common/api/clipboard.js",
"lib/common/api/deprecate.ts",
"lib/common/api/module-list.ts",
"lib/common/api/module-list.js",
"lib/common/api/native-image.js",
"lib/common/api/shell.js",
"lib/common/buffer-utils.ts",
"lib/common/clipboard-utils.ts",
"lib/common/crash-reporter.js",
"lib/common/define-properties.ts",
"lib/common/electron-binding-setup.ts",
"lib/common/error-utils.ts",
"lib/common/remote/buffer-utils.ts",
"lib/common/remote/is-promise.ts",
"lib/common/is-promise.ts",
"lib/common/web-view-methods.ts",
"lib/common/webpack-globals-provider.ts",
"lib/renderer/api/context-bridge.ts",
"lib/renderer/api/crash-reporter.js",
"lib/renderer/api/desktop-capturer.ts",
"lib/renderer/api/ipc-renderer.ts",
"lib/renderer/api/ipc-renderer.js",
"lib/renderer/api/remote.js",
"lib/renderer/api/web-frame.ts",
"lib/renderer/callbacks-registry.ts",
"lib/renderer/chrome-api.ts",
"lib/renderer/content-scripts-injector.ts",
"lib/renderer/extensions/event.ts",
@@ -155,7 +158,6 @@ auto_filenames = {
"lib/renderer/inspector.ts",
"lib/renderer/ipc-renderer-internal-utils.ts",
"lib/renderer/ipc-renderer-internal.ts",
"lib/renderer/remote/callbacks-registry.ts",
"lib/renderer/security-warnings.ts",
"lib/renderer/web-frame-init.ts",
"lib/renderer/web-view/guest-view-internal.ts",
@@ -164,8 +166,8 @@ auto_filenames = {
"lib/renderer/web-view/web-view-element.ts",
"lib/renderer/web-view/web-view-impl.ts",
"lib/renderer/web-view/web-view-init.ts",
"lib/sandboxed_renderer/api/exports/electron.ts",
"lib/sandboxed_renderer/api/module-list.ts",
"lib/sandboxed_renderer/api/exports/electron.js",
"lib/sandboxed_renderer/api/module-list.js",
"lib/sandboxed_renderer/init.js",
"package.json",
"tsconfig.electron.json",
@@ -175,6 +177,7 @@ auto_filenames = {
isolated_bundle_deps = [
"lib/common/electron-binding-setup.ts",
"lib/common/error-utils.ts",
"lib/common/webpack-globals-provider.ts",
"lib/isolated_renderer/init.js",
"lib/renderer/ipc-renderer-internal-utils.ts",
"lib/renderer/ipc-renderer-internal.ts",
@@ -189,6 +192,7 @@ auto_filenames = {
content_script_bundle_deps = [
"lib/common/electron-binding-setup.ts",
"lib/common/error-utils.ts",
"lib/common/webpack-globals-provider.ts",
"lib/content_script/init.js",
"lib/renderer/chrome-api.ts",
"lib/renderer/extensions/event.ts",
@@ -214,7 +218,7 @@ auto_filenames = {
"lib/browser/api/content-tracing.js",
"lib/browser/api/crash-reporter.js",
"lib/browser/api/dialog.js",
"lib/browser/api/exports/electron.ts",
"lib/browser/api/exports/electron.js",
"lib/browser/api/global-shortcut.js",
"lib/browser/api/in-app-purchase.js",
"lib/browser/api/ipc-main.ts",
@@ -222,7 +226,7 @@ auto_filenames = {
"lib/browser/api/menu-item.js",
"lib/browser/api/menu-utils.js",
"lib/browser/api/menu.js",
"lib/browser/api/module-list.ts",
"lib/browser/api/module-list.js",
"lib/browser/api/native-theme.ts",
"lib/browser/api/net-log.js",
"lib/browser/api/net.js",
@@ -254,30 +258,29 @@ auto_filenames = {
"lib/browser/guest-view-manager.js",
"lib/browser/guest-window-manager.js",
"lib/browser/init.ts",
"lib/browser/ipc-main-impl.ts",
"lib/browser/ipc-main-internal-utils.ts",
"lib/browser/ipc-main-internal.ts",
"lib/browser/navigation-controller.js",
"lib/browser/remote/objects-registry.js",
"lib/browser/remote/server.js",
"lib/browser/objects-registry.js",
"lib/browser/rpc-server.js",
"lib/browser/utils.ts",
"lib/common/api/clipboard.js",
"lib/common/api/deprecate.ts",
"lib/common/api/module-list.ts",
"lib/common/api/exports/electron.js",
"lib/common/api/module-list.js",
"lib/common/api/native-image.js",
"lib/common/api/shell.js",
"lib/common/buffer-utils.ts",
"lib/common/clipboard-utils.ts",
"lib/common/crash-reporter.js",
"lib/common/define-properties.ts",
"lib/common/electron-binding-setup.ts",
"lib/common/error-utils.ts",
"lib/common/init.ts",
"lib/common/is-promise.ts",
"lib/common/parse-features-string.js",
"lib/common/remote/buffer-utils.ts",
"lib/common/remote/is-promise.ts",
"lib/common/reset-search-paths.ts",
"lib/common/web-view-methods.ts",
"lib/common/webpack-globals-provider.ts",
"lib/renderer/ipc-renderer-internal-utils.ts",
"lib/renderer/ipc-renderer-internal.ts",
"package.json",
@@ -289,26 +292,29 @@ auto_filenames = {
"lib/browser/api/module-keys.js",
"lib/common/api/clipboard.js",
"lib/common/api/deprecate.ts",
"lib/common/api/module-list.ts",
"lib/common/api/exports/electron.js",
"lib/common/api/module-list.js",
"lib/common/api/native-image.js",
"lib/common/api/shell.js",
"lib/common/buffer-utils.ts",
"lib/common/clipboard-utils.ts",
"lib/common/crash-reporter.js",
"lib/common/define-properties.ts",
"lib/common/electron-binding-setup.ts",
"lib/common/error-utils.ts",
"lib/common/init.ts",
"lib/common/remote/buffer-utils.ts",
"lib/common/remote/is-promise.ts",
"lib/common/is-promise.ts",
"lib/common/reset-search-paths.ts",
"lib/common/web-view-methods.ts",
"lib/common/webpack-globals-provider.ts",
"lib/renderer/api/context-bridge.ts",
"lib/renderer/api/crash-reporter.js",
"lib/renderer/api/desktop-capturer.ts",
"lib/renderer/api/exports/electron.ts",
"lib/renderer/api/ipc-renderer.ts",
"lib/renderer/api/module-list.ts",
"lib/renderer/api/exports/electron.js",
"lib/renderer/api/ipc-renderer.js",
"lib/renderer/api/module-list.js",
"lib/renderer/api/remote.js",
"lib/renderer/api/web-frame.ts",
"lib/renderer/callbacks-registry.ts",
"lib/renderer/chrome-api.ts",
"lib/renderer/content-scripts-injector.ts",
"lib/renderer/extensions/event.ts",
@@ -319,7 +325,6 @@ auto_filenames = {
"lib/renderer/inspector.ts",
"lib/renderer/ipc-renderer-internal-utils.ts",
"lib/renderer/ipc-renderer-internal.ts",
"lib/renderer/remote/callbacks-registry.ts",
"lib/renderer/security-warnings.ts",
"lib/renderer/web-frame-init.ts",
"lib/renderer/web-view/guest-view-internal.ts",
@@ -339,28 +344,30 @@ auto_filenames = {
"lib/browser/api/module-keys.js",
"lib/common/api/clipboard.js",
"lib/common/api/deprecate.ts",
"lib/common/api/module-list.ts",
"lib/common/api/exports/electron.js",
"lib/common/api/module-list.js",
"lib/common/api/native-image.js",
"lib/common/api/shell.js",
"lib/common/buffer-utils.ts",
"lib/common/clipboard-utils.ts",
"lib/common/crash-reporter.js",
"lib/common/define-properties.ts",
"lib/common/electron-binding-setup.ts",
"lib/common/error-utils.ts",
"lib/common/init.ts",
"lib/common/remote/buffer-utils.ts",
"lib/common/remote/is-promise.ts",
"lib/common/is-promise.ts",
"lib/common/reset-search-paths.ts",
"lib/common/webpack-globals-provider.ts",
"lib/renderer/api/context-bridge.ts",
"lib/renderer/api/crash-reporter.js",
"lib/renderer/api/desktop-capturer.ts",
"lib/renderer/api/exports/electron.ts",
"lib/renderer/api/ipc-renderer.ts",
"lib/renderer/api/module-list.ts",
"lib/renderer/api/exports/electron.js",
"lib/renderer/api/ipc-renderer.js",
"lib/renderer/api/module-list.js",
"lib/renderer/api/remote.js",
"lib/renderer/api/web-frame.ts",
"lib/renderer/callbacks-registry.ts",
"lib/renderer/ipc-renderer-internal-utils.ts",
"lib/renderer/ipc-renderer-internal.ts",
"lib/renderer/remote/callbacks-registry.ts",
"lib/renderer/webpack-provider.ts",
"lib/worker/init.js",
"package.json",

View File

@@ -1,7 +1,6 @@
filenames = {
default_app_ts_sources = [
"default_app/default_app.ts",
"default_app/index.ts",
"default_app/main.ts",
"default_app/preload.ts",
]
@@ -130,10 +129,6 @@ filenames = {
"shell/browser/auto_updater.cc",
"shell/browser/auto_updater.h",
"shell/browser/auto_updater_mac.mm",
"shell/browser/atom_autofill_driver_factory.cc",
"shell/browser/atom_autofill_driver_factory.h",
"shell/browser/atom_autofill_driver.cc",
"shell/browser/atom_autofill_driver.h",
"shell/browser/atom_browser_client.cc",
"shell/browser/atom_browser_client.h",
"shell/browser/atom_browser_context.cc",
@@ -435,11 +430,17 @@ filenames = {
"shell/common/api/electron_bindings.cc",
"shell/common/api/electron_bindings.h",
"shell/common/api/constructor.h",
"shell/common/api/event_emitter_caller_deprecated.cc",
"shell/common/api/event_emitter_caller_deprecated.h",
"shell/common/api/event_emitter_caller.cc",
"shell/common/api/event_emitter_caller.h",
"shell/common/api/features.cc",
"shell/common/api/locker.cc",
"shell/common/api/locker.h",
"shell/common/api/object_life_monitor.cc",
"shell/common/api/object_life_monitor.h",
"shell/common/api/remote_callback_freer.cc",
"shell/common/api/remote_callback_freer.h",
"shell/common/api/remote_object_freer.cc",
"shell/common/api/remote_object_freer.h",
"shell/common/asar/archive.cc",
"shell/common/asar/archive.h",
"shell/common/asar/asar_util.cc",
@@ -469,34 +470,12 @@ filenames = {
"shell/common/crash_reporter/linux/crash_dump_handler.h",
"shell/common/crash_reporter/win/crash_service_main.cc",
"shell/common/crash_reporter/win/crash_service_main.h",
"shell/common/gin_converters/callback_converter.h",
"shell/common/gin_converters/file_dialog_converter.cc",
"shell/common/gin_converters/file_dialog_converter.h",
"shell/common/gin_converters/file_path_converter.h",
"shell/common/gin_converters/gurl_converter.h",
"shell/common/gin_converters/image_converter.cc",
"shell/common/gin_converters/image_converter.h",
"shell/common/gin_converters/native_mate_handle_converter.h",
"shell/common/gin_converters/message_box_converter.cc",
"shell/common/gin_converters/message_box_converter.h",
"shell/common/gin_converters/native_window_converter.h",
"shell/common/gin_converters/net_converter.cc",
"shell/common/gin_converters/net_converter.h",
"shell/common/gin_converters/callback_converter_gin_adapter.h",
"shell/common/gin_converters/gurl_converter_gin_adapter.h",
"shell/common/gin_converters/net_converter_gin_adapter.h",
"shell/common/gin_converters/std_converter.h",
"shell/common/gin_converters/value_converter_gin_adapter.h",
"shell/common/gin_helper/callback.cc",
"shell/common/gin_helper/callback.h",
"shell/common/gin_helper/destroyable.cc",
"shell/common/gin_helper/destroyable.h",
"shell/common/gin_helper/dictionary.h",
"shell/common/gin_helper/error_thrower.cc",
"shell/common/gin_helper/error_thrower.h",
"shell/common/gin_helper/event_emitter_caller.cc",
"shell/common/gin_helper/event_emitter_caller.h",
"shell/common/gin_helper/function_template.cc",
"shell/common/gin_helper/function_template.h",
"shell/common/gin_helper/object_template_builder.cc",
"shell/common/gin_helper/object_template_builder.h",
"shell/common/gin_util.h",
"shell/common/heap_snapshot.cc",
"shell/common/heap_snapshot.h",
"shell/common/key_weak_map.h",
@@ -512,18 +491,22 @@ filenames = {
"shell/common/native_mate_converters/accelerator_converter.h",
"shell/common/native_mate_converters/blink_converter.cc",
"shell/common/native_mate_converters/blink_converter.h",
"shell/common/native_mate_converters/callback_converter_deprecated.cc",
"shell/common/native_mate_converters/callback_converter_deprecated.h",
"shell/common/native_mate_converters/callback.cc",
"shell/common/native_mate_converters/callback.h",
"shell/common/native_mate_converters/content_converter.cc",
"shell/common/native_mate_converters/content_converter.h",
"shell/common/native_mate_converters/file_dialog_converter.cc",
"shell/common/native_mate_converters/file_dialog_converter.h",
"shell/common/native_mate_converters/message_box_converter.cc",
"shell/common/native_mate_converters/message_box_converter.h",
"shell/common/native_mate_converters/file_path_converter.h",
"shell/common/native_mate_converters/gfx_converter.cc",
"shell/common/native_mate_converters/gfx_converter.h",
"shell/common/native_mate_converters/gurl_converter.h",
"shell/common/native_mate_converters/image_converter.cc",
"shell/common/native_mate_converters/image_converter.h",
"shell/common/native_mate_converters/map_converter.h",
"shell/common/native_mate_converters/native_window_converter.h",
"shell/common/native_mate_converters/net_converter.cc",
"shell/common/native_mate_converters/net_converter.h",
"shell/common/native_mate_converters/network_converter.cc",
"shell/common/native_mate_converters/network_converter.h",
@@ -553,6 +536,10 @@ filenames = {
"shell/common/promise_util.cc",
"shell/common/skia_util.h",
"shell/common/skia_util.cc",
"shell/renderer/api/context_bridge/render_frame_context_bridge_store.cc",
"shell/renderer/api/context_bridge/render_frame_context_bridge_store.h",
"shell/renderer/api/atom_api_context_bridge.cc",
"shell/renderer/api/atom_api_context_bridge.h",
"shell/renderer/api/atom_api_renderer_ipc.cc",
"shell/renderer/api/atom_api_spell_check_client.cc",
"shell/renderer/api/atom_api_spell_check_client.h",

View File

@@ -33,7 +33,7 @@ BrowserWindow.prototype._init = function () {
// Hide the auto-hide menu when webContents is focused.
this.webContents.on('activate', () => {
if (process.platform !== 'darwin' && this.isMenuBarAutoHide() && this.isMenuBarVisible()) {
if (process.platform !== 'darwin' && this.autoHideMenuBar && this.isMenuBarVisible()) {
this.setMenuBarVisibility(false)
}
})
@@ -118,8 +118,6 @@ BrowserWindow.fromWebContents = (webContents) => {
for (const window of BrowserWindow.getAllWindows()) {
if (window.webContents.equal(webContents)) return window
}
return null
}
BrowserWindow.fromBrowserView = (browserView) => {

View File

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

View File

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

View File

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

View File

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

View File

@@ -21,6 +21,7 @@ module.exports = [
{ name: 'inAppPurchase' },
{ name: 'Menu' },
{ name: 'MenuItem' },
{ name: 'nativeTheme' },
{ name: 'net' },
{ name: 'netLog' },
{ name: 'Notification' },

View File

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

View File

@@ -72,7 +72,6 @@ const defaultPrintingSetting = {
headerFooterEnabled: false,
marginsType: 0,
isFirstRequest: false,
requestID: getNextId(),
previewUIID: 0,
previewModifiable: true,
printToPDF: true,
@@ -205,7 +204,10 @@ WebContents.prototype.executeJavaScript = function (code, hasUserGesture) {
// Translate the options of printToPDF.
WebContents.prototype.printToPDF = function (options) {
const printingSetting = Object.assign({}, defaultPrintingSetting)
const printingSetting = {
...defaultPrintingSetting,
requestID: getNextId()
}
if (options.landscape) {
printingSetting.landscape = options.landscape
}
@@ -327,15 +329,14 @@ WebContents.prototype._init = function () {
}
})
this.on('-ipc-invoke', function (event, internal, channel, args) {
this.on('-ipc-invoke', function (event, channel, args) {
event._reply = (result) => event.sendReply({ result })
event._throw = (error) => {
console.error(`Error occurred in handler for '${channel}':`, error)
event.sendReply({ error: error.toString() })
}
const target = internal ? ipcMainInternal : ipcMain
if (target._invokeHandlers.has(channel)) {
target._invokeHandlers.get(channel)(event, ...args)
if (ipcMain._invokeHandlers.has(channel)) {
ipcMain._invokeHandlers.get(channel)(event, ...args)
} else {
event._throw(`No handler registered for '${channel}'`)
}

View File

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

View File

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

View File

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

View File

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

View File

@@ -151,16 +151,8 @@ app._setDefaultAppPaths(packagePath)
// Load the chrome devtools support.
require('@electron/internal/browser/devtools')
const features = process.electronBinding('features')
// Load the chrome extension support.
if (!features.isExtensionsEnabled()) {
require('@electron/internal/browser/chrome-extension')
}
if (features.isRemoteModuleEnabled()) {
require('@electron/internal/browser/remote/server')
}
require('@electron/internal/browser/chrome-extension')
// Load protocol module to ensure it is populated on app ready
require('@electron/internal/browser/api/protocol')

View File

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

View File

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

View File

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

View File

@@ -127,6 +127,10 @@ class ObjectsRegistry {
this.clear(webContents, contextId)
}
}
// Note that the "render-view-deleted" event may not be emitted on time when
// the renderer process get destroyed because of navigation, we rely on the
// renderer process to send "ELECTRON_BROWSER_CONTEXT_RELEASE" message to
// guard this situation.
webContents.on('render-view-deleted', listener)
}
}

View File

@@ -1,471 +0,0 @@
'use strict'
const electron = require('electron')
const { EventEmitter } = require('events')
const v8Util = process.electronBinding('v8_util')
const eventBinding = process.electronBinding('event')
const features = process.electronBinding('features')
if (!features.isRemoteModuleEnabled()) {
throw new Error('remote module is disabled')
}
const { ipcMainInternal } = require('@electron/internal/browser/ipc-main-internal')
const objectsRegistry = require('@electron/internal/browser/remote/objects-registry')
const guestViewManager = require('@electron/internal/browser/guest-view-manager')
const bufferUtils = require('@electron/internal/common/remote/buffer-utils')
const errorUtils = require('@electron/internal/common/error-utils')
const { isPromise } = require('@electron/internal/common/remote/is-promise')
const hasProp = {}.hasOwnProperty
// The internal properties of Function.
const FUNCTION_PROPERTIES = [
'length', 'name', 'arguments', 'caller', 'prototype'
]
// The remote functions in renderer processes.
// id => Function
const rendererFunctions = v8Util.createDoubleIDWeakMap()
// Return the description of object's members:
const getObjectMembers = function (object) {
let names = Object.getOwnPropertyNames(object)
// For Function, we should not override following properties even though they
// are "own" properties.
if (typeof object === 'function') {
names = names.filter((name) => {
return !FUNCTION_PROPERTIES.includes(name)
})
}
// Map properties to descriptors.
return names.map((name) => {
const descriptor = Object.getOwnPropertyDescriptor(object, name)
const member = { name, enumerable: descriptor.enumerable, writable: false }
if (descriptor.get === undefined && typeof object[name] === 'function') {
member.type = 'method'
} else {
if (descriptor.set || descriptor.writable) member.writable = true
member.type = 'get'
}
return member
})
}
// Return the description of object's prototype.
const getObjectPrototype = function (object) {
const proto = Object.getPrototypeOf(object)
if (proto === null || proto === Object.prototype) return null
return {
members: getObjectMembers(proto),
proto: getObjectPrototype(proto)
}
}
// Convert a real value into meta data.
const valueToMeta = function (sender, contextId, value, optimizeSimpleObject = false) {
// Determine the type of value.
const meta = { type: typeof value }
if (meta.type === 'object') {
// Recognize certain types of objects.
if (value === null) {
meta.type = 'value'
} else if (bufferUtils.isBuffer(value)) {
meta.type = 'buffer'
} else if (Array.isArray(value)) {
meta.type = 'array'
} else if (value instanceof Error) {
meta.type = 'error'
} else if (value instanceof Date) {
meta.type = 'date'
} else if (isPromise(value)) {
meta.type = 'promise'
} else if (hasProp.call(value, 'callee') && value.length != null) {
// Treat the arguments object as array.
meta.type = 'array'
} else if (optimizeSimpleObject && v8Util.getHiddenValue(value, 'simple')) {
// Treat simple objects as value.
meta.type = 'value'
}
}
// Fill the meta object according to value's type.
if (meta.type === 'array') {
meta.members = value.map((el) => valueToMeta(sender, contextId, el, optimizeSimpleObject))
} else if (meta.type === 'object' || meta.type === 'function') {
meta.name = value.constructor ? value.constructor.name : ''
// Reference the original value if it's an object, because when it's
// passed to renderer we would assume the renderer keeps a reference of
// it.
meta.id = objectsRegistry.add(sender, contextId, value)
meta.members = getObjectMembers(value)
meta.proto = getObjectPrototype(value)
} else if (meta.type === 'buffer') {
meta.value = bufferUtils.bufferToMeta(value)
} else if (meta.type === 'promise') {
// Add default handler to prevent unhandled rejections in main process
// Instead they should appear in the renderer process
value.then(function () {}, function () {})
meta.then = valueToMeta(sender, contextId, function (onFulfilled, onRejected) {
value.then(onFulfilled, onRejected)
})
} else if (meta.type === 'error') {
meta.members = plainObjectToMeta(value)
// Error.name is not part of own properties.
meta.members.push({
name: 'name',
value: value.name
})
} else if (meta.type === 'date') {
meta.value = value.getTime()
} else {
meta.type = 'value'
meta.value = value
}
return meta
}
// Convert object to meta by value.
const plainObjectToMeta = function (obj) {
return Object.getOwnPropertyNames(obj).map(function (name) {
return {
name: name,
value: obj[name]
}
})
}
// Convert Error into meta data.
const exceptionToMeta = function (error) {
return {
type: 'exception',
value: errorUtils.serialize(error)
}
}
const throwRPCError = function (message) {
const error = new Error(message)
error.code = 'EBADRPC'
error.errno = -72
throw error
}
const removeRemoteListenersAndLogWarning = (sender, callIntoRenderer) => {
const location = v8Util.getHiddenValue(callIntoRenderer, 'location')
let message = `Attempting to call a function in a renderer window that has been closed or released.` +
`\nFunction provided here: ${location}`
if (sender instanceof EventEmitter) {
const remoteEvents = sender.eventNames().filter((eventName) => {
return sender.listeners(eventName).includes(callIntoRenderer)
})
if (remoteEvents.length > 0) {
message += `\nRemote event names: ${remoteEvents.join(', ')}`
remoteEvents.forEach((eventName) => {
sender.removeListener(eventName, callIntoRenderer)
})
}
}
console.warn(message)
}
// Convert array of meta data from renderer into array of real values.
const unwrapArgs = function (sender, frameId, contextId, args) {
const metaToValue = function (meta) {
switch (meta.type) {
case 'value':
return meta.value
case 'remote-object':
return objectsRegistry.get(meta.id)
case 'array':
return unwrapArgs(sender, frameId, contextId, meta.value)
case 'buffer':
return bufferUtils.metaToBuffer(meta.value)
case 'date':
return new Date(meta.value)
case 'promise':
return Promise.resolve({
then: metaToValue(meta.then)
})
case 'object': {
const ret = {}
Object.defineProperty(ret.constructor, 'name', { value: meta.name })
for (const { name, value } of meta.members) {
ret[name] = metaToValue(value)
}
return ret
}
case 'function-with-return-value':
const returnValue = metaToValue(meta.value)
return function () {
return returnValue
}
case 'function': {
// Merge contextId and meta.id, since meta.id can be the same in
// different webContents.
const objectId = [contextId, meta.id]
// Cache the callbacks in renderer.
if (rendererFunctions.has(objectId)) {
return rendererFunctions.get(objectId)
}
const callIntoRenderer = function (...args) {
let succeed = false
if (!sender.isDestroyed()) {
succeed = sender._sendToFrameInternal(frameId, 'ELECTRON_RENDERER_CALLBACK', contextId, meta.id, valueToMeta(sender, contextId, args))
}
if (!succeed) {
removeRemoteListenersAndLogWarning(this, callIntoRenderer)
}
}
v8Util.setHiddenValue(callIntoRenderer, 'location', meta.location)
Object.defineProperty(callIntoRenderer, 'length', { value: meta.length })
v8Util.setRemoteCallbackFreer(callIntoRenderer, contextId, meta.id, sender)
rendererFunctions.set(objectId, callIntoRenderer)
return callIntoRenderer
}
default:
throw new TypeError(`Unknown type: ${meta.type}`)
}
}
return args.map(metaToValue)
}
const isRemoteModuleEnabledImpl = function (contents) {
const webPreferences = contents.getLastWebPreferences() || {}
return !!webPreferences.enableRemoteModule
}
const isRemoteModuleEnabledCache = new WeakMap()
const isRemoteModuleEnabled = function (contents) {
if (!isRemoteModuleEnabledCache.has(contents)) {
isRemoteModuleEnabledCache.set(contents, isRemoteModuleEnabledImpl(contents))
}
return isRemoteModuleEnabledCache.get(contents)
}
const handleRemoteCommand = function (channel, handler) {
ipcMainInternal.on(channel, (event, contextId, ...args) => {
let returnValue
if (!isRemoteModuleEnabled(event.sender)) {
event.returnValue = null
return
}
try {
returnValue = handler(event, contextId, ...args)
} catch (error) {
returnValue = exceptionToMeta(error)
}
if (returnValue !== undefined) {
event.returnValue = returnValue
}
})
}
const emitCustomEvent = function (contents, eventName, ...args) {
const event = eventBinding.createWithSender(contents)
electron.app.emit(eventName, event, contents, ...args)
contents.emit(eventName, event, ...args)
return event
}
handleRemoteCommand('ELECTRON_BROWSER_WRONG_CONTEXT_ERROR', function (event, contextId, passedContextId, id) {
const objectId = [passedContextId, id]
if (!rendererFunctions.has(objectId)) {
// Do nothing if the error has already been reported before.
return
}
removeRemoteListenersAndLogWarning(event.sender, rendererFunctions.get(objectId))
})
handleRemoteCommand('ELECTRON_BROWSER_REQUIRE', function (event, contextId, moduleName) {
const customEvent = emitCustomEvent(event.sender, 'remote-require', moduleName)
if (customEvent.returnValue === undefined) {
if (customEvent.defaultPrevented) {
throw new Error(`Blocked remote.require('${moduleName}')`)
} else {
customEvent.returnValue = process.mainModule.require(moduleName)
}
}
return valueToMeta(event.sender, contextId, customEvent.returnValue)
})
handleRemoteCommand('ELECTRON_BROWSER_GET_BUILTIN', function (event, contextId, moduleName) {
const customEvent = emitCustomEvent(event.sender, 'remote-get-builtin', moduleName)
if (customEvent.returnValue === undefined) {
if (customEvent.defaultPrevented) {
throw new Error(`Blocked remote.getBuiltin('${moduleName}')`)
} else {
customEvent.returnValue = electron[moduleName]
}
}
return valueToMeta(event.sender, contextId, customEvent.returnValue)
})
handleRemoteCommand('ELECTRON_BROWSER_GLOBAL', function (event, contextId, globalName) {
const customEvent = emitCustomEvent(event.sender, 'remote-get-global', globalName)
if (customEvent.returnValue === undefined) {
if (customEvent.defaultPrevented) {
throw new Error(`Blocked remote.getGlobal('${globalName}')`)
} else {
customEvent.returnValue = global[globalName]
}
}
return valueToMeta(event.sender, contextId, customEvent.returnValue)
})
handleRemoteCommand('ELECTRON_BROWSER_CURRENT_WINDOW', function (event, contextId) {
const customEvent = emitCustomEvent(event.sender, 'remote-get-current-window')
if (customEvent.returnValue === undefined) {
if (customEvent.defaultPrevented) {
throw new Error('Blocked remote.getCurrentWindow()')
} else {
customEvent.returnValue = event.sender.getOwnerBrowserWindow()
}
}
return valueToMeta(event.sender, contextId, customEvent.returnValue)
})
handleRemoteCommand('ELECTRON_BROWSER_CURRENT_WEB_CONTENTS', function (event, contextId) {
const customEvent = emitCustomEvent(event.sender, 'remote-get-current-web-contents')
if (customEvent.returnValue === undefined) {
if (customEvent.defaultPrevented) {
throw new Error('Blocked remote.getCurrentWebContents()')
} else {
customEvent.returnValue = event.sender
}
}
return valueToMeta(event.sender, contextId, customEvent.returnValue)
})
handleRemoteCommand('ELECTRON_BROWSER_CONSTRUCTOR', function (event, contextId, id, args) {
args = unwrapArgs(event.sender, event.frameId, contextId, args)
const constructor = objectsRegistry.get(id)
if (constructor == null) {
throwRPCError(`Cannot call constructor on missing remote object ${id}`)
}
return valueToMeta(event.sender, contextId, new constructor(...args))
})
handleRemoteCommand('ELECTRON_BROWSER_FUNCTION_CALL', function (event, contextId, id, args) {
args = unwrapArgs(event.sender, event.frameId, contextId, args)
const func = objectsRegistry.get(id)
if (func == null) {
throwRPCError(`Cannot call function on missing remote object ${id}`)
}
try {
return valueToMeta(event.sender, contextId, func(...args), true)
} catch (error) {
const err = new Error(`Could not call remote function '${func.name || 'anonymous'}'. Check that the function signature is correct. Underlying error: ${error.message}\nUnderlying stack: ${error.stack}\n`)
err.cause = error
throw err
}
})
handleRemoteCommand('ELECTRON_BROWSER_MEMBER_CONSTRUCTOR', function (event, contextId, id, method, args) {
args = unwrapArgs(event.sender, event.frameId, contextId, args)
const object = objectsRegistry.get(id)
if (object == null) {
throwRPCError(`Cannot call constructor '${method}' on missing remote object ${id}`)
}
return valueToMeta(event.sender, contextId, new object[method](...args))
})
handleRemoteCommand('ELECTRON_BROWSER_MEMBER_CALL', function (event, contextId, id, method, args) {
args = unwrapArgs(event.sender, event.frameId, contextId, args)
const object = objectsRegistry.get(id)
if (object == null) {
throwRPCError(`Cannot call method '${method}' on missing remote object ${id}`)
}
try {
return valueToMeta(event.sender, contextId, object[method](...args), true)
} catch (error) {
const err = new Error(`Could not call remote method '${method}'. Check that the method signature is correct. Underlying error: ${error.message}\nUnderlying stack: ${error.stack}\n`)
err.cause = error
throw err
}
})
handleRemoteCommand('ELECTRON_BROWSER_MEMBER_SET', function (event, contextId, id, name, args) {
args = unwrapArgs(event.sender, event.frameId, contextId, args)
const obj = objectsRegistry.get(id)
if (obj == null) {
throwRPCError(`Cannot set property '${name}' on missing remote object ${id}`)
}
obj[name] = args[0]
return null
})
handleRemoteCommand('ELECTRON_BROWSER_MEMBER_GET', function (event, contextId, id, name) {
const obj = objectsRegistry.get(id)
if (obj == null) {
throwRPCError(`Cannot get property '${name}' on missing remote object ${id}`)
}
return valueToMeta(event.sender, contextId, obj[name])
})
handleRemoteCommand('ELECTRON_BROWSER_DEREFERENCE', function (event, contextId, id, rendererSideRefCount) {
objectsRegistry.remove(event.sender, contextId, id, rendererSideRefCount)
})
handleRemoteCommand('ELECTRON_BROWSER_CONTEXT_RELEASE', (event, contextId) => {
objectsRegistry.clear(event.sender, contextId)
return null
})
handleRemoteCommand('ELECTRON_BROWSER_GUEST_WEB_CONTENTS', function (event, contextId, guestInstanceId) {
const guest = guestViewManager.getGuestForWebContents(guestInstanceId, event.sender)
const customEvent = emitCustomEvent(event.sender, 'remote-get-guest-web-contents', guest)
if (customEvent.returnValue === undefined) {
if (customEvent.defaultPrevented) {
throw new Error(`Blocked remote.getGuestForWebContents()`)
} else {
customEvent.returnValue = guest
}
}
return valueToMeta(event.sender, contextId, customEvent.returnValue)
})
module.exports = {
isRemoteModuleEnabled
}

View File

@@ -1,18 +1,276 @@
'use strict'
const electron = require('electron')
const { EventEmitter } = require('events')
const fs = require('fs')
const v8Util = process.electronBinding('v8_util')
const eventBinding = process.electronBinding('event')
const clipboard = process.electronBinding('clipboard')
const features = process.electronBinding('features')
const { getContentScripts } = require('@electron/internal/browser/chrome-extension')
const { crashReporterInit } = require('@electron/internal/browser/crash-reporter-init')
const { ipcMainInternal } = require('@electron/internal/browser/ipc-main-internal')
const ipcMainUtils = require('@electron/internal/browser/ipc-main-internal-utils')
const objectsRegistry = require('@electron/internal/browser/objects-registry')
const guestViewManager = require('@electron/internal/browser/guest-view-manager')
const bufferUtils = require('@electron/internal/common/buffer-utils')
const errorUtils = require('@electron/internal/common/error-utils')
const clipboardUtils = require('@electron/internal/common/clipboard-utils')
const { isPromise } = require('@electron/internal/common/is-promise')
const hasProp = {}.hasOwnProperty
// The internal properties of Function.
const FUNCTION_PROPERTIES = [
'length', 'name', 'arguments', 'caller', 'prototype'
]
// The remote functions in renderer processes.
// id => Function
const rendererFunctions = v8Util.createDoubleIDWeakMap()
// Return the description of object's members:
const getObjectMembers = function (object) {
let names = Object.getOwnPropertyNames(object)
// For Function, we should not override following properties even though they
// are "own" properties.
if (typeof object === 'function') {
names = names.filter((name) => {
return !FUNCTION_PROPERTIES.includes(name)
})
}
// Map properties to descriptors.
return names.map((name) => {
const descriptor = Object.getOwnPropertyDescriptor(object, name)
const member = { name, enumerable: descriptor.enumerable, writable: false }
if (descriptor.get === undefined && typeof object[name] === 'function') {
member.type = 'method'
} else {
if (descriptor.set || descriptor.writable) member.writable = true
member.type = 'get'
}
return member
})
}
// Return the description of object's prototype.
const getObjectPrototype = function (object) {
const proto = Object.getPrototypeOf(object)
if (proto === null || proto === Object.prototype) return null
return {
members: getObjectMembers(proto),
proto: getObjectPrototype(proto)
}
}
// Convert a real value into meta data.
const valueToMeta = function (sender, contextId, value, optimizeSimpleObject = false) {
// Determine the type of value.
const meta = { type: typeof value }
if (meta.type === 'object') {
// Recognize certain types of objects.
if (value === null) {
meta.type = 'value'
} else if (bufferUtils.isBuffer(value)) {
meta.type = 'buffer'
} else if (Array.isArray(value)) {
meta.type = 'array'
} else if (value instanceof Error) {
meta.type = 'error'
} else if (value instanceof Date) {
meta.type = 'date'
} else if (isPromise(value)) {
meta.type = 'promise'
} else if (hasProp.call(value, 'callee') && value.length != null) {
// Treat the arguments object as array.
meta.type = 'array'
} else if (optimizeSimpleObject && v8Util.getHiddenValue(value, 'simple')) {
// Treat simple objects as value.
meta.type = 'value'
}
}
// Fill the meta object according to value's type.
if (meta.type === 'array') {
meta.members = value.map((el) => valueToMeta(sender, contextId, el, optimizeSimpleObject))
} else if (meta.type === 'object' || meta.type === 'function') {
meta.name = value.constructor ? value.constructor.name : ''
// Reference the original value if it's an object, because when it's
// passed to renderer we would assume the renderer keeps a reference of
// it.
meta.id = objectsRegistry.add(sender, contextId, value)
meta.members = getObjectMembers(value)
meta.proto = getObjectPrototype(value)
} else if (meta.type === 'buffer') {
meta.value = bufferUtils.bufferToMeta(value)
} else if (meta.type === 'promise') {
// Add default handler to prevent unhandled rejections in main process
// Instead they should appear in the renderer process
value.then(function () {}, function () {})
meta.then = valueToMeta(sender, contextId, function (onFulfilled, onRejected) {
value.then(onFulfilled, onRejected)
})
} else if (meta.type === 'error') {
meta.members = plainObjectToMeta(value)
// Error.name is not part of own properties.
meta.members.push({
name: 'name',
value: value.name
})
} else if (meta.type === 'date') {
meta.value = value.getTime()
} else {
meta.type = 'value'
meta.value = value
}
return meta
}
// Convert object to meta by value.
const plainObjectToMeta = function (obj) {
return Object.getOwnPropertyNames(obj).map(function (name) {
return {
name: name,
value: obj[name]
}
})
}
// Convert Error into meta data.
const exceptionToMeta = function (error) {
return {
type: 'exception',
value: errorUtils.serialize(error)
}
}
const throwRPCError = function (message) {
const error = new Error(message)
error.code = 'EBADRPC'
error.errno = -72
throw error
}
const removeRemoteListenersAndLogWarning = (sender, callIntoRenderer) => {
const location = v8Util.getHiddenValue(callIntoRenderer, 'location')
let message = `Attempting to call a function in a renderer window that has been closed or released.` +
`\nFunction provided here: ${location}`
if (sender instanceof EventEmitter) {
const remoteEvents = sender.eventNames().filter((eventName) => {
return sender.listeners(eventName).includes(callIntoRenderer)
})
if (remoteEvents.length > 0) {
message += `\nRemote event names: ${remoteEvents.join(', ')}`
remoteEvents.forEach((eventName) => {
sender.removeListener(eventName, callIntoRenderer)
})
}
}
console.warn(message)
}
// Convert array of meta data from renderer into array of real values.
const unwrapArgs = function (sender, frameId, contextId, args) {
const metaToValue = function (meta) {
switch (meta.type) {
case 'value':
return meta.value
case 'remote-object':
return objectsRegistry.get(meta.id)
case 'array':
return unwrapArgs(sender, frameId, contextId, meta.value)
case 'buffer':
return bufferUtils.metaToBuffer(meta.value)
case 'date':
return new Date(meta.value)
case 'promise':
return Promise.resolve({
then: metaToValue(meta.then)
})
case 'object': {
const ret = {}
Object.defineProperty(ret.constructor, 'name', { value: meta.name })
for (const { name, value } of meta.members) {
ret[name] = metaToValue(value)
}
return ret
}
case 'function-with-return-value':
const returnValue = metaToValue(meta.value)
return function () {
return returnValue
}
case 'function': {
// Merge contextId and meta.id, since meta.id can be the same in
// different webContents.
const objectId = [contextId, meta.id]
// Cache the callbacks in renderer.
if (rendererFunctions.has(objectId)) {
return rendererFunctions.get(objectId)
}
const callIntoRenderer = function (...args) {
let succeed = false
if (!sender.isDestroyed()) {
succeed = sender._sendToFrameInternal(frameId, 'ELECTRON_RENDERER_CALLBACK', contextId, meta.id, valueToMeta(sender, contextId, args))
}
if (!succeed) {
removeRemoteListenersAndLogWarning(this, callIntoRenderer)
}
}
v8Util.setHiddenValue(callIntoRenderer, 'location', meta.location)
Object.defineProperty(callIntoRenderer, 'length', { value: meta.length })
v8Util.setRemoteCallbackFreer(callIntoRenderer, frameId, contextId, meta.id, sender)
rendererFunctions.set(objectId, callIntoRenderer)
return callIntoRenderer
}
default:
throw new TypeError(`Unknown type: ${meta.type}`)
}
}
return args.map(metaToValue)
}
const isRemoteModuleEnabledCache = new WeakMap()
const isRemoteModuleEnabled = function (contents) {
if (!isRemoteModuleEnabledCache.has(contents)) {
isRemoteModuleEnabledCache.set(contents, contents._isRemoteModuleEnabled())
}
return isRemoteModuleEnabledCache.get(contents)
}
const handleRemoteCommand = function (channel, handler) {
ipcMainInternal.on(channel, (event, contextId, ...args) => {
let returnValue
if (!isRemoteModuleEnabled(event.sender)) {
event.returnValue = null
return
}
try {
returnValue = handler(event, contextId, ...args)
} catch (error) {
returnValue = exceptionToMeta(error)
}
if (returnValue !== undefined) {
event.returnValue = returnValue
}
})
}
const emitCustomEvent = function (contents, eventName, ...args) {
const event = eventBinding.createWithSender(contents)
@@ -23,6 +281,187 @@ const emitCustomEvent = function (contents, eventName, ...args) {
return event
}
handleRemoteCommand('ELECTRON_BROWSER_WRONG_CONTEXT_ERROR', function (event, contextId, passedContextId, id) {
const objectId = [passedContextId, id]
if (!rendererFunctions.has(objectId)) {
// Do nothing if the error has already been reported before.
return
}
removeRemoteListenersAndLogWarning(event.sender, rendererFunctions.get(objectId))
})
handleRemoteCommand('ELECTRON_BROWSER_REQUIRE', function (event, contextId, moduleName) {
const customEvent = emitCustomEvent(event.sender, 'remote-require', moduleName)
if (customEvent.returnValue === undefined) {
if (customEvent.defaultPrevented) {
throw new Error(`Blocked remote.require('${moduleName}')`)
} else {
customEvent.returnValue = process.mainModule.require(moduleName)
}
}
return valueToMeta(event.sender, contextId, customEvent.returnValue)
})
handleRemoteCommand('ELECTRON_BROWSER_GET_BUILTIN', function (event, contextId, moduleName) {
const customEvent = emitCustomEvent(event.sender, 'remote-get-builtin', moduleName)
if (customEvent.returnValue === undefined) {
if (customEvent.defaultPrevented) {
throw new Error(`Blocked remote.getBuiltin('${moduleName}')`)
} else {
customEvent.returnValue = electron[moduleName]
}
}
return valueToMeta(event.sender, contextId, customEvent.returnValue)
})
handleRemoteCommand('ELECTRON_BROWSER_GLOBAL', function (event, contextId, globalName) {
const customEvent = emitCustomEvent(event.sender, 'remote-get-global', globalName)
if (customEvent.returnValue === undefined) {
if (customEvent.defaultPrevented) {
throw new Error(`Blocked remote.getGlobal('${globalName}')`)
} else {
customEvent.returnValue = global[globalName]
}
}
return valueToMeta(event.sender, contextId, customEvent.returnValue)
})
handleRemoteCommand('ELECTRON_BROWSER_CURRENT_WINDOW', function (event, contextId) {
const customEvent = emitCustomEvent(event.sender, 'remote-get-current-window')
if (customEvent.returnValue === undefined) {
if (customEvent.defaultPrevented) {
throw new Error('Blocked remote.getCurrentWindow()')
} else {
customEvent.returnValue = event.sender.getOwnerBrowserWindow()
}
}
return valueToMeta(event.sender, contextId, customEvent.returnValue)
})
handleRemoteCommand('ELECTRON_BROWSER_CURRENT_WEB_CONTENTS', function (event, contextId) {
const customEvent = emitCustomEvent(event.sender, 'remote-get-current-web-contents')
if (customEvent.returnValue === undefined) {
if (customEvent.defaultPrevented) {
throw new Error('Blocked remote.getCurrentWebContents()')
} else {
customEvent.returnValue = event.sender
}
}
return valueToMeta(event.sender, contextId, customEvent.returnValue)
})
handleRemoteCommand('ELECTRON_BROWSER_CONSTRUCTOR', function (event, contextId, id, args) {
args = unwrapArgs(event.sender, event.frameId, contextId, args)
const constructor = objectsRegistry.get(id)
if (constructor == null) {
throwRPCError(`Cannot call constructor on missing remote object ${id}`)
}
return valueToMeta(event.sender, contextId, new constructor(...args))
})
handleRemoteCommand('ELECTRON_BROWSER_FUNCTION_CALL', function (event, contextId, id, args) {
args = unwrapArgs(event.sender, event.frameId, contextId, args)
const func = objectsRegistry.get(id)
if (func == null) {
throwRPCError(`Cannot call function on missing remote object ${id}`)
}
try {
return valueToMeta(event.sender, contextId, func(...args), true)
} catch (error) {
const err = new Error(`Could not call remote function '${func.name || 'anonymous'}'. Check that the function signature is correct. Underlying error: ${error.message}\nUnderlying stack: ${error.stack}\n`)
err.cause = error
throw err
}
})
handleRemoteCommand('ELECTRON_BROWSER_MEMBER_CONSTRUCTOR', function (event, contextId, id, method, args) {
args = unwrapArgs(event.sender, event.frameId, contextId, args)
const object = objectsRegistry.get(id)
if (object == null) {
throwRPCError(`Cannot call constructor '${method}' on missing remote object ${id}`)
}
return valueToMeta(event.sender, contextId, new object[method](...args))
})
handleRemoteCommand('ELECTRON_BROWSER_MEMBER_CALL', function (event, contextId, id, method, args) {
args = unwrapArgs(event.sender, event.frameId, contextId, args)
const object = objectsRegistry.get(id)
if (object == null) {
throwRPCError(`Cannot call method '${method}' on missing remote object ${id}`)
}
try {
return valueToMeta(event.sender, contextId, object[method](...args), true)
} catch (error) {
const err = new Error(`Could not call remote method '${method}'. Check that the method signature is correct. Underlying error: ${error.message}\nUnderlying stack: ${error.stack}\n`)
err.cause = error
throw err
}
})
handleRemoteCommand('ELECTRON_BROWSER_MEMBER_SET', function (event, contextId, id, name, args) {
args = unwrapArgs(event.sender, event.frameId, contextId, args)
const obj = objectsRegistry.get(id)
if (obj == null) {
throwRPCError(`Cannot set property '${name}' on missing remote object ${id}`)
}
obj[name] = args[0]
return null
})
handleRemoteCommand('ELECTRON_BROWSER_MEMBER_GET', function (event, contextId, id, name) {
const obj = objectsRegistry.get(id)
if (obj == null) {
throwRPCError(`Cannot get property '${name}' on missing remote object ${id}`)
}
return valueToMeta(event.sender, contextId, obj[name])
})
handleRemoteCommand('ELECTRON_BROWSER_DEREFERENCE', function (event, contextId, id, rendererSideRefCount) {
objectsRegistry.remove(event.sender, contextId, id, rendererSideRefCount)
})
handleRemoteCommand('ELECTRON_BROWSER_CONTEXT_RELEASE', (event, contextId) => {
objectsRegistry.clear(event.sender, contextId)
})
handleRemoteCommand('ELECTRON_BROWSER_GUEST_WEB_CONTENTS', function (event, contextId, guestInstanceId) {
const guest = guestViewManager.getGuestForWebContents(guestInstanceId, event.sender)
const customEvent = emitCustomEvent(event.sender, 'remote-get-guest-web-contents', guest)
if (customEvent.returnValue === undefined) {
if (customEvent.defaultPrevented) {
throw new Error(`Blocked remote.getGuestForWebContents()`)
} else {
customEvent.returnValue = guest
}
}
return valueToMeta(event.sender, contextId, customEvent.returnValue)
})
// Implements window.close()
ipcMainInternal.on('ELECTRON_BROWSER_WINDOW_CLOSE', function (event) {
const window = event.sender.getOwnerBrowserWindow()
@@ -32,11 +471,11 @@ ipcMainInternal.on('ELECTRON_BROWSER_WINDOW_CLOSE', function (event) {
event.returnValue = null
})
ipcMainUtils.handleSync('ELECTRON_CRASH_REPORTER_INIT', function (event, options) {
ipcMainUtils.handle('ELECTRON_CRASH_REPORTER_INIT', function (event, options) {
return crashReporterInit(options)
})
ipcMainInternal.handle('ELECTRON_BROWSER_GET_LAST_WEB_PREFERENCES', function (event) {
ipcMainUtils.handle('ELECTRON_BROWSER_GET_LAST_WEB_PREFERENCES', function (event) {
return event.sender.getLastWebPreferences()
})
@@ -52,7 +491,7 @@ const allowedClipboardMethods = (() => {
}
})()
ipcMainUtils.handleSync('ELECTRON_BROWSER_CLIPBOARD', function (event, method, ...args) {
ipcMainUtils.handle('ELECTRON_BROWSER_CLIPBOARD', function (event, method, ...args) {
if (!allowedClipboardMethods.has(method)) {
throw new Error(`Invalid method: ${method}`)
}
@@ -63,7 +502,7 @@ ipcMainUtils.handleSync('ELECTRON_BROWSER_CLIPBOARD', function (event, method, .
if (features.isDesktopCapturerEnabled()) {
const desktopCapturer = require('@electron/internal/browser/desktop-capturer')
ipcMainInternal.handle('ELECTRON_BROWSER_DESKTOP_CAPTURER_GET_SOURCES', function (event, ...args) {
ipcMainUtils.handle('ELECTRON_BROWSER_DESKTOP_CAPTURER_GET_SOURCES', function (event, ...args) {
const customEvent = emitCustomEvent(event.sender, 'desktop-capturer-get-sources')
if (customEvent.defaultPrevented) {
@@ -75,10 +514,6 @@ if (features.isDesktopCapturerEnabled()) {
})
}
const isRemoteModuleEnabled = features.isRemoteModuleEnabled()
? require('@electron/internal/browser/remote/server').isRemoteModuleEnabled
: () => false
const getPreloadScript = async function (preloadPath) {
let preloadSrc = null
let preloadError = null
@@ -90,24 +525,13 @@ const getPreloadScript = async function (preloadPath) {
return { preloadPath, preloadSrc, preloadError }
}
if (features.isExtensionsEnabled()) {
ipcMainUtils.handleSync('ELECTRON_GET_CONTENT_SCRIPTS', () => [])
} else {
const { getContentScripts } = require('@electron/internal/browser/chrome-extension')
ipcMainUtils.handleSync('ELECTRON_GET_CONTENT_SCRIPTS', () => getContentScripts())
}
ipcMainUtils.handle('ELECTRON_GET_CONTENT_SCRIPTS', () => getContentScripts())
ipcMainUtils.handleSync('ELECTRON_BROWSER_SANDBOX_LOAD', async function (event) {
ipcMainUtils.handle('ELECTRON_BROWSER_SANDBOX_LOAD', async function (event) {
const preloadPaths = event.sender._getPreloadPaths()
let contentScripts = []
if (!features.isExtensionsEnabled()) {
const { getContentScripts } = require('@electron/internal/browser/chrome-extension')
contentScripts = getContentScripts()
}
return {
contentScripts,
contentScripts: getContentScripts(),
preloadScripts: await Promise.all(preloadPaths.map(path => getPreloadScript(path))),
isRemoteModuleEnabled: isRemoteModuleEnabled(event.sender),
isWebViewTagEnabled: guestViewManager.isWebViewTagEnabled(event.sender),

View File

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

View File

@@ -1,5 +1,7 @@
'use strict'
// Common modules, please sort alphabetically
export const commonModuleList: ElectronInternal.ModuleEntry[] = [
module.exports = [
{ name: 'clipboard', loader: () => require('./clipboard') },
{ name: 'nativeImage', loader: () => require('./native-image') },
{ name: 'shell', loader: () => require('./shell') },

View File

@@ -8,6 +8,8 @@
const path = require('path')
const util = require('util')
const Promise = global.Promise
const envNoAsar = process.env.ELECTRON_NO_ASAR &&
process.type !== 'browser' &&
process.type !== 'renderer'
@@ -40,8 +42,6 @@
return newArchive
}
const ASAR_EXTENSION = '.asar'
// Separate asar package's path from full path.
const splitPath = archivePathOrBuffer => {
// Shortcut for disabled asar.
@@ -54,22 +54,7 @@
}
if (typeof archivePath !== 'string') return { isAsar: false }
if (archivePath.endsWith(ASAR_EXTENSION)) {
return { isAsar: true, asarPath: archivePath, filePath: '' }
}
archivePath = path.normalize(archivePath)
const index = archivePath.lastIndexOf(`${ASAR_EXTENSION}${path.sep}`)
if (index === -1) return { isAsar: false }
// E.g. for "//some/path/to/archive.asar/then/internal.file"...
return {
isAsar: true,
// "//some/path/to/archive.asar"
asarPath: archivePath.substr(0, index + ASAR_EXTENSION.length),
// "then/internal.file" (with a path separator excluded)
filePath: archivePath.substr(index + ASAR_EXTENSION.length + 1)
}
return asar.splitPath(path.normalize(archivePath))
}
// Convert asar archive's Stats object to fs's Stats object.

View File

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

View File

@@ -0,0 +1,8 @@
// Captures original globals into a scope to ensure that userland modifications do
// not impact Electron. Note that users doing:
//
// global.Promise.resolve = myFn
//
// Will mutate this captured one as well and that is OK.
export const Promise = global.Promise

View File

@@ -0,0 +1,20 @@
const { hasSwitch } = process.electronBinding('command_line')
const binding = process.electronBinding('context_bridge')
const contextIsolationEnabled = hasSwitch('context-isolation')
const checkContextIsolationEnabled = () => {
if (!contextIsolationEnabled) throw new Error('contextBridge API can only be used when contextIsolation is enabled')
}
const contextBridge = {
exposeInMainWorld: (key: string, api: Record<string, any>) => {
checkContextIsolationEnabled()
return binding.exposeAPIInMainWorld(key, api)
},
debugGC: () => binding._debugGCMaps({})
}
if (!binding._debugGCMaps) delete contextBridge.debugGC
export default contextBridge

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,19 +0,0 @@
const features = process.electronBinding('features')
const v8Util = process.electronBinding('v8_util')
const enableRemoteModule = v8Util.getHiddenValue<boolean>(global, 'enableRemoteModule')
// Renderer side modules, please sort alphabetically.
export const rendererModuleList: ElectronInternal.ModuleEntry[] = [
{ name: 'crashReporter', loader: () => require('./crash-reporter') },
{ name: 'ipcRenderer', loader: () => require('./ipc-renderer') },
{ name: 'webFrame', loader: () => require('./web-frame') }
]
if (features.isDesktopCapturerEnabled()) {
rendererModuleList.push({ name: 'desktopCapturer', loader: () => require('./desktop-capturer') })
}
if (features.isRemoteModuleEnabled() && enableRemoteModule) {
rendererModuleList.push({ name: 'remote', loader: () => require('./remote') })
}

View File

@@ -2,10 +2,10 @@
const v8Util = process.electronBinding('v8_util')
const { CallbacksRegistry } = require('@electron/internal/renderer/remote/callbacks-registry')
const bufferUtils = require('@electron/internal/common/remote/buffer-utils')
const { CallbacksRegistry } = require('@electron/internal/renderer/callbacks-registry')
const bufferUtils = require('@electron/internal/common/buffer-utils')
const errorUtils = require('@electron/internal/common/error-utils')
const { isPromise } = require('@electron/internal/common/remote/is-promise')
const { isPromise } = require('@electron/internal/common/is-promise')
const { ipcRendererInternal } = require('@electron/internal/renderer/ipc-renderer-internal')
const callbacksRegistry = new CallbacksRegistry()
@@ -20,7 +20,7 @@ const contextId = v8Util.getHiddenValue(global, 'contextId')
// to guard that situation.
process.on('exit', () => {
const command = 'ELECTRON_BROWSER_CONTEXT_RELEASE'
ipcRendererInternal.sendSync(command, contextId)
ipcRendererInternal.send(command, contextId)
})
// Convert the arguments object into an array of meta data.
@@ -349,8 +349,9 @@ const addBuiltinProperty = (name) => {
})
}
const { commonModuleList } = require('@electron/internal/common/api/module-list')
const browserModules = commonModuleList.concat(require('@electron/internal/browser/api/module-keys'))
const browserModules =
require('@electron/internal/common/api/module-list').concat(
require('@electron/internal/browser/api/module-keys'))
// And add a helper receiver for each one.
browserModules

View File

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

View File

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

View File

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

View File

@@ -100,9 +100,7 @@ switch (window.location.protocol) {
}
case 'chrome-extension:': {
// Inject the chrome.* APIs that chrome extensions require
if (!process.electronBinding('features').isExtensionsEnabled()) {
require('@electron/internal/renderer/chrome-api').injectTo(window.location.hostname, window)
}
require('@electron/internal/renderer/chrome-api').injectTo(window.location.hostname, window)
break
}
case 'chrome:':
@@ -113,10 +111,8 @@ switch (window.location.protocol) {
windowSetup(guestInstanceId, openerId, isHiddenPage, usesNativeWindowOpen)
// Inject content scripts.
if (!process.electronBinding('features').isExtensionsEnabled()) {
const contentScripts = ipcRendererUtils.invokeSync('ELECTRON_GET_CONTENT_SCRIPTS') as Electron.ContentScriptEntry[]
require('@electron/internal/renderer/content-scripts-injector')(contentScripts)
}
const contentScripts = ipcRendererUtils.invokeSync('ELECTRON_GET_CONTENT_SCRIPTS') as Electron.ContentScriptEntry[]
require('@electron/internal/renderer/content-scripts-injector')(contentScripts)
}
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,11 +1,9 @@
import * as electron from 'electron'
import { remote, webFrame } from 'electron'
import { ipcRendererInternal } from '@electron/internal/renderer/ipc-renderer-internal'
import * as ipcRendererUtils from '@electron/internal/renderer/ipc-renderer-internal-utils'
import * as guestViewInternal from '@electron/internal/renderer/web-view/guest-view-internal'
import { WEB_VIEW_CONSTANTS } from '@electron/internal/renderer/web-view/web-view-constants'
import { syncMethods, asyncMethods } from '@electron/internal/common/web-view-methods'
const { webFrame } = electron
const v8Util = process.electronBinding('v8_util')
@@ -226,7 +224,6 @@ export const setupMethods = (WebViewElement: typeof ElectronInternal.WebViewElem
// WebContents associated with this webview.
WebViewElement.prototype.getWebContents = function () {
const remote = electron.remote as Electron.RemoteInternal
if (!remote) {
throw new Error('getGuestWebContents requires remote, which is not enabled')
}
@@ -235,7 +232,7 @@ export const setupMethods = (WebViewElement: typeof ElectronInternal.WebViewElem
internal.createGuestSync()
}
return remote.getGuestWebContents(internal.guestInstanceId!)
return (remote as Electron.RemoteInternal).getGuestWebContents(internal.guestInstanceId!)
}
// Focusing the webview should move page focus to the underlying iframe.
@@ -256,7 +253,7 @@ export const setupMethods = (WebViewElement: typeof ElectronInternal.WebViewElem
const createNonBlockHandler = function (method: string) {
return function (this: ElectronInternal.WebViewElement, ...args: Array<any>) {
return ipcRendererInternal.invoke('ELECTRON_GUEST_VIEW_MANAGER_CALL', this.getWebContentsId(), method, args)
return ipcRendererUtils.invoke('ELECTRON_GUEST_VIEW_MANAGER_CALL', this.getWebContentsId(), method, args)
}
}

View File

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

View File

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

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