Compare commits

..

181 Commits

Author SHA1 Message Date
Electron Bot
614079654c Bump v8.0.0-nightly.20190902 2019-09-02 08:34:32 -07:00
Electron Bot
51015c5b48 Bump v8.0.0-nightly.20190901 2019-09-01 08:31:00 -07:00
Samuel Attard
c621a36320 fix: ensure that the "top" coordinate of the inner frame is correct (#20051)
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 15:45:59 -07:00
ipoint-pgerhard
e37ad09330 docs: Update boilerplates-and-clis.md (#19975)
Updated boilerplates-and-clis.md in order to more accuratly represent the current availability of templates in electron forge
2019-08-30 15:40:37 -05:00
Shelley Vohr
bfe256891c build: add gn-check to precommit linting (#19850) 2019-08-30 10:37:02 -07:00
Dave Jeffery
0f5ff1f5bb docs: clarify app.setName() effects (#19893)
* Document that `app.setName()` has no effect in Mac environments

* docs: add note to clarify `app.setName()` functionality

* Update app.md
2019-08-30 10:30:38 -07:00
Electron Bot
e96a042223 Bump v8.0.0-nightly.20190830 2019-08-30 08:32:04 -07:00
Shelley Vohr
5cbbd489d5 fix: honor cursor blink rate (#20020)
* 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 09:39:46 -05:00
Jeremy Apthorp
805a55099b test: tsify more web contents specs (#19969)
* test: tsify more WebContents specs

* getFocusedWebContents

* setDevToolsWebContents, isFocused, isCurrentlyAudible

* getWebPreferences, openDevTools

* before-input-event

* zoom-changed

* sendInputEvent

* insertCSS

* startDrag

* focus, getOSProcessId

* zoom api

* more closeAllWindows

* fix detached dev tools test

* fix zoom-changed test

* compare the correct kind of id 🤦‍♂️

* 'fix' openDevTools test to wait for multiple focus events

* fix tests? 🤞

* use request instead of blur to detect openExternal success

* try not timing out the keychain for testing

* use blur event on mac, sigh

* oh, right, still gotta open an actual url
2019-08-29 19:45:41 -05:00
Samuel Attard
654338693f fix: Revert "fix: make sure that menu bar gets focus even when you click an item to focus it first (#19710)" (#20019)
This reverts commit 27b2747b61.
2019-08-29 15:06:39 -07:00
Shelley Vohr
a9e3dabc8a build: accidentally inverted a bool (#20029) 2019-08-29 11:11:10 -07:00
Jeremy Apthorp
609403fba6 test: tsify affinity spec (#19961) 2019-08-29 09:59:27 -07:00
Electron Bot
6b55584923 Bump v8.0.0-nightly.20190829 2019-08-29 08:31:27 -07:00
Shelley Vohr
81e6f317c9 chore: improve smoke test for tray (#19991) 2019-08-29 08:07:02 -07:00
Shelley Vohr
7d4e0ad7b0 build: simplify unicode console output (#20017) 2019-08-29 10:46:54 -04:00
Tomáš Hübelbauer
35ebbb5f6e docs: add a CSP meta tag to make the tutorial compliant with the security checklist (#19819)
I've asked #19775 because I was frustrated with how hard it was to find a way to fix (instead of hide) the CSP warning in Electron and I complained that even the official quick start guide wasn't compliant with the security checklist at https://electronjs.org/docs/tutorial/security. Someone helped me out with a CSP meta tag which I have later noticed is indeed mentioned in the checklist, too: https://electronjs.org/docs/tutorial/security#csp-meta-tag. I have not used the checklist one verbatim because it prevents a `script` tag from working when serving `index.html` through the `file:` protocol as the quick start does. I instead used the one the person in my issue recommended which seems to work well to me. I am not that well versed in CSP so there might be a better policy to include with the quick start, but this is what I've got for now.
2019-08-29 17:06:51 +09:00
Jeremy Apthorp
c819fbe852 test: move WebContentsView spec (#19990) 2019-08-29 16:17:44 +09:00
Alexey Kuzmin
c03288f458 chore: add missing includes (#20003) 2019-08-29 15:57:11 +09:00
Jeremy Apthorp
90d62e5b98 fix: nws13n: make ses.setUserAgent work (#20014)
* refactor tests to better control window creation

* fix: nws13n: make ses.setUserAgent work
2019-08-29 15:50:14 +09:00
Cheng Zhao
b3947d6a83 chore: cache URLLoaderFactory per-session (#19998)
* cache the URLLoaderFactory in AtomBrowserContext

* use cached loader factory in AtomURLLoaderFactory
2019-08-29 15:07:46 +09:00
Milan Burda
eed72c35d7 feat: add session.downloadURL() (#19889) 2019-08-28 20:27:20 -07:00
Jeremy Apthorp
79e936aea8 test: fix clearAuthCache test (#20015) 2019-08-28 17:43:12 -07:00
Milan Burda
01fdb80f7c refactor: implement isRemoteModuleEnabled via getLastWebPreferences() (#19220) 2019-08-28 15:57:03 -07:00
Shelley Vohr
04debd5890 build: add test runner parameter checks (#19994) 2019-08-28 15:19:52 -07:00
Jeremy Apthorp
af138dab55 test: move webRequest spec to main runner (#19992) 2019-08-28 13:56:15 -07:00
Jeremy Apthorp
f212ed85dd test: tsify sub-frames spec (#19965) 2019-08-28 13:55:01 -07:00
Jeremy Apthorp
99de0975c3 test: tsify powerMonitor spec (#19963) 2019-08-28 13:54:50 -07:00
Jeremy Apthorp
41d8247ffc test: tsify internal-spec (#19962) 2019-08-28 13:54:42 -07:00
Charles Kerr
217ed9aabc fix: gtk_init() called 2x in AtomBrowserMainParts (#19986)
Fixes #19984.
2019-08-28 12:36:03 -05:00
Shelley Vohr
538c4763cf chore: remove unused config files (#19997) 2019-08-28 09:18:49 -07:00
Electron Bot
3bc5302d78 Bump v8.0.0-nightly.20190828 2019-08-28 08:31:11 -07:00
Charles Kerr
987300c97a refactor: omit redundant map searches (#19929)
* refactor: don't walk maps twice to remove elements

* refactor: don't walk maps twice to read elements

* refactor: don't walk maps twice to insert elements

* refactor: don't walk map 3x on UvTaskRunner timeout

* refactor: more don't-walk-maps-twice cleanup

* fixup! refactor: don't walk maps twice to insert elements

* refactor: don't walk containers twice when erasing

* refactor: omit excess lookups in RemoteObjectFreer
2019-08-28 09:39:21 -05:00
Heilig Benedek
27ce6a9cd3 fix: handle WM_GETMINMAXINFO instead of letting chromium do it (#19928)
* 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:34:34 +09:00
Jeremy Apthorp
832c926712 fix: allow unsandboxed renderers to request new privileges (#19953)
* fix: allow unsandboxed renderers to request new privileges

* add test
2019-08-27 18:35:46 -04:00
Marat Abdullin
ae9424d93a feat: add "accessibleTitle" property to a BrowserWindow instance (#19698)
Sometimes it's necessary to convey more information about the window to screen reader users only (simply putting everything to the window title might be unnecessarily noisy).

For example, Chromium uses that technique to tell screen reader users that the window is in incognito mode (the incognito window looks differently and doesn't have «incognito» in the title, but for blind users the screen reader will announce that it's incognito).
2019-08-28 00:35:34 +02:00
Jeremy Apthorp
1dcda7b809 chore: DCHECK for correct thread in EventEmitter::EmitWithSender (#19959) 2019-08-27 15:15:52 -07:00
Jeremy Apthorp
bdc84d0bfb test: tsify session spec (#19604) 2019-08-27 14:55:19 -07:00
Jeremy Apthorp
4b8e1588b4 fix: remove unused header from extensions-only file (#19947) 2019-08-27 10:59:22 -07:00
Cheng Zhao
4eee71ffbf 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 09:12:33 -07:00
Electron Bot
bdb20d53cb Bump v8.0.0-nightly.20190827 2019-08-27 08:31:13 -07:00
Charles Kerr
7e61cd0dfb fix: i18n of gtk msgbox buttons (#19904)
* 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-27 09:57:12 -05:00
Electron Bot
2542c51c48 chore: bump node in DEPS to v12.9.1 (#19980) 2019-08-27 07:51:28 -07:00
Jeremy Apthorp
92c3a4e4c2 test: tsify spec for experimental views api (#19966) 2019-08-27 16:37:30 +09:00
Samuel Attard
4e809f0048 fix: ensure that reloads retain modified window background colors (#19967) 2019-08-26 23:14:23 -07:00
Heilig Benedek
d04072d1eb fix: don't call SetBounds on restore (#19886) 2019-08-26 14:04:20 -07:00
Kuts Alexey
cddbddc543 feat: HTTP preconnect feature minimal for electronjs (#18671) 2019-08-26 09:47:32 -07:00
Electron Bot
c57db7f163 Bump v8.0.0-nightly.20190826 2019-08-26 08:32:02 -07:00
Milan Burda
94c6b256de refactor: simplify ShowSaveDialog, make consistent with ShowOpenDialog (#19924) 2019-08-26 13:12:09 +02:00
Heilig Benedek
f6c523db13 fix: adjust window size in NCCALCSIZE instead of adding insets (#19883) 2019-08-26 10:03:57 +09:00
Charles Kerr
080fdb3817 fix: command-line scheme switch values' spillover (#19912)
* 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 09:40:44 +09:00
Milan Burda
181f663cf1 refactor: use C++11 member initializers in native_mate (#19925) 2019-08-26 09:16:28 +09:00
Electron Bot
1eda92859f Bump v8.0.0-nightly.20190825 2019-08-25 08:31:03 -07:00
Electron Bot
f54bc1cb2e Bump v8.0.0-nightly.20190824 2019-08-24 08:31:28 -07:00
Electron Bot
b7d25ccb77 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
2019-08-23 18:14:23 -07:00
Shelley Vohr
c89debd19a refactor: use Error util when only throwing errors (#19837) 2019-08-23 15:49:54 -07:00
Charles Kerr
ef6d4a46c2 chore: make apply_all_patches.py work in both python2 and python3 (#19872) 2019-08-23 15:48:27 -07:00
Milan Burda
81e9dab52f refactor: replace ipcRendererUtils.invoke() with ipcRendererInternal.invoke() (#19574) 2019-08-23 15:45:50 -07:00
Shelley Vohr
698120daf0 fix: crash on input file handler dialog (#19897)
* fix: crash on input file handler dialog

* invert cancellation logic
2019-08-23 14:18:30 -07:00
Samuel Attard
c61020e9d3 build: use a lower process count for publish builds with no sccache (#19913) 2019-08-23 14:01:12 -07:00
Electron Bot
6144408f3a Bump v8.0.0-nightly.20190823 2019-08-23 08:31:55 -07:00
Milan Burda
7825d043f2 refactor: unify module-list format and exports/electron (#19697) 2019-08-23 11:18:58 +02:00
Shelley Vohr
c6a8b7f959 docs: clarify dock.bounce usage (#19894) 2019-08-23 01:16:18 -07:00
Samuel Attard
6a3922d330 refactor: make util::Promise type safe when chaining in native (#19809)
* refactor: make util::Promise type safe when chaining in native

* fixup! refactor: make util::Promise type safe when chaining in native

* chore: remove spare brackets
2019-08-22 17:03:28 -07:00
loc
f7e3e1f97a fix: mitigate white screen flash after occlusion by disabling compositor recycling (#19873)
* fix: remove white screen flicker by disabling compositor recycling

* chore: disable spec whose flakiness was made obvious by this patch
2019-08-22 15:16:06 -07:00
Cheng Zhao
ab0bf6d238 fix: notify views of content view size change (#19878) 2019-08-22 14:16:56 -07:00
Electron Bot
6667969887 chore: bump node to v12.9.0 (master) (#19863)
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2019-08-22 14:12:11 -07:00
Jaime Bernardo
12b00ca942 fix: extern Parse impl for Windows debug builds (#19876)
* 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 13:16:38 -07:00
Robert Nagy
1f43af5cea feat: add openbsd support in the node module (#19860) 2019-08-22 12:09:15 -07:00
Electron Bot
268094e0ef Bump v8.0.0-nightly.20190822 2019-08-22 08:31:04 -07:00
Heilig Benedek
9ccd6aa0dd feat: enable picture-in-picture mode for video tags (#17686)
* feat: enable picture in picture mode for video tags

* test: add test to verify picture in picture support

* lint: fix indent

* fix: clean up after rebase

* test: update test with 16:9 test video

* fix: .paches after rebase
2019-08-22 19:17:50 +09:00
John Kleinschmidt
46b6bcd99b chore: Update comment for desktop_capturer (#19848)
* chore: Update comment for desktop_capturer

* Guard TopLevelWindow::MoveAbove with ENABLE_DESKTOP_CAPTURER

* Fix lint errors
2019-08-21 15:16:43 -07:00
John Kleinschmidt
4bc7b3b1a4 build: start building Windows on Arm builds (#19780)
* build: add zip manifest for Windows on Arm

* ci: add Windows On Arm testing

(cherry picked from commit 4064e1f4874ff7a37c52c2ad974f92418c7e71c4)

* Fix path to invoke CI on WOA hardware

* Explicitly call 7z.exe to unzip files

* Make sure GCLIENT_EXTRA_ARGS set for WOA builds get prepended on release build

* set proper arch for npm

* Try using Compress-Archive/Expand-Archive

* Revert "Try using Compress-Archive/Expand-Archive"

* disable woa hardware test for now
2019-08-21 17:37:30 -04:00
Shelley Vohr
5e525b3e0f fix: add default media usage strings to info.plist (#19871) 2019-08-21 13:14:25 -07:00
Samuel Attard
612e3f7ff7 build: optimize the CI path where we update the patch files (#19851)
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-08-21 14:52:17 -04:00
Shelley Vohr
991a56135d build: dynamically calculate out dir (#19857) 2019-08-21 10:41:35 -07:00
Electron Bot
3bd829aee0 Bump v8.0.0-nightly.20190821 2019-08-21 08:31:24 -07:00
Samuel Attard
674779899e build: ninja count should be 2*cores + 2 (#19852) 2019-08-21 10:25:23 -04:00
Heilig Benedek
3f49f984e6 fix: race condition in NodeStreamLoader (#19811)
* fix: race condition in NodeStreamLoader

* nit: add comments
2019-08-21 12:23:46 +09:00
Cheng Zhao
b7defaaf6a 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
2019-08-21 11:14:21 +09:00
Samuel Attard
f10f44acf5 fix: trim branch name before comparing to master (#19853) 2019-08-20 18:10:44 -07:00
John Kleinschmidt
d258797d05 ci: add macOS debug builds (#19831)
* ci: add macOS debug builds

* Fix mac debug builds
2019-08-20 16:11:29 -04:00
Carlos
fb214a599e docs: update documentation under tutorials (#19804) 2019-08-20 09:45:25 -07:00
Electron Bot
a4c0f26f06 Bump v8.0.0-nightly.20190820 2019-08-20 08:32:09 -07:00
Erick Zhao
145b4fae94 feat: implement will-move event on macOS (#19641) 2019-08-20 07:53:43 -07:00
Cheng Zhao
cd1b15a155 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
2019-08-20 20:46:20 +09:00
Shelley Vohr
1dc02e6dbc fix: fall back to default logs path in getPath('logs') (#19653) 2019-08-19 15:16:00 -07:00
pi1024e
0851697cb7 docs: fix punctuation errors in native-image.m (#19620)
* Added correct punctuation to sentences in documentation as well as changed lets to consts to pass the docs linter

* Fixed inconsistent indentation
2019-08-19 15:15:13 -07:00
Electron Bot
bd11be98aa chore: bump node to v12.8.1 (master) (#19790)
* 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 14:15:04 -07:00
Shelley Vohr
a54d438e18 chore: upgrades-wg owns DEPS (#19830) 2019-08-19 13:56:20 -07:00
Heilig Benedek
b33558d822 refactor: mojofy autofill renderer->browser (#18760)
* re-implement renderer->browser calls with mojo

* lint

* fix: clean up after rebase

* lint

* fix: lazy load autofill drivers
2019-08-19 13:13:24 -07:00
Shelley Vohr
43e6d7fe88 chore: add error throwing utility (#19803)
* chore: add error throwing utility

* feedback from review

* DRY out repeated isolate calls
2019-08-19 09:10:18 -07:00
Electron Bot
8f1c51eaea Bump v8.0.0-nightly.20190819 2019-08-19 08:32:31 -07:00
Electron Bot
090786b037 Bump v8.0.0-nightly.20190818 2019-08-18 08:31:14 -07:00
Electron Bot
dba3927b4e Bump v8.0.0-nightly.20190817 2019-08-17 08:31:36 -07:00
Micha Hanselmann
56d10aeef7 docs: add mising return desc (#19778) 2019-08-16 09:24:17 -07:00
Shelley Vohr
6a76540cb6 fix: return type in open/save dialogs (#19781) 2019-08-16 08:55:01 -07:00
Electron Bot
2c002a3342 Bump v8.0.0-nightly.20190816 2019-08-16 08:32:35 -07:00
Jean-Philippe Morin
42ac64284f docs: MessageBoxOptions.icon should allow type string (#19782)
In the `dialog` documentation (and the generated typings in `electron.d.ts`), it is mentionned that the `icon` property only supports `NativeImage`, but the `nativeImage` documentation says that:

```
In Electron, for the APIs that take images, you can pass either file paths or NativeImage
```
2019-08-16 17:06:02 +02:00
Cheng Zhao
2595cb5698 fix: compilation failure after chromium upgrade (#19787) 2019-08-16 07:55:34 -07:00
Cheng Zhao
c3bb73a711 feat: migrate webRequest module to NetworkService (Part 6) (#19752)
* Implement OnBeforeSendHeaders

* Pass the request

* Handle simple listeners

* Handle response listeners

* Read responses from listener
2019-08-16 10:19:05 +09:00
Micha Hanselmann
e59095423e docs: add exemplary fiddle for launch in fiddle feat (#19759)
* add fit-screen

* new url format

* nit
2019-08-15 15:37:37 -07:00
Electron Bot
db21391156 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>
2019-08-15 13:50:58 -07:00
Shelley Vohr
12df0e8994 fix: use GTK3 stock i18n strings (#19756) 2019-08-15 10:31:07 -07:00
Electron Bot
ca0cf5415e Bump v8.0.0-nightly.20190815 2019-08-15 08:31:20 -07:00
Shelley Vohr
33f2ec6355 fix: ensure child_process.fork() doesn't modify main (#19742) 2019-08-15 08:01:58 -07:00
Julien Isorce
680399f476 feat: Implement BrowserWindow.getMediaSourceId() and BrowserWindow.moveAbove(mediaSourceId) (#18926)
* feat: Implement BrowserWindow.moveAbove(mediaSourceId)

BrowserWindow.{focus,blur,moveTop}() are not enough in some
situations. For example when implementing an overlay that
follows another window that can lose focus. In that case
it is useful to move the overlay above the tracked window.

sourceId is a string in the format of DesktopCapturerSource.id,
for example "window:1869:0".

Notes: Added BrowserWindow.moveAbove(mediaSourceId)

https://github.com/electron/electron/issues/18922

* feat: Implement BrowserWindow.getMediaSourceId

Return the Window id in the format of DesktopCapturerSource's id.
For example "window:1234:0".

https://github.com/electron/electron/issues/16460

Notes: Added BrowserWindow.getMediaSourceId
2019-08-15 15:51:15 +09:00
Micha Hanselmann
d0c7a91a50 move image converter to gin (#19655) 2019-08-15 11:18:34 +09:00
Heilig Benedek
27b2747b61 fix: make sure that menu bar gets focus even when you click an item to focus it first (#19710) 2019-08-14 18:11:41 -07:00
Micha Hanselmann
9b1f698770 docs: mention QuickEdit in Windows troubleshooting (#19701)
* shot a trouble

* change title
2019-08-14 14:23:12 -07:00
Samuel Attard
efa1818cb4 feat: add new nativeTheme API (#19656)
* 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 13:42:55 -07:00
Electron Bot
246187a20f Bump v8.0.0-nightly.20190814 2019-08-14 08:31:05 -07:00
Micha Hanselmann
4c54cfc692 move net converter to gin (#19734) 2019-08-14 14:15:34 +09:00
Erick Zhao
5d892a557f fix: proper l10n on Linux dialog buttons (#19725)
* fix: proper l10n on linux dialog

* switch string
2019-08-13 20:22:25 -07:00
Cheng Zhao
49fe2604b3 Revert "fix: activate the uv_loop on incoming IPC messages (#19449)" (#19727)
This reverts commit 8028c57b42.
2019-08-13 14:03:25 -07:00
Shelley Vohr
28466a39d8 feat: add property customization to save dialogs (#19672) 2019-08-13 13:40:07 -07:00
Shelley Vohr
e1824c00a9 feat: macOS removal fallback when moveItemToTrash fails (#19700)
* feat: macOS removal fallback when moveItemToTrash fails

* platform_util shouldn't know about mate::Arguments

* pull full_path from args as well
2019-08-13 12:31:53 -07:00
Shelley Vohr
b5798326e8 feat: add dontAddToRecent to windows showOpenDialog (#19669) 2019-08-13 08:48:22 -07:00
Electron Bot
fee84de782 Bump v8.0.0-nightly.20190813 2019-08-13 08:33:27 -07:00
Shelley Vohr
e8fa248571 fix: crash in window.print() (#19690)
* fix: crash in window.print()

* add preliminary tests
2019-08-12 23:44:14 -07:00
Micha Hanselmann
ba5ee79af8 move file dialog converter to gin (#19709) 2019-08-13 14:49:48 +09:00
Cheng Zhao
69eac0d9d2 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
2019-08-13 14:47:35 +09:00
Electron Bot
9713fa09e7 chore: bump node to v12.8.0 (master) (#19521)
* 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 17:29:34 -07:00
Erick Zhao
f654da9f56 feat: add about panel customization on Windows (#19420) 2019-08-12 16:32:51 -07:00
Сковорода Никита Андреевич
ef03c4b7bb docs: fix app.on('session-created' example (#19713)
It does not have the 'event' argument.

Refs: https://github.com/electron/electron/pull/12123
Refs: https://github.com/electron/electron/pull/15236
Refs: https://github.com/electron/electron/issues/15203
2019-08-12 14:46:42 -07:00
Samuel Attard
13df748f02 build: fix nightly install command in release notes (#19711) 2019-08-12 13:01:52 -07:00
Cheng Zhao
04dbd5c53f fix: don't handle browser messages before document element is created (#19718)
* 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 10:38:41 -07:00
Electron Bot
398c5d553d Bump v8.0.0-nightly.20190812 2019-08-12 08:32:19 -07:00
Electron Bot
39f0bd3e82 Bump v8.0.0-nightly.20190811 2019-08-11 08:31:23 -07:00
Cheng Zhao
2dffc9f6eb feat: migrate webRequest module to NetworkService (Part 4) (#19679)
* chore: use gin in WebRequest

* Add stubs for APIs
2019-08-11 13:24:51 +09:00
Electron Bot
bc0a2d1b28 Bump v8.0.0-nightly.20190810 2019-08-10 08:31:20 -07:00
Erick Zhao
1749af9707 fix: avoid losing focus on inputs when opening menu (Windows/Linux) (#19657)
* remove cause of issue

* remove comment
2019-08-09 14:10:11 -07:00
Micha Hanselmann
57507ca37c refactor: move native window gin converter (#19577)
* move native window gin converter

* extract to new file
2019-08-09 13:43:18 -07:00
Shelley Vohr
7861e9f728 feat: allow customization of print page header and footer (#19688)
* feat: allow customization of more print settings

* address feedback from @jkleinsc

* header and footer are optional
2019-08-09 13:16:25 -07:00
Electron Bot
84cbc1d6c0 Bump v8.0.0-nightly.20190809 2019-08-09 08:32:09 -07:00
Milan Burda
03debb4ef9 feat: add tray.focus() (#19548) 2019-08-09 07:43:48 -07:00
Shelley Vohr
ed3b69ffb1 docs: update hasShadow for win and linux (#19675) 2019-08-08 15:49:43 -07:00
Milan Burda
0fb3c8cb7c feat: add new options to tray.displayBalloon() (#19544) 2019-08-08 14:43:33 -07:00
Richard Townsend
58840f39bb docs: document device scaling issue (#19387) 2019-08-08 13:59:44 -07:00
Pedro Pontes
da29ce355f fix: always use new site instance for a new navigation. (#18860) 2019-08-08 11:48:33 -07:00
Electron Bot
7a9e6659f0 Bump v8.0.0-nightly.20190808 2019-08-08 08:32:04 -07:00
Micha Hanselmann
9eb89b4ac7 fix: return correct bounds on will-resize (#19639) 2019-08-07 19:58:56 -07:00
Shelley Vohr
fec54c9c5d test: remove ffi specs (#19661) 2019-08-07 11:41:56 -07:00
Electron Bot
67169a5d0c Bump v8.0.0-nightly.20190807 2019-08-07 08:31:14 -07:00
Robo
eebea63bed 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
2019-08-07 11:04:09 -04:00
Shelley Vohr
9c7a216814 fix: crash on print cancellation and silent print settings (#19598)
* fix: crash on print cancellation

* fix: update printing patch for new options

* refactor: use DictionaryValue for printBackground
2019-08-07 10:47:24 -04:00
Micha Hanselmann
a8861e6a66 move gurl converter to gin (#19578) 2019-08-07 16:18:26 +09:00
Erick Zhao
8a9a5d69b6 fix: normalize behavior of win.setOpacity() for invalid number values across operating systems (#19535)
* fix: define behavior for out-of-bounds setOpacity

* fix linux issue

* fix getOpacity behaviour

* wrong variable

* normalize more stuff

* docs

* test: use ifdescribe helper

* Update spec-main/api-browser-window-spec.ts

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

* fixes

* more tests!!!

* Update shell/browser/native_window_views.cc

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

* Update shell/browser/native_window_mac.mm

Co-Authored-By: Charles Kerr <ckerr@github.com>
2019-08-07 16:17:32 +09:00
Cheng Zhao
761a4deab3 feat: associate InProgressRequest with requests (#19648) 2019-08-07 09:21:53 +09:00
CezaryKulakowski
50cc54e50b fix: keep references to active menus created by api Menu (#19427)
Without this such menus would be destroyed by js garbage collector even
when they are still displayed.
2019-08-06 14:55:00 -07:00
Shelley Vohr
da2401ff39 spec: fix dirtyChai spec failures (#19652) 2019-08-06 10:27:33 -07:00
Electron Bot
c3d0fed9ed Bump v8.0.0-nightly.20190806 2019-08-06 08:31:49 -07:00
András Polgár
c0982d7316 docs: update link to webContents.send (#19608) 2019-08-05 20:58:06 -07:00
Shelley Vohr
f0396c19be fix: clearRecentDocuments role on Windows (#19599)
* fix: clear recent documents on windows

* chore: don't check for version < win 7
2019-08-05 15:11:43 -07:00
Samuel Attard
33a9d898a6 fix: make child windows not crash when ipc messages are received (#19553) 2019-08-05 12:50:51 -07:00
Samuel Attard
cfd230d7f1 docs: remove implicit 'any' and 'Object' types from the docs (#19585)
* 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 10:45:58 -07:00
Milan Burda
ee674acca4 feat: add tray.removeBalloon() (#19547) 2019-08-05 08:52:47 -07:00
Electron Bot
8f043bbdaa Bump v8.0.0-nightly.20190805 2019-08-05 08:32:11 -07:00
Erick Zhao
750005f02b fix: handle edge behavior for about panel on Linux (#19586)
* fix: graceful About dialog fail/exit (Linux)

* Allow current to travel along path with no electrical impedance
2019-08-05 07:53:40 -07:00
Shelley Vohr
0bb227f8a4 fix: crash on window.print() (#19601) 2019-08-05 09:19:01 -04:00
Zach Bloomquist
40d9f828d4 docs: Fix process.enablePromiseAPI typo in promisification.md (#19576)
* Fix `process.enablePromiseAPI` typo in promisification.md

* Update promisification.md
2019-08-05 10:19:48 +09:00
Jeremy Apthorp
49f2071e22 test: tsify netlog spec (#19605) 2019-08-05 09:47:42 +09:00
Jeremy Apthorp
f08be2162a test: tsify callbacks-registry spec (#19606) 2019-08-05 09:46:58 +09:00
Electron Bot
45e452557b Bump v8.0.0-nightly.20190804 2019-08-04 08:32:25 -07:00
Electron Bot
df94cc1b13 Bump v8.0.0-nightly.20190803 2019-08-03 08:31:26 -07:00
Jeremy Apthorp
bd28b876a0 fix: disable 'reopen windows?' dialog after crash (#19584) 2019-08-02 17:04:41 -07:00
Electron Bot
e959137a4b chore: bump chromium to 32e0bab929213da1019992bf31d29 (master) (#19488) 2019-08-02 16:56:46 -07:00
Jeremy Apthorp
d0800aa200 test: report hexadecimal status codes on windows (#19597) 2019-08-02 14:23:11 -07:00
Milan Burda
3011a0f14f refactor: convert ipc-renderer.ts to TypeScript (#19556)
* refactor: convert ipc-renderer.ts to TypeScript

* Update typings/internal-ambient.d.ts

Co-Authored-By: Samuel Attard <sattard@slack-corp.com>
2019-08-02 14:35:04 -05:00
Micha Hanselmann
ee64c6ab86 refactor: move file path gin converter to new file (#19575)
* move file path gin converter to new file

* move string16 gin conv to new file
2019-08-02 14:34:30 -05:00
Electron Bot
79277cc383 Bump v8.0.0-nightly.20190802 2019-08-02 08:31:00 -07:00
Andy Dill
e78b902a7d fix: expose setMenuBarVisibility again (#19557) 2019-08-01 14:01:05 -07:00
Milan Burda
e8c4e6f0b3 fix: use correct constants for tray icon messages (#19549) 2019-08-01 14:00:37 -07:00
Electron Bot
2e785899dd Bump v8.0.0-nightly.20190801 2019-08-01 08:31:16 -07:00
Milan Burda
115b57649e docs: fix TouchBar related documentation (#19444) 2019-08-01 10:59:26 -04:00
Micha Hanselmann
b80429ab7f refactor: migrate dialog API to //gin (#19482)
* get ShowMessageBoxSync working with gin

* move more dialog methods

* all methods moved

* cleanup

* add util func for template creation
2019-08-01 10:57:41 -04:00
Samuel Attard
c190e64012 build: update the ABI version for electron 8 nightlies (#19551) 2019-08-01 10:54:26 -04:00
John Kleinschmidt
3a6cafaf0a fix: use WeakPtr to detect deletion (#19257) 2019-07-31 19:48:40 -04:00
Milan Burda
c76b0b70c1 refactor: remove content::WebContentsObserver from Event (#19251) 2019-07-31 15:20:28 -07:00
Jeremy Apthorp
c71cdce0b7 chore: disable JS impl when //extensions support is on (#19512) 2019-07-31 14:25:41 -07:00
Shelley Vohr
a5f87cee6b doc: add missing MenuItem roles (#19329) 2019-07-31 14:13:56 -07:00
Samuel Attard
bf66fe51f6 build: fix first beta version choosing logic 2019-07-31 11:04:19 -07:00
470 changed files with 5541 additions and 9345 deletions

View File

@@ -180,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-ci"' >> $BASH_ENV
echo 'export SCCACHE_BUCKET="electronjs-sccache"' >> $BASH_ENV
echo 'export SCCACHE_TWO_TIER=true' >> $BASH_ENV
fi
fi

10
.github/main.workflow vendored
View File

@@ -1,10 +0,0 @@
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
View File

@@ -1,25 +0,0 @@
# 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,7 +26,6 @@ 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) {
@@ -656,12 +655,6 @@ 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",
@@ -776,7 +769,6 @@ if (is_mac) {
":electron_framework_libraries",
":electron_framework_resources",
":electron_swiftshader_library",
":electron_xibs",
]
if (!is_mas_build) {
deps += [ ":electron_crashpad_helper" ]

9
DEPS
View File

@@ -5,15 +5,14 @@ gclient_gn_args = [
'checkout_android_native_support',
'checkout_libaom',
'checkout_nacl',
'checkout_oculus_sdk',
'checkout_openxr'
'checkout_oculus_sdk'
]
vars = {
'chromium_version':
'78.0.3904.99',
'62327c655093c821aa0fcfc6db53f5fd943e08c7',
'node_version':
'v12.8.1',
'v12.9.1',
'nan_version':
'2ee313aaca52e2b478965ac50eb5082520380d1b',
@@ -61,8 +60,6 @@ vars = {
True,
'checkout_oculus_sdk':
False,
'checkout_openxr':
False,
'build_with_chromium':
True,
'checkout_android':

View File

@@ -1 +1 @@
7.1.1
8.0.0-nightly.20190902

View File

@@ -138,5 +138,6 @@ deploy_script:
& python script\release\uploaders\upload.py
}
} elseif (Test-Path Env:\TEST_WOA) {
node script/release/ci-release-build.js --job=electron-woa-testing --ci=VSTS --armTest --appveyorJobId=$env:APPVEYOR_JOB_ID $env:APPVEYOR_REPO_BRANCH
# node script/release/ci-release-build.js --job=electron-woa-testing --ci=VSTS --armTest --appveyorJobId=$env:APPVEYOR_JOB_ID $env:APPVEYOR_REPO_BRANCH
echo "Eventually run tests on WOA hardware at this step"
}

View File

@@ -6,8 +6,8 @@ steps:
- script: |
cd src\electron
node script/yarn.js install --frozen-lockfile
displayName: 'Yarn install'
npm install --verbose
displayName: 'NPM install'
- powershell: |
$localArtifactPath = "$pwd\dist.zip"
@@ -27,6 +27,16 @@ steps:
env:
APPVEYOR_TOKEN: $(APPVEYOR_TOKEN)
- powershell: |
$localArtifactPath = "$pwd\src\out\Default\mksnapshot.zip"
$serverArtifactPath = "$env:APPVEYOR_URL/buildjobs/$env:APPVEYOR_JOB_ID/artifacts/mksnapshot.zip"
Invoke-RestMethod -Method Get -Uri $serverArtifactPath -OutFile $localArtifactPath -Headers @{ "Authorization" = "Bearer $env:APPVEYOR_TOKEN" }
cd src\out\Default
& "${env:ProgramFiles(x86)}\7-Zip\7z.exe" x -y mksnapshot.zip
displayName: 'Download and unzip mksnapshot.zip for test'
env:
APPVEYOR_TOKEN: $(APPVEYOR_TOKEN)
- powershell: |
$localArtifactPath = "$pwd\src\node_headers.zip"
$serverArtifactPath = "$env:APPVEYOR_URL/buildjobs/$env:APPVEYOR_JOB_ID/artifacts/node_headers.zip"
@@ -60,16 +70,6 @@ steps:
env:
ELECTRON_OUT_DIR: Default
IGNORE_YARN_INSTALL_ERROR: 1
ELECTRON_TEST_RESULTS_DIR: junit
MOCHA_MULTI_REPORTERS: 'mocha-junit-reporter, tap'
MOCHA_REPORTER: mocha-multi-reporters
- task: PublishTestResults@2
displayName: 'Publish Test Results'
inputs:
testResultsFiles: '*.xml'
searchFolder: '$(System.DefaultWorkingDirectory)/src/junit/'
condition: always()
- script: |
cd src
@@ -77,8 +77,8 @@ steps:
python electron\script\verify-ffmpeg.py --build-dir out\Default --source-root %cd% --ffmpeg-path out\ffmpeg
displayName: 'Verify ffmpeg'
- powershell: |
Get-Process | Where Name Like "electron*" | Stop-Process
Get-Process | Where Name Like "MicrosoftEdge*" | Stop-Process
displayName: 'Kill processes left running from last test run'
condition: always()
- script: |
cd src
echo "Verifying mksnapshot"
python electron\script\verify-mksnapshot.py --build-dir out\Default --source-root %cd%
displayName: 'Verify mksnapshot'

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 = 75
node_module_version = 76
v8_promise_internal_field_count = 1
v8_typed_array_max_size_in_heap = 0

View File

@@ -1,57 +0,0 @@
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.js'),
'electron': path.resolve(electronRoot, 'lib', loadElectronFromAlternateTarget || target, 'api', 'exports', 'electron.ts'),
// Force timers to resolve to our dependency that doens't use window.postMessage
'timers': path.resolve(electronRoot, 'node_modules', 'timers-browserify', 'main.js')
},
@@ -74,10 +74,7 @@ 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

@@ -43,6 +43,8 @@ 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",
@@ -133,6 +135,10 @@ static_library("chrome") {
sources += [
"//chrome/browser/speech/tts_controller_delegate_impl.cc",
"//chrome/browser/speech/tts_controller_delegate_impl.h",
"//chrome/browser/speech/tts_message_filter.cc",
"//chrome/browser/speech/tts_message_filter.h",
"//chrome/renderer/tts_dispatcher.cc",
"//chrome/renderer/tts_dispatcher.h",
]
}
@@ -162,8 +168,6 @@ 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 += [
@@ -198,6 +202,8 @@ static_library("chrome") {
"//chrome/browser/ui/views/overlay/back_to_tab_image_button.h",
"//chrome/browser/ui/views/overlay/close_image_button.cc",
"//chrome/browser/ui/views/overlay/close_image_button.h",
"//chrome/browser/ui/views/overlay/mute_image_button.cc",
"//chrome/browser/ui/views/overlay/mute_image_button.h",
"//chrome/browser/ui/views/overlay/overlay_window_views.cc",
"//chrome/browser/ui/views/overlay/overlay_window_views.h",
"//chrome/browser/ui/views/overlay/playback_image_button.cc",

View File

@@ -54,7 +54,6 @@ component("pepper_flash") {
"//chrome/browser/renderer_host/pepper/monitor_finder_mac.h",
"//chrome/browser/renderer_host/pepper/monitor_finder_mac.mm",
]
libs = [ "CoreGraphics.framework" ]
}
if (is_linux) {
deps += [ "//components/services/font/public/cpp" ]

View File

@@ -2,9 +2,10 @@
<head>
<title>Electron</title>
<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'" />
<meta http-equiv="Content-Security-Policy" content="default-src 'none'; script-src 'self'; 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>
@@ -83,9 +84,6 @@
</div>
</div>
</nav>
<script>
window.electronDefaultApp.initialize()
</script>
</body>
</html>

30
default_app/index.ts Normal file
View File

@@ -0,0 +1,30 @@
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,31 +1,4 @@
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
}
}
}
}
import { ipcRenderer } from 'electron'
async function initialize () {
const electronPath = await ipcRenderer.invoke('bootstrap')
@@ -42,12 +15,6 @@ 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)
}
}
contextBridge.exposeInMainWorld('electronDefaultApp', {
initialize
})
document.addEventListener('DOMContentLoaded', initialize)

View File

@@ -39,7 +39,6 @@ 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)

View File

@@ -390,7 +390,7 @@ Emitted when Electron has created a new `session`.
```javascript
const { app } = require('electron')
app.on('session-created', (event, session) => {
app.on('session-created', (session) => {
console.log(session)
})
```
@@ -675,6 +675,8 @@ 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()`
@@ -1168,21 +1170,21 @@ This API must be called after the `ready` event is emitted.
**[Deprecated](modernization/property-updates.md)**
### `app.showAboutPanel()` _macOS_ _Linux_
### `app.showAboutPanel()`
Show the app's about panel options. These options can be overridden with `app.setAboutPanelOptions(options)`.
### `app.setAboutPanelOptions(options)` _macOS_ _Linux_
### `app.setAboutPanelOptions(options)`
* `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_ - Credit information.
* `credits` String (optional) _macOS_ _Windows_ - Credit information.
* `authors` String[] (optional) _Linux_ - List of app authors.
* `website` String (optional) _Linux_ - The app's website.
* `iconPath` String (optional) _Linux_ - Path to the app's icon. Will be shown as 64x64 pixels while retaining aspect ratio.
* `iconPath` String (optional) _Linux_ _Windows_ - Path to the app's icon. On Linux, will be shown as 64x64 pixels while retaining aspect ratio.
Set the about panel options. This will override the values defined in the app's
`.plist` file on MacOS. See the [Apple docs][about-panel-options] for more details. On Linux, values must be set in order to be shown; there are no defaults.

View File

@@ -51,9 +51,6 @@ This event is usually emitted after the `did-finish-load` event, but for
pages with many remote resources, it may be emitted before the `did-finish-load`
event.
Please note that using this event implies that the renderer will be considered "visible" and
paint even though `show` is false. This event will never fire if you use `paintWhenInitiallyHidden: false`
## Setting `backgroundColor`
For a complex app, the `ready-to-show` event could be emitted too late, making
@@ -187,7 +184,6 @@ It creates a new `BrowserWindow` with native properties as set by the `options`.
leave it undefined so the executable's icon will be used.
* `show` Boolean (optional) - Whether window should be shown when created. Default is
`true`.
* `paintWhenInitiallyHidden` Boolean (optional) - Whether the renderer should be active when `show` is `false` and it has just been created. In order for `document.visibilityState` to work correctly on first load with `show: false` you should set this to `false`. Setting this to `false` will cause the `ready-to-show` event to not fire. Default is `true`.
* `frame` Boolean (optional) - Specify `false` to create a
[Frameless Window](frameless-window.md). Default is `true`.
* `parent` BrowserWindow (optional) - Specify parent window. Default is `null`.
@@ -383,6 +379,9 @@ 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
@@ -489,9 +488,6 @@ Emitted when the window is hidden.
Emitted when the web page has been rendered (while not being shown) and window can be displayed without
a visual flash.
Please note that using this event implies that the renderer will be considered "visible" and
paint even though `show` is false. This event will never fire if you use `paintWhenInitiallyHidden: false`
#### Event: 'maximize'
Emitted when window is maximized.
@@ -523,14 +519,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' _Windows_
#### Event: 'will-move' _macOS_ _Windows_
Returns:
* `event` Event
* `newBounds` [`Rectangle`](structures/rectangle.md) - Location the window is being moved to.
Emitted before the window is moved. Calling `event.preventDefault()` will prevent the window from being moved.
Emitted before the window is moved. On Windows, 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.
@@ -828,6 +824,12 @@ 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:
@@ -1201,6 +1203,14 @@ 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
@@ -1273,6 +1283,15 @@ 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.
@@ -1553,7 +1572,7 @@ Same as `webContents.showDefinitionForSelection()`.
#### `win.setIcon(icon)` _Windows_ _Linux_
* `icon` [NativeImage](native-image.md) | String
* `icon` [NativeImage](native-image.md)
Changes window icon.

View File

@@ -4,12 +4,18 @@
Process: [Main](../glossary.md#main-process), [Renderer](../glossary.md#renderer-process)
The following example shows how to write a string to the clipboard:
```javascript
const { clipboard } = require('electron')
clipboard.writeText('Example String')
```
On Linux, there is also a `selection` clipboard. To manipulate it
you need to pass `selection` to each method:
```javascript
const { clipboard } = require('electron')
clipboard.writeText('Example String', 'selection')
console.log(clipboard.readText('selection'))
```
@@ -22,106 +28,56 @@ The `clipboard` module has the following methods:
### `clipboard.readText([type])`
* `type` String (optional) - Can be `selection` or `clipboard`; default is 'clipboard'. `selection` is only available on Linux.
* `type` String (optional) - Can be `selection` or `clipboard`. `selection` is only available on Linux.
Returns `String` - The content in the clipboard as plain text.
```js
const { clipboard } = require('electron')
clipboard.writeText('hello i am a bit of text!')
const text = clipboard.readText()
console.log(text)
// hello i am a bit of text!'
```
### `clipboard.writeText(text[, type])`
* `text` String
* `type` String (optional) - Can be `selection` or `clipboard`; default is 'clipboard'. `selection` is only available on Linux.
* `type` String (optional) - Can be `selection` or `clipboard`. `selection` is only available on Linux.
Writes the `text` into the clipboard as plain text.
```js
const { clipboard } = require('electron')
const text = 'hello i am a bit of text!'
clipboard.writeText(text)
```
### `clipboard.readHTML([type])`
* `type` String (optional) - Can be `selection` or `clipboard`; default is 'clipboard'. `selection` is only available on Linux.
* `type` String (optional) - Can be `selection` or `clipboard`. `selection` is only available on Linux.
Returns `String` - The content in the clipboard as markup.
```js
const { clipboard } = require('electron')
clipboard.writeHTML('<b>Hi</b>')
const html = clipboard.readHTML()
console.log(html)
// <meta charset='utf-8'><b>Hi</b>
```
### `clipboard.writeHTML(markup[, type])`
* `markup` String
* `type` String (optional) - Can be `selection` or `clipboard`; default is 'clipboard'. `selection` is only available on Linux.
* `type` String (optional) - Can be `selection` or `clipboard`. `selection` is only available on Linux.
Writes `markup` to the clipboard.
```js
const { clipboard } = require('electron')
clipboard.writeHTML('<b>Hi</b')
```
### `clipboard.readImage([type])`
* `type` String (optional) - Can be `selection` or `clipboard`; default is 'clipboard'. `selection` is only available on Linux.
* `type` String (optional) - Can be `selection` or `clipboard`. `selection` is only available on Linux.
Returns [`NativeImage`](native-image.md) - The image content in the clipboard.
### `clipboard.writeImage(image[, type])`
* `image` [NativeImage](native-image.md)
* `type` String (optional) - Can be `selection` or `clipboard`; default is 'clipboard'. `selection` is only available on Linux.
* `type` String (optional) - Can be `selection` or `clipboard`. `selection` is only available on Linux.
Writes `image` to the clipboard.
### `clipboard.readRTF([type])`
* `type` String (optional) - Can be `selection` or `clipboard`; default is 'clipboard'. `selection` is only available on Linux.
* `type` String (optional) - Can be `selection` or `clipboard`. `selection` is only available on Linux.
Returns `String` - The content in the clipboard as RTF.
```js
const { clipboard } = require('electron')
clipboard.writeRTF('{\\rtf1\\ansi{\\fonttbl\\f0\\fswiss Helvetica;}\\f0\\pard\nThis is some {\\b bold} text.\\par\n}')
const rtf = clipboard.readRTF()
console.log(rtf)
// {\\rtf1\\ansi{\\fonttbl\\f0\\fswiss Helvetica;}\\f0\\pard\nThis is some {\\b bold} text.\\par\n}
```
### `clipboard.writeRTF(text[, type])`
* `text` String
* `type` String (optional) - Can be `selection` or `clipboard`; default is 'clipboard'. `selection` is only available on Linux.
* `type` String (optional) - Can be `selection` or `clipboard`. `selection` is only available on Linux.
Writes the `text` into the clipboard in RTF.
```js
const { clipboard } = require('electron')
const rtf = '{\\rtf1\\ansi{\\fonttbl\\f0\\fswiss Helvetica;}\\f0\\pard\nThis is some {\\b bold} text.\\par\n}'
clipboard.writeRTF(rtf)
```
### `clipboard.readBookmark()` _macOS_ _Windows_
Returns `Object`:
@@ -137,7 +93,7 @@ bookmark is unavailable.
* `title` String
* `url` String
* `type` String (optional) - Can be `selection` or `clipboard`; default is 'clipboard'. `selection` is only available on Linux.
* `type` String (optional) - Can be `selection` or `clipboard`. `selection` is only available on Linux.
Writes the `title` and `url` into the clipboard as a bookmark.
@@ -146,9 +102,7 @@ you can use `clipboard.write` to write both a bookmark and fallback text to the
clipboard.
```js
const { clipboard } = require('electron')
clipboard.writeBookmark({
clipboard.write({
text: 'https://electronjs.org',
bookmark: 'Electron Homepage'
})
@@ -156,50 +110,39 @@ clipboard.writeBookmark({
### `clipboard.readFindText()` _macOS_
Returns `String` - The text on the find pasteboard, which is the pasteboard that holds information about the current state of the active applications find panel.
This method uses synchronous IPC when called from the renderer process.
The cached value is reread from the find pasteboard whenever the application is activated.
Returns `String` - The text on the find pasteboard. This method uses synchronous
IPC when called from the renderer process. The cached value is reread from the
find pasteboard whenever the application is activated.
### `clipboard.writeFindText(text)` _macOS_
* `text` String
Writes the `text` into the find pasteboard (the pasteboard that holds information about the current state of the active applications find panel) as plain text. This method uses synchronous IPC when called from the renderer process.
Writes the `text` into the find pasteboard as plain text. This method uses
synchronous IPC when called from the renderer process.
### `clipboard.clear([type])`
* `type` String (optional) - Can be `selection` or `clipboard`; default is 'clipboard'. `selection` is only available on Linux.
* `type` String (optional) - Can be `selection` or `clipboard`. `selection` is only available on Linux.
Clears the clipboard content.
### `clipboard.availableFormats([type])`
* `type` String (optional) - Can be `selection` or `clipboard`; default is 'clipboard'. `selection` is only available on Linux.
* `type` String (optional) - Can be `selection` or `clipboard`. `selection` is only available on Linux.
Returns `String[]` - An array of supported formats for the clipboard `type`.
```js
const { clipboard } = require('electron')
const formats = clipboard.availableFormats()
console.log(formats)
// [ 'text/plain', 'text/html' ]
```
### `clipboard.has(format[, type])` _Experimental_
* `format` String
* `type` String (optional) - Can be `selection` or `clipboard`; default is 'clipboard'. `selection` is only available on Linux.
* `type` String (optional) - Can be `selection` or `clipboard`. `selection` is only available on Linux.
Returns `Boolean` - Whether the clipboard supports the specified `format`.
```js
```javascript
const { clipboard } = require('electron')
const hasFormat = clipboard.has('<p>selection</p>')
console.log(hasFormat)
// 'true' or 'false
console.log(clipboard.has('<p>selection</p>'))
```
### `clipboard.read(format)` _Experimental_
@@ -214,33 +157,14 @@ Returns `String` - Reads `format` type from the clipboard.
Returns `Buffer` - Reads `format` type from the clipboard.
```js
const { clipboard } = require('electron')
const buffer = Buffer.from('this is binary', 'utf8')
clipboard.writeBuffer('public.utf8-plain-text', buffer)
const ret = clipboard.readBuffer('public.utf8-plain-text')
console.log(buffer.equals(out))
// true
```
### `clipboard.writeBuffer(format, buffer[, type])` _Experimental_
* `format` String
* `buffer` Buffer
* `type` String (optional) - Can be `selection` or `clipboard`; default is 'clipboard'. `selection` is only available on Linux.
* `type` String (optional) - Can be `selection` or `clipboard`. `selection` is only available on Linux.
Writes the `buffer` into the clipboard as `format`.
```js
const { clipboard } = require('electron')
const buffer = Buffer.from('writeBuffer', 'utf8')
clipboard.writeBuffer('public.utf8-plain-text', buffer)
```
### `clipboard.write(data[, type])`
* `data` Object
@@ -249,29 +173,10 @@ clipboard.writeBuffer('public.utf8-plain-text', buffer)
* `image` [NativeImage](native-image.md) (optional)
* `rtf` String (optional)
* `bookmark` String (optional) - The title of the URL at `text`.
* `type` String (optional) - Can be `selection` or `clipboard`; default is 'clipboard'. `selection` is only available on Linux.
* `type` String (optional) - Can be `selection` or `clipboard`. `selection` is only available on Linux.
Writes `data` to the clipboard.
```js
```javascript
const { clipboard } = require('electron')
clipboard.write({
text: 'test',
html: '<b>Hi</b>',
rtf: '{\\rtf1\\utf8 text}',
bookmark: 'a title'
})
console.log(clipboard.readText())
// 'test'
console.log(clipboard.readHTML())
// <meta charset='utf-8'><b>Hi</b>
console.log(clipboard.readRTF())
// '{\\rtf1\\utf8 text}'
console.log(clipboard.readBookmark())
// { title: 'a title', url: 'test' }
clipboard.write({ text: 'test', html: '<b>test</b>' })
```
Writes `data` to the clipboard.

View File

@@ -1,111 +0,0 @@
# 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,6 +48,7 @@ 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.
@@ -110,6 +111,7 @@ 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.
@@ -171,6 +173,13 @@ 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`.
@@ -193,8 +202,14 @@ 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`.
* `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 `Promise<Object>` - Resolve with an object containing the following:

View File

@@ -77,7 +77,6 @@ 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`.
@@ -148,4 +147,4 @@ found in the [`ipc-main-invoke-event`](structures/ipc-main-invoke-event.md)
structure docs.
[event-emitter]: https://nodejs.org/api/events.html#events_class_eventemitter
[web-contents-send]: web-contents.md#contentssendchannel-args
[web-contents-send]: web-contents.md#contentssendchannel-arg1-arg2-

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.enablePromiseAPI` runtime flag.
To enable deprecation warnings for these updated functions, use the [`process.enablePromiseAPIs` runtime flag](../process.md#processenablepromiseapis).
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')
let win = new BrowserWindow({ icon: '/Users/somebody/images/window.png' })
const 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')
let appIcon = new Tray('/Users/somebody/images/icon.png')
const appIcon = new Tray('/Users/somebody/images/icon.png')
console.log(appIcon)
```
Following suffixes for DPI are also supported:
The 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
let image = nativeImage.createFromPath('/Users/somebody/images/icon.png')
const image = nativeImage.createFromPath('/Users/somebody/images/icon.png')
console.log(image)
```
@@ -180,7 +180,8 @@ 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
@@ -248,9 +249,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, `getBitmap()` does not
The difference between `getBitmap()` and `toBitmap()` is that `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_
@@ -295,7 +296,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

@@ -2,7 +2,7 @@
> Read and respond to changes in Chromium's native color theme.
Process: [Main](../glossary.md#main-process)
Process: [Main](../glossary.md#main-process), [Renderer](../glossary.md#renderer-process)
## Events
@@ -22,38 +22,7 @@ The `nativeTheme` module has the following properties:
### `nativeTheme.shouldUseDarkColors` _Readonly_
A `Boolean` for if the OS / Chromium currently has a dark mode enabled or is
being instructed to show a dark-style UI. If you want to modify this value you
should use `themeSource` below.
### `nativeTheme.themeSource`
A `String` property that can be `system`, `light` or `dark`. It is used to override and supercede
the value that Chromium has chosen to use internally.
Setting this property to `system` will remove the override and
everything will be reset to the OS default. By default `themeSource` is `system`.
Settings this property to `dark` will have the following effects:
* `nativeTheme.shouldUseDarkColors` will be `true` when accessed
* Any UI Electron renders on Linux and Windows including context menus, devtools, etc. will use the dark UI.
* Any UI the OS renders on macOS including menus, window frames, etc. will use the dark UI.
* The [`prefers-color-scheme`](https://developer.mozilla.org/en-US/docs/Web/CSS/@media/prefers-color-scheme) CSS query will match `dark` mode.
* The `updated` event will be emitted
Settings this property to `light` will have the following effects:
* `nativeTheme.shouldUseDarkColors` will be `false` when accessed
* Any UI Electron renders on Linux and Windows including context menus, devtools, etc. will use the light UI.
* Any UI the OS renders on macOS including menus, window frames, etc. will use the light UI.
* The [`prefers-color-scheme`](https://developer.mozilla.org/en-US/docs/Web/CSS/@media/prefers-color-scheme) CSS query will match `light` mode.
* The `updated` event will be emitted
The usage of this property should align with a classic "dark mode" state machine in your application
where the user has three options.
* `Follow OS` --> `themeSource = 'system'`
* `Dark Mode` --> `themeSource = 'dark'`
* `Light Mode` --> `themeSource = 'light'`
Your application should then always use `shouldUseDarkColors` to determine what CSS to apply.
being instructed to show a dark-style UI.
### `nativeTheme.shouldUseHighContrastColors` _macOS_ _Windows_ _Readonly_

View File

@@ -217,15 +217,11 @@ that all statistics are reported in Kilobytes.
Returns `String` - The version of the host operating system.
Example:
Examples:
```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'
```
* `macOS` -> `10.13.6`
* `Windows` -> `10.0.17763`
* `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

@@ -389,7 +389,9 @@ which sends a `Buffer` as a response.
* `url` String
* `method` String (optional)
* `session` Session | null (optional)
* `uploadData` [ProtocolResponseUploadData](structures/protocol-response-upload-data.md) (optional)
* `uploadData` Object (optional)
* `contentType` String - MIME type of the content.
* `data` String - Content to be sent.
* `completion` Function (optional)
* `error` Error

View File

@@ -91,7 +91,7 @@ session.defaultSession.on('will-download', (event, item, webContents) => {
})
```
#### Event: 'preconnect' _Experimental_
#### Event: 'preconnect'
Returns:
@@ -139,9 +139,9 @@ Writes any unwritten DOMStorage data to disk.
#### `ses.setProxy(config)`
* `config` Object
* `pacScript` String - The URL associated with the PAC file.
* `proxyRules` String - Rules indicating which proxies to use.
* `proxyBypassRules` String - Rules indicating which URLs should
* `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
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)` _Experimental_
#### `ses.preconnect(options)`
* `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
* `proc` Function | null
* `request` Object
* `hostname` String
* `certificate` [Certificate](structures/certificate.md)
@@ -408,6 +408,17 @@ 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
@@ -416,8 +427,8 @@ Returns `Promise<Buffer>` - resolves with blob data.
* `mimeType` String (optional)
* `offset` Integer - Start range for the download.
* `length` Integer - Total length of the download.
* `lastModified` String - Last-Modified header value.
* `eTag` String - ETag header value.
* `lastModified` String (optional) - Last-Modified header value.
* `eTag` String (optional) - ETag header value.
* `startTime` Double (optional) - Time when download was started in
number of seconds since UNIX epoch.

View File

@@ -43,11 +43,12 @@ 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)`
### `shell.moveItemToTrash(fullPath[, deleteOnFail])`
* `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.
Returns `Boolean` - Whether the item was successfully moved to the trash or otherwise deleted.
Move the given file to trash and returns a boolean status for the operation.

View File

@@ -1,6 +1,6 @@
# InputEvent Object
* `modifiers` String[] - An array of modifiers of the event, can
be `shift`, `control`, `alt`, `meta`, `isKeypad`, `isAutoRepeat`,
`leftButtonDown`, `middleButtonDown`, `rightButtonDown`, `capsLock`,
`numLock`, `left`, `right`.
* `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`.

View File

@@ -1,4 +1,4 @@
# ProtocolResponseUploadData Object
* `contentType` String - MIME type of the content.
* `data` String | Buffer - Content to be sent.
* `data` String - Content to be sent.

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`.
* `iconPosition` String (optional) - Can be `left`, `right` or `overlay`. Defaults to `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) (optional) - Items to display in the popover.
* `items` [TouchBar](touch-bar.md) - 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. Defaults to `null`.
* `overlayStyle` String (optional) - Selected overlay item style. Defaults to `null`.
* `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`.
* `showArrowButtons` Boolean (optional) - Defaults to `false`.
* `mode` String (optional) - Defaults to `free`.
* `mode` String (optional) - Can be `fixed` or `free`. The default is `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]`.
* `null` - Actually null, not a string, removes all styles.
* `none` - Removes all styles.
#### `touchBarScrubber.overlayStyle`
@@ -44,7 +44,7 @@ touch bar. Possible values:
* `background` - Maps to `[NSScrubberSelectionStyle roundedBackgroundStyle]`.
* `outline` - Maps to `[NSScrubberSelectionStyle outlineOverlayStyle]`.
* `null` - Actually null, not a string, removes all styles.
* `none` - 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.
* `rounded` - The control is displayed using the rounded style.
is displayed and the position within the window. Maps to `NSSegmentStyleAutomatic`.
* `rounded` - The control is displayed using the rounded style. Maps to `NSSegmentStyleRounded`.
* `textured-rounded` - The control is displayed using the textured rounded
style.
* `round-rect` - The control is displayed using the round rect style.
style. Maps to `NSSegmentStyleTexturedRounded`.
* `round-rect` - The control is displayed using the round rect style. Maps to `NSSegmentStyleRoundRect`.
* `textured-square` - The control is displayed using the textured square
style.
* `capsule` - The control is displayed using the capsule style.
* `small-square` - The control is displayed using the small square style.
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`.
* `separated` - The segments in the control are displayed very close to each
other but not touching.
other but not touching. Maps to `NSSegmentStyleSeparated`.
* `mode` String (optional) - The selection mode of the control:
* `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.
* `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`.
* `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.
* `large` - Large space between items.
* `flexible` - Take up all available space.
* `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`.

View File

@@ -222,12 +222,31 @@ Returns `Boolean` - Whether double click events will be ignored.
#### `tray.displayBalloon(options)` _Windows_
* `options` Object
* `icon` ([NativeImage](native-image.md) | String) (optional) -
* `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`.
* `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,6 +1264,8 @@ 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`.
@@ -1591,8 +1593,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) - The image must be non-empty on
macOS.
* `icon` [NativeImage](native-image.md) | String - 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,7 +99,7 @@ Some examples of valid `urls`:
* `timestamp` Double
* `requestHeaders` Record<string, string>
* `callback` Function
* `response` Object
* `beforeSendResponse` Object
* `cancel` Boolean (optional)
* `requestHeaders` Record<string, string | string[]> (optional) - When provided, request will be made
with these headers.
@@ -148,7 +148,7 @@ response are visible by the time this listener is fired.
* `statusCode` Integer
* `responseHeaders` Record<string, string> (optional)
* `callback` Function
* `response` Object
* `headersReceivedResponse` Object
* `cancel` Boolean (optional)
* `responseHeaders` Record<string, string | string[]> (optional) - When provided, the server is assumed
to have responded with these headers.

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-ci"
export SCCACHE_BUCKET="electronjs-sccache"
export SCCACHE_TWO_TIER=true
```

View File

@@ -113,3 +113,10 @@ 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,3 +48,12 @@ 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.

Before

Width:  |  Height:  |  Size: 868 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 MiB

View File

@@ -31,8 +31,7 @@ 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 [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
Forge comes with [a ready-to-use template](https://electronforge.io/templates) using Webpack as a bundler. It includes an example typescript configuration and provides two configuration files to enable easy customization. It uses the same core modules used by the
greater Electron community (like [`electron-packager`](https://github.com/electron/electron-packager))  
changes made by Electron maintainers (like Slack) benefit Forge's users, too.

View File

@@ -195,6 +195,8 @@ 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

@@ -38,15 +38,11 @@ npm install --platform=win32 electron
## Proxies
If you need to use an HTTP proxy, you need to set the `ELECTRON_GET_USE_PROXY` variable to any
value, plus additional environment variables depending on your host system's Node version:
* [Node 10 and above][proxy-env-10]
* [Before Node 10][proxy-env]
If you need to use an HTTP proxy you can [set these environment variables][proxy-env].
## Custom Mirrors and Caches
During installation, the `electron` module will call out to
[`@electron/get`][electron-get] to download prebuilt binaries of
[`electron-download`][electron-download] to download prebuilt binaries of
Electron for your platform. It will do so by contacting GitHub's
release download page (`https://github.com/electron/electron/releases/tag/v$VERSION`,
where `$VERSION` is the exact version of Electron).
@@ -150,8 +146,7 @@ If you need to force a re-download of the asset and the SHASUM file set the
[npm]: https://docs.npmjs.com
[versioning]: ./electron-versioning.md
[releases]: https://github.com/electron/electron/releases
[proxy-env-10]: https://github.com/gajus/global-agent/blob/v2.1.5/README.md#environment-variables
[proxy-env]: https://github.com/np-maintain/global-tunnel/blob/v2.7.1/README.md#auto-config
[electron-get]: https://github.com/electron/get
[proxy-env]: https://github.com/request/request/tree/f0c4ec061141051988d1216c24936ad2e7d5c45d#controlling-proxy-behaviour-using-environment-variables
[electron-download]: https://github.com/electron-userland/electron-download
[npm-permissions]: https://docs.npmjs.com/getting-started/fixing-npm-permissions
[unsafe-perm]: https://docs.npmjs.com/misc/config#unsafe-perm

View File

@@ -1,431 +0,0 @@
# 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

@@ -13,7 +13,7 @@
<!-- Desktop Capturer API -->
<message name="IDS_DESKTOP_MEDIA_PICKER_SINGLE_SCREEN_NAME" desc="Name for screens in the desktop media picker UI when there is only one monitor.">
Entire Screen
Entire screen
</message>
<message name="IDS_DESKTOP_MEDIA_PICKER_MULTIPLE_SCREEN_NAME" desc="Name for screens in the desktop media picker UI when there are multiple monitors.">
{SCREEN_INDEX, plural, =1{Screen #} other{Screen #}}

View File

@@ -14,7 +14,6 @@ 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",
@@ -131,21 +130,21 @@ auto_filenames = {
"lib/browser/api/module-keys.js",
"lib/common/api/clipboard.js",
"lib/common/api/deprecate.ts",
"lib/common/api/module-list.js",
"lib/common/api/module-list.ts",
"lib/common/api/native-image.js",
"lib/common/api/native-theme.ts",
"lib/common/api/shell.js",
"lib/common/buffer-utils.ts",
"lib/common/clipboard-utils.ts",
"lib/common/crash-reporter.js",
"lib/common/define-properties.ts",
"lib/common/electron-binding-setup.ts",
"lib/common/error-utils.ts",
"lib/common/is-promise.ts",
"lib/common/web-view-methods.ts",
"lib/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.js",
"lib/renderer/api/ipc-renderer.ts",
"lib/renderer/api/remote.js",
"lib/renderer/api/web-frame.ts",
"lib/renderer/callbacks-registry.ts",
@@ -166,8 +165,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.js",
"lib/sandboxed_renderer/api/module-list.js",
"lib/sandboxed_renderer/api/exports/electron.ts",
"lib/sandboxed_renderer/api/module-list.ts",
"lib/sandboxed_renderer/init.js",
"package.json",
"tsconfig.electron.json",
@@ -177,7 +176,6 @@ 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",
@@ -192,7 +190,6 @@ 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",
@@ -218,7 +215,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.js",
"lib/browser/api/exports/electron.ts",
"lib/browser/api/global-shortcut.js",
"lib/browser/api/in-app-purchase.js",
"lib/browser/api/ipc-main.ts",
@@ -226,8 +223,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.js",
"lib/browser/api/native-theme.ts",
"lib/browser/api/module-list.ts",
"lib/browser/api/net-log.js",
"lib/browser/api/net.js",
"lib/browser/api/notification.js",
@@ -258,6 +254,7 @@ 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",
@@ -266,13 +263,14 @@ auto_filenames = {
"lib/browser/utils.ts",
"lib/common/api/clipboard.js",
"lib/common/api/deprecate.ts",
"lib/common/api/exports/electron.js",
"lib/common/api/module-list.js",
"lib/common/api/module-list.ts",
"lib/common/api/native-image.js",
"lib/common/api/native-theme.ts",
"lib/common/api/shell.js",
"lib/common/buffer-utils.ts",
"lib/common/clipboard-utils.ts",
"lib/common/crash-reporter.js",
"lib/common/define-properties.ts",
"lib/common/electron-binding-setup.ts",
"lib/common/error-utils.ts",
"lib/common/init.ts",
@@ -280,7 +278,6 @@ auto_filenames = {
"lib/common/parse-features-string.js",
"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",
@@ -292,26 +289,25 @@ auto_filenames = {
"lib/browser/api/module-keys.js",
"lib/common/api/clipboard.js",
"lib/common/api/deprecate.ts",
"lib/common/api/exports/electron.js",
"lib/common/api/module-list.js",
"lib/common/api/module-list.ts",
"lib/common/api/native-image.js",
"lib/common/api/native-theme.ts",
"lib/common/api/shell.js",
"lib/common/buffer-utils.ts",
"lib/common/clipboard-utils.ts",
"lib/common/crash-reporter.js",
"lib/common/define-properties.ts",
"lib/common/electron-binding-setup.ts",
"lib/common/error-utils.ts",
"lib/common/init.ts",
"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.js",
"lib/renderer/api/ipc-renderer.js",
"lib/renderer/api/module-list.js",
"lib/renderer/api/exports/electron.ts",
"lib/renderer/api/ipc-renderer.ts",
"lib/renderer/api/module-list.ts",
"lib/renderer/api/remote.js",
"lib/renderer/api/web-frame.ts",
"lib/renderer/callbacks-registry.ts",
@@ -344,25 +340,24 @@ auto_filenames = {
"lib/browser/api/module-keys.js",
"lib/common/api/clipboard.js",
"lib/common/api/deprecate.ts",
"lib/common/api/exports/electron.js",
"lib/common/api/module-list.js",
"lib/common/api/module-list.ts",
"lib/common/api/native-image.js",
"lib/common/api/native-theme.ts",
"lib/common/api/shell.js",
"lib/common/buffer-utils.ts",
"lib/common/clipboard-utils.ts",
"lib/common/crash-reporter.js",
"lib/common/define-properties.ts",
"lib/common/electron-binding-setup.ts",
"lib/common/error-utils.ts",
"lib/common/init.ts",
"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.js",
"lib/renderer/api/ipc-renderer.js",
"lib/renderer/api/module-list.js",
"lib/renderer/api/exports/electron.ts",
"lib/renderer/api/ipc-renderer.ts",
"lib/renderer/api/module-list.ts",
"lib/renderer/api/remote.js",
"lib/renderer/api/web-frame.ts",
"lib/renderer/callbacks-registry.ts",

View File

@@ -1,6 +1,7 @@
filenames = {
default_app_ts_sources = [
"default_app/default_app.ts",
"default_app/index.ts",
"default_app/main.ts",
"default_app/preload.ts",
]
@@ -46,8 +47,6 @@ filenames = {
"shell/browser/api/atom_api_content_tracing.cc",
"shell/browser/api/atom_api_cookies.cc",
"shell/browser/api/atom_api_cookies.h",
"shell/browser/api/atom_api_data_pipe_holder.cc",
"shell/browser/api/atom_api_data_pipe_holder.h",
"shell/browser/api/atom_api_debugger.cc",
"shell/browser/api/atom_api_debugger.h",
"shell/browser/api/atom_api_dialog.cc",
@@ -64,9 +63,6 @@ filenames = {
"shell/browser/api/atom_api_menu_mac.mm",
"shell/browser/api/atom_api_menu_views.cc",
"shell/browser/api/atom_api_menu_views.h",
"shell/browser/api/atom_api_native_theme.cc",
"shell/browser/api/atom_api_native_theme.h",
"shell/browser/api/atom_api_native_theme_mac.mm",
"shell/browser/api/atom_api_net.cc",
"shell/browser/api/atom_api_net.h",
"shell/browser/api/atom_api_net_log.cc",
@@ -129,6 +125,12 @@ filenames = {
"shell/browser/auto_updater.cc",
"shell/browser/auto_updater.h",
"shell/browser/auto_updater_mac.mm",
"shell/browser/atom_autofill_driver_factory.cc",
"shell/browser/atom_autofill_driver_factory.h",
"shell/browser/atom_autofill_driver.cc",
"shell/browser/atom_autofill_driver.h",
"shell/browser/atom_blob_reader.cc",
"shell/browser/atom_blob_reader.h",
"shell/browser/atom_browser_client.cc",
"shell/browser/atom_browser_client.h",
"shell/browser/atom_browser_context.cc",
@@ -425,6 +427,8 @@ filenames = {
"shell/common/api/atom_api_native_image.cc",
"shell/common/api/atom_api_native_image.h",
"shell/common/api/atom_api_native_image_mac.mm",
"shell/common/api/atom_api_native_theme.cc",
"shell/common/api/atom_api_native_theme.h",
"shell/common/api/atom_api_shell.cc",
"shell/common/api/atom_api_v8_util.cc",
"shell/common/api/electron_bindings.cc",
@@ -433,6 +437,7 @@ filenames = {
"shell/common/api/event_emitter_caller.cc",
"shell/common/api/event_emitter_caller.h",
"shell/common/api/features.cc",
"shell/common/api/gin_utils.h",
"shell/common/api/locker.cc",
"shell/common/api/locker.h",
"shell/common/api/object_life_monitor.cc",
@@ -471,8 +476,17 @@ filenames = {
"shell/common/crash_reporter/win/crash_service_main.cc",
"shell/common/crash_reporter/win/crash_service_main.h",
"shell/common/gin_converters/callback_converter_gin_adapter.h",
"shell/common/gin_converters/gurl_converter_gin_adapter.h",
"shell/common/gin_converters/net_converter_gin_adapter.h",
"shell/common/gin_converters/file_dialog_converter.cc",
"shell/common/gin_converters/file_dialog_converter.h",
"shell/common/gin_converters/file_path_converter.h",
"shell/common/gin_converters/gurl_converter.h",
"shell/common/gin_converters/image_converter.cc",
"shell/common/gin_converters/image_converter.h",
"shell/common/gin_converters/message_box_converter.cc",
"shell/common/gin_converters/message_box_converter.h",
"shell/common/gin_converters/native_window_converter.h",
"shell/common/gin_converters/net_converter.cc",
"shell/common/gin_converters/net_converter.h",
"shell/common/gin_converters/std_converter.h",
"shell/common/gin_converters/value_converter_gin_adapter.h",
"shell/common/gin_util.h",
@@ -483,6 +497,8 @@ filenames = {
"shell/common/keyboard_util.h",
"shell/common/deprecate_util.cc",
"shell/common/deprecate_util.h",
"shell/common/error_util.cc",
"shell/common/error_util.h",
"shell/common/mouse_util.cc",
"shell/common/mouse_util.h",
"shell/common/mac/main_application_bundle.h",
@@ -495,18 +511,14 @@ filenames = {
"shell/common/native_mate_converters/callback.h",
"shell/common/native_mate_converters/content_converter.cc",
"shell/common/native_mate_converters/content_converter.h",
"shell/common/native_mate_converters/file_dialog_converter.cc",
"shell/common/native_mate_converters/file_dialog_converter.h",
"shell/common/native_mate_converters/message_box_converter.cc",
"shell/common/native_mate_converters/message_box_converter.h",
"shell/common/native_mate_converters/file_path_converter.h",
"shell/common/native_mate_converters/gfx_converter.cc",
"shell/common/native_mate_converters/gfx_converter.h",
"shell/common/native_mate_converters/gurl_converter.h",
"shell/common/native_mate_converters/image_converter.cc",
"shell/common/native_mate_converters/image_converter.h",
"shell/common/native_mate_converters/map_converter.h",
"shell/common/native_mate_converters/net_converter.cc",
"shell/common/native_mate_converters/native_window_converter.h",
"shell/common/native_mate_converters/net_converter.h",
"shell/common/native_mate_converters/network_converter.cc",
"shell/common/native_mate_converters/network_converter.h",
@@ -536,10 +548,6 @@ 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.autoHideMenuBar && this.isMenuBarVisible()) {
if (process.platform !== 'darwin' && this.isMenuBarAutoHide() && this.isMenuBarVisible()) {
this.setMenuBarVisibility(false)
}
})

View File

@@ -4,15 +4,29 @@ const { app, BrowserWindow, deprecate } = require('electron')
const binding = process.electronBinding('dialog')
const v8Util = process.electronBinding('v8_util')
const fileDialogProperties = {
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 = {
openFile: 1 << 0,
openDirectory: 1 << 1,
multiSelections: 1 << 2,
createDirectory: 1 << 3,
createDirectory: 1 << 3, // macOS
showHiddenFiles: 1 << 4,
promptToCreate: 1 << 5,
noResolveAliases: 1 << 6,
treatPackageAsDirectory: 1 << 7
promptToCreate: 1 << 5, // Windows
noResolveAliases: 1 << 6, // macOS
treatPackageAsDirectory: 1 << 7, // macOS
dontAddToRecent: 1 << 8 // Windows
}
const normalizeAccessKey = (text) => {
@@ -44,6 +58,18 @@ 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()
@@ -58,6 +84,7 @@ const saveDialog = (sync, window, options) => {
buttonLabel = '',
defaultPath = '',
filters = [],
properties = [],
title = '',
message = '',
securityScopedBookmarks = false,
@@ -72,6 +99,8 @@ 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)
}
@@ -102,20 +131,13 @@ 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 = dialogProperties
settings.properties = setupDialogProperties(DialogType.OPEN, properties)
return (sync) ? binding.showOpenDialogSync(settings) : binding.showOpenDialog(settings)
}

View File

@@ -1,15 +0,0 @@
'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

@@ -0,0 +1,6 @@
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,38 +1,6 @@
import { EventEmitter } from 'events'
import { IpcMainInvokeEvent } from 'electron'
import { IpcMainImpl } from '@electron/internal/browser/ipc-main-impl'
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()
const ipcMain = new IpcMainImpl()
// Do not throw exception when channel name is "error".
ipcMain.on('error', () => {})

View File

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

View File

@@ -1,11 +1,9 @@
'use strict'
// TODO: Updating this file also required updating the module-keys file
const features = process.electronBinding('features')
// Browser side modules, please sort alphabetically.
module.exports = [
export const browserModuleList: ElectronInternal.ModuleEntry[] = [
{ name: 'app', loader: () => require('./app') },
{ name: 'autoUpdater', loader: () => require('./auto-updater') },
{ name: 'BrowserView', loader: () => require('./browser-view') },
@@ -18,7 +16,6 @@ module.exports = [
{ name: 'inAppPurchase', loader: () => require('./in-app-purchase') },
{ name: 'Menu', loader: () => require('./menu') },
{ name: 'MenuItem', loader: () => require('./menu-item') },
{ name: 'nativeTheme', loader: () => require('./native-theme') },
{ name: 'net', loader: () => require('./net') },
{ name: 'netLog', loader: () => require('./net-log') },
{ name: 'Notification', loader: () => require('./notification') },
@@ -37,7 +34,7 @@ module.exports = [
]
if (features.isViewApiEnabled()) {
module.exports.push(
browserModuleList.push(
{ name: 'BoxLayout', loader: () => require('./views/box-layout') },
{ name: 'Button', loader: () => require('./views/button') },
{ name: 'LabelButton', loader: () => require('./views/label-button') },

View File

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

View File

@@ -1,7 +1,12 @@
'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')
@@ -156,7 +161,7 @@ const hookWebContentsEvents = function (webContents) {
// Handle the chrome.* API messages.
let nextId = 0
ipcMainUtils.handle('CHROME_RUNTIME_CONNECT', function (event, extensionId, connectInfo) {
ipcMainUtils.handleSync('CHROME_RUNTIME_CONNECT', function (event, extensionId, connectInfo) {
if (isBackgroundPage(event.sender)) {
throw new Error('chrome.runtime.connect is not supported in background page')
}
@@ -178,7 +183,7 @@ ipcMainUtils.handle('CHROME_RUNTIME_CONNECT', function (event, extensionId, conn
return { tabId, portId }
})
ipcMainUtils.handle('CHROME_EXTENSION_MANIFEST', function (event, extensionId) {
ipcMainUtils.handleSync('CHROME_EXTENSION_MANIFEST', function (event, extensionId) {
const manifest = manifestMap[extensionId]
if (!manifest) {
throw new Error(`Invalid extensionId: ${extensionId}`)
@@ -186,7 +191,7 @@ ipcMainUtils.handle('CHROME_EXTENSION_MANIFEST', function (event, extensionId) {
return manifest
})
ipcMainUtils.handle('CHROME_RUNTIME_SEND_MESSAGE', async function (event, extensionId, message) {
ipcMainInternal.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')
}
@@ -199,7 +204,7 @@ ipcMainUtils.handle('CHROME_RUNTIME_SEND_MESSAGE', async function (event, extens
return ipcMainUtils.invokeInWebContents(page.webContents, true, `CHROME_RUNTIME_ONMESSAGE_${extensionId}`, event.sender.id, message)
})
ipcMainUtils.handle('CHROME_TABS_SEND_MESSAGE', async function (event, tabId, extensionId, message) {
ipcMainInternal.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}`)
@@ -233,7 +238,7 @@ const getMessagesPath = (extensionId) => {
}
}
ipcMainUtils.handle('CHROME_GET_MESSAGES', async function (event, extensionId) {
ipcMainUtils.handleSync('CHROME_GET_MESSAGES', async function (event, extensionId) {
const messagesPath = getMessagesPath(extensionId)
return fs.promises.readFile(messagesPath)
})
@@ -252,7 +257,7 @@ const getChromeStoragePath = (storageType, extensionId) => {
return path.join(app.getPath('userData'), `/Chrome Storage/${extensionId}-${storageType}.json`)
}
ipcMainUtils.handle('CHROME_STORAGE_READ', async function (event, storageType, extensionId) {
ipcMainInternal.handle('CHROME_STORAGE_READ', async function (event, storageType, extensionId) {
const filePath = getChromeStoragePath(storageType, extensionId)
try {
@@ -266,7 +271,7 @@ ipcMainUtils.handle('CHROME_STORAGE_READ', async function (event, storageType, e
}
})
ipcMainUtils.handle('CHROME_STORAGE_WRITE', async function (event, storageType, extensionId, data) {
ipcMainInternal.handle('CHROME_STORAGE_WRITE', async function (event, storageType, extensionId, data) {
const filePath = getChromeStoragePath(storageType, extensionId)
try {
@@ -291,7 +296,7 @@ const assertChromeExtension = function (contents, api) {
}
}
ipcMainUtils.handle('CHROME_TABS_EXECUTE_SCRIPT', async function (event, tabId, extensionId, details) {
ipcMainInternal.handle('CHROME_TABS_EXECUTE_SCRIPT', async function (event, tabId, extensionId, details) {
assertChromeExtension(event.sender, 'chrome.tabs.executeScript()')
const contents = webContents.fromId(tabId)

View File

@@ -19,13 +19,7 @@ export const getSources = (event: Electron.IpcMainEvent, options: ElectronIntern
}
const getSources = new Promise<ElectronInternal.GetSourcesResult[]>((resolve, reject) => {
let capturer: ElectronInternal.DesktopCapturer | null = createDesktopCapturer()
const stopRunning = () => {
if (capturer) {
capturer.emit = null
capturer = null
}
// Remove from currentlyRunning once we resolve or reject
currentlyRunning = currentlyRunning.filter(running => running.options !== options)
}
@@ -48,13 +42,19 @@ export const getSources = (event: Electron.IpcMainEvent, options: ElectronIntern
})))
})
let capturer: ElectronInternal.DesktopCapturer | null = createDesktopCapturer()
capturer.emit = emitter.emit.bind(emitter)
capturer.startHandling(options.captureWindow, options.captureScreen, options.thumbnailSize, options.fetchWindowIcons)
// If the WebContents is destroyed before receiving result, just remove the
// reference to emit and the capturer itself so that it never dispatches
// back to the renderer
event.sender.once('destroyed', () => stopRunning())
event.sender.once('destroyed', () => {
capturer!.emit = null
capturer = null
stopRunning()
})
})
currentlyRunning.push({

View File

@@ -2,7 +2,8 @@ import { dialog, Menu } from 'electron'
import * as fs from 'fs'
import * as url from 'url'
const ipcMainUtils = require('@electron/internal/browser/ipc-main-internal-utils')
import { ipcMainInternal } from '@electron/internal/browser/ipc-main-internal'
import * as ipcMainUtils from '@electron/internal/browser/ipc-main-internal-utils'
const convertToMenuTemplate = function (items: ContextMenuItem[], handler: (id: number) => void) {
return items.map(function (item) {
@@ -59,7 +60,7 @@ const assertChromeDevTools = function (contents: Electron.WebContents, api: stri
}
}
ipcMainUtils.handle('ELECTRON_INSPECTOR_CONTEXT_MENU', function (event: Electron.IpcMainEvent, items: ContextMenuItem[], isEditMenu: boolean) {
ipcMainInternal.handle('ELECTRON_INSPECTOR_CONTEXT_MENU', function (event: Electron.IpcMainInvokeEvent, items: ContextMenuItem[], isEditMenu: boolean) {
return new Promise(resolve => {
assertChromeDevTools(event.sender, 'window.InspectorFrontendHost.showContextMenuAtPoint()')
@@ -71,7 +72,7 @@ ipcMainUtils.handle('ELECTRON_INSPECTOR_CONTEXT_MENU', function (event: Electron
})
})
ipcMainUtils.handle('ELECTRON_INSPECTOR_SELECT_FILE', async function (event: Electron.IpcMainEvent) {
ipcMainInternal.handle('ELECTRON_INSPECTOR_SELECT_FILE', async function (event: Electron.IpcMainInvokeEvent) {
assertChromeDevTools(event.sender, 'window.UI.createFileSelectorElement()')
const result = await dialog.showOpenDialog({})
@@ -83,7 +84,7 @@ ipcMainUtils.handle('ELECTRON_INSPECTOR_SELECT_FILE', async function (event: Ele
return [path, data]
})
ipcMainUtils.handle('ELECTRON_INSPECTOR_CONFIRM', async function (event: Electron.IpcMainEvent, message: string = '', title: string = '') {
ipcMainUtils.handleSync('ELECTRON_INSPECTOR_CONFIRM', async function (event: Electron.IpcMainInvokeEvent, 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.zoomFactor,
zoomFactor: embedder.getZoomFactor(),
disablePopups: !params.allowpopups,
webSecurity: !params.disablewebsecurity,
enableBlinkFeatures: params.blinkfeatures,
@@ -312,21 +312,33 @@ const isWebViewTagEnabled = function (contents) {
return isWebViewTagEnabledCache.get(contents)
}
const handleMessage = function (channel, handler) {
ipcMainUtils.handle(channel, (event, ...args) => {
const makeSafeHandler = function (channel, handler) {
return (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)
@@ -345,11 +357,18 @@ 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 (!allMethods.has(method)) {
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)) {
throw new Error(`Invalid method: ${method}`)
}

View File

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

View File

@@ -152,7 +152,9 @@ app._setDefaultAppPaths(packagePath)
require('@electron/internal/browser/devtools')
// Load the chrome extension support.
require('@electron/internal/browser/chrome-extension')
if (!process.electronBinding('features').isExtensionsEnabled()) {
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

@@ -0,0 +1,33 @@
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,26 +1,15 @@
import { ipcMainInternal } from '@electron/internal/browser/ipc-main-internal'
import * as errorUtils from '@electron/internal/common/error-utils'
type IPCHandler = (event: ElectronInternal.IpcMainInternalEvent, ...args: any[]) => any
type IPCHandler = (event: Electron.IpcMainInvokeEvent, ...args: any[]) => any
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
}
})
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)]
}
})
}

View File

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

View File

@@ -127,10 +127,6 @@ 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

@@ -9,7 +9,6 @@ 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')
@@ -231,7 +230,7 @@ const unwrapArgs = function (sender, frameId, contextId, args) {
v8Util.setHiddenValue(callIntoRenderer, 'location', meta.location)
Object.defineProperty(callIntoRenderer, 'length', { value: meta.length })
v8Util.setRemoteCallbackFreer(callIntoRenderer, frameId, contextId, meta.id, sender)
v8Util.setRemoteCallbackFreer(callIntoRenderer, contextId, meta.id, sender)
rendererFunctions.set(objectId, callIntoRenderer)
return callIntoRenderer
}
@@ -242,11 +241,16 @@ const unwrapArgs = function (sender, frameId, contextId, args) {
return args.map(metaToValue)
}
const isRemoteModuleEnabledImpl = function (contents) {
const webPreferences = contents.getLastWebPreferences() || {}
return !!webPreferences.enableRemoteModule
}
const isRemoteModuleEnabledCache = new WeakMap()
const isRemoteModuleEnabled = function (contents) {
if (!isRemoteModuleEnabledCache.has(contents)) {
isRemoteModuleEnabledCache.set(contents, contents._isRemoteModuleEnabled())
isRemoteModuleEnabledCache.set(contents, isRemoteModuleEnabledImpl(contents))
}
return isRemoteModuleEnabledCache.get(contents)
@@ -444,6 +448,7 @@ handleRemoteCommand('ELECTRON_BROWSER_DEREFERENCE', function (event, contextId,
handleRemoteCommand('ELECTRON_BROWSER_CONTEXT_RELEASE', (event, contextId) => {
objectsRegistry.clear(event.sender, contextId)
return null
})
handleRemoteCommand('ELECTRON_BROWSER_GUEST_WEB_CONTENTS', function (event, contextId, guestInstanceId) {
@@ -471,11 +476,11 @@ ipcMainInternal.on('ELECTRON_BROWSER_WINDOW_CLOSE', function (event) {
event.returnValue = null
})
ipcMainUtils.handle('ELECTRON_CRASH_REPORTER_INIT', function (event, options) {
ipcMainUtils.handleSync('ELECTRON_CRASH_REPORTER_INIT', function (event, options) {
return crashReporterInit(options)
})
ipcMainUtils.handle('ELECTRON_BROWSER_GET_LAST_WEB_PREFERENCES', function (event) {
ipcMainInternal.handle('ELECTRON_BROWSER_GET_LAST_WEB_PREFERENCES', function (event) {
return event.sender.getLastWebPreferences()
})
@@ -491,7 +496,7 @@ const allowedClipboardMethods = (() => {
}
})()
ipcMainUtils.handle('ELECTRON_BROWSER_CLIPBOARD', function (event, method, ...args) {
ipcMainUtils.handleSync('ELECTRON_BROWSER_CLIPBOARD', function (event, method, ...args) {
if (!allowedClipboardMethods.has(method)) {
throw new Error(`Invalid method: ${method}`)
}
@@ -502,7 +507,7 @@ ipcMainUtils.handle('ELECTRON_BROWSER_CLIPBOARD', function (event, method, ...ar
if (features.isDesktopCapturerEnabled()) {
const desktopCapturer = require('@electron/internal/browser/desktop-capturer')
ipcMainUtils.handle('ELECTRON_BROWSER_DESKTOP_CAPTURER_GET_SOURCES', function (event, ...args) {
ipcMainInternal.handle('ELECTRON_BROWSER_DESKTOP_CAPTURER_GET_SOURCES', function (event, ...args) {
const customEvent = emitCustomEvent(event.sender, 'desktop-capturer-get-sources')
if (customEvent.defaultPrevented) {
@@ -525,13 +530,24 @@ const getPreloadScript = async function (preloadPath) {
return { preloadPath, preloadSrc, preloadError }
}
ipcMainUtils.handle('ELECTRON_GET_CONTENT_SCRIPTS', () => getContentScripts())
if (process.electronBinding('features').isExtensionsEnabled()) {
ipcMainUtils.handleSync('ELECTRON_GET_CONTENT_SCRIPTS', () => [])
} else {
const { getContentScripts } = require('@electron/internal/browser/chrome-extension')
ipcMainUtils.handleSync('ELECTRON_GET_CONTENT_SCRIPTS', () => getContentScripts())
}
ipcMainUtils.handle('ELECTRON_BROWSER_SANDBOX_LOAD', async function (event) {
ipcMainUtils.handleSync('ELECTRON_BROWSER_SANDBOX_LOAD', async function (event) {
const preloadPaths = event.sender._getPreloadPaths()
let contentScripts = []
if (!process.electronBinding('features').isExtensionsEnabled()) {
const { getContentScripts } = require('@electron/internal/browser/chrome-extension')
contentScripts = getContentScripts()
}
return {
contentScripts: getContentScripts(),
contentScripts,
preloadScripts: await Promise.all(preloadPaths.map(path => getPreloadScript(path))),
isRemoteModuleEnabled: isRemoteModuleEnabled(event.sender),
isWebViewTagEnabled: guestViewManager.isWebViewTagEnabled(event.sender),

View File

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

View File

@@ -8,8 +8,6 @@
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'
@@ -42,6 +40,8 @@
return newArchive
}
const ASAR_EXTENSION = '.asar'
// Separate asar package's path from full path.
const splitPath = archivePathOrBuffer => {
// Shortcut for disabled asar.
@@ -54,7 +54,22 @@
}
if (typeof archivePath !== 'string') return { isAsar: false }
return asar.splitPath(path.normalize(archivePath))
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)
}
}
// Convert asar archive's Stats object to fs's Stats object.

View File

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

View File

@@ -1,8 +0,0 @@
// 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

@@ -1,20 +0,0 @@
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 * as ipcRendererUtils from '@electron/internal/renderer/ipc-renderer-internal-utils'
import { ipcRendererInternal } from '@electron/internal/renderer/ipc-renderer-internal'
// |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 ipcRendererUtils.invoke<ElectronInternal.GetSourcesResult[]>('ELECTRON_BROWSER_DESKTOP_CAPTURER_GET_SOURCES', {
const sources = await ipcRendererInternal.invoke<ElectronInternal.GetSourcesResult[]>('ELECTRON_BROWSER_DESKTOP_CAPTURER_GET_SOURCES', {
captureWindow,
captureScreen,
thumbnailSize,

View File

@@ -1,14 +0,0 @@
'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

@@ -0,0 +1,6 @@
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,10 +1,8 @@
'use strict'
const { ipc } = process.electronBinding('ipc')
const v8Util = process.electronBinding('v8_util')
// Created by init.js.
const ipcRenderer = v8Util.getHiddenValue(global, 'ipc')
const ipcRenderer = v8Util.getHiddenValue<Electron.IpcRenderer>(global, 'ipc')
const internal = false
ipcRenderer.send = function (channel, ...args) {
@@ -23,15 +21,12 @@ ipcRenderer.sendTo = function (webContentsId, channel, ...args) {
return ipc.sendTo(internal, false, webContentsId, channel, args)
}
ipcRenderer.sendToAll = function (webContentsId, channel, ...args) {
return ipc.sendTo(internal, true, 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.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
export default ipcRenderer

View File

@@ -1,23 +1,19 @@
'use strict'
const features = process.electronBinding('features')
const v8Util = process.electronBinding('v8_util')
const enableRemoteModule = v8Util.getHiddenValue(global, 'enableRemoteModule')
const enableRemoteModule = v8Util.getHiddenValue<boolean>(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') },
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()) {
module.exports.push({ name: 'desktopCapturer', loader: () => require('./desktop-capturer') })
rendererModuleList.push({ name: 'desktopCapturer', loader: () => require('./desktop-capturer') })
}
if (enableRemoteModule) {
module.exports.push({ name: 'remote', loader: () => require('./remote') })
rendererModuleList.push({ name: 'remote', loader: () => require('./remote') })
}

View File

@@ -20,7 +20,7 @@ const contextId = v8Util.getHiddenValue(global, 'contextId')
// to guard that situation.
process.on('exit', () => {
const command = 'ELECTRON_BROWSER_CONTEXT_RELEASE'
ipcRendererInternal.send(command, contextId)
ipcRendererInternal.sendSync(command, contextId)
})
// Convert the arguments object into an array of meta data.
@@ -349,9 +349,8 @@ const addBuiltinProperty = (name) => {
})
}
const browserModules =
require('@electron/internal/common/api/module-list').concat(
require('@electron/internal/browser/api/module-keys'))
const { commonModuleList } = require('@electron/internal/common/api/module-list')
const browserModules = commonModuleList.concat(require('@electron/internal/browser/api/module-keys'))
// And add a helper receiver for each one.
browserModules

View File

@@ -67,6 +67,10 @@ 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}`, (
@@ -116,11 +120,7 @@ export function injectTo (extensionId: string, context: any) {
let targetExtensionId = extensionId
let connectInfo = { name: '' }
if (args.length === 1) {
if (typeof args[0] === 'string') {
targetExtensionId = args[0]
} else {
connectInfo = args[0]
}
targetExtensionId = 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')
}
ipcRendererUtils.invoke('CHROME_RUNTIME_SEND_MESSAGE', targetExtensionId, message).then(responseCallback)
ipcRendererInternal.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 = () => {}
) {
ipcRendererUtils.invoke('CHROME_TABS_EXECUTE_SCRIPT', tabId, extensionId, details)
ipcRendererInternal.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 = () => {}
) {
ipcRendererUtils.invoke('CHROME_TABS_SEND_MESSAGE', tabId, extensionId, message).then(responseCallback)
ipcRendererInternal.invoke('CHROME_TABS_SEND_MESSAGE', tabId, extensionId, message).then(responseCallback)
},
onUpdated: new Event(),

View File

@@ -1,9 +1,9 @@
import * as ipcRendererUtils from '@electron/internal/renderer/ipc-renderer-internal-utils'
import { ipcRendererInternal } from '@electron/internal/renderer/ipc-renderer-internal'
const getStorage = (storageType: string, extensionId: number, callback: Function) => {
if (typeof callback !== 'function') throw new TypeError('No callback provided')
ipcRendererUtils.invoke<string>('CHROME_STORAGE_READ', storageType, extensionId)
ipcRendererInternal.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)
ipcRendererUtils.invoke('CHROME_STORAGE_WRITE', storageType, extensionId, json)
ipcRendererInternal.invoke('CHROME_STORAGE_WRITE', storageType, extensionId, json)
.then(() => {
if (callback) callback()
})

View File

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

View File

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

View File

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

View File

@@ -4,38 +4,18 @@ 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, (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)
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))
}
})
}
export function invokeSync<T> (command: string, ...args: any[]): T {
const [ error, result ] = ipcRendererInternal.sendSync(command, null, ...args)
const [ error, result ] = ipcRendererInternal.sendSync(command, ...args)
if (error) {
throw errorUtils.deserialize(error)

View File

@@ -1,22 +1,30 @@
const binding = process.electronBinding('ipc')
const { ipc } = process.electronBinding('ipc')
const v8Util = process.electronBinding('v8_util')
// Created by init.js.
export const ipcRendererInternal: Electron.IpcRendererInternal = v8Util.getHiddenValue(global, 'ipc-internal')
export const ipcRendererInternal = v8Util.getHiddenValue<Electron.IpcRendererInternal>(global, 'ipc-internal')
const internal = true
ipcRendererInternal.send = function (channel, ...args) {
return binding.ipc.send(internal, channel, args)
return ipc.send(internal, channel, args)
}
ipcRendererInternal.sendSync = function (channel, ...args) {
return binding.ipc.sendSync(internal, channel, args)[0]
return ipc.sendSync(internal, channel, args)[0]
}
ipcRendererInternal.sendTo = function (webContentsId, channel, ...args) {
return binding.ipc.sendTo(internal, false, webContentsId, channel, args)
return ipc.sendTo(internal, false, webContentsId, channel, args)
}
ipcRendererInternal.sendToAll = function (webContentsId, channel, ...args) {
return binding.ipc.sendTo(internal, true, 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
}

View File

@@ -1,5 +1,5 @@
import { webFrame } from 'electron'
import { invoke } from '@electron/internal/renderer/ipc-renderer-internal-utils'
import { ipcRendererInternal } from '@electron/internal/renderer/ipc-renderer-internal'
let shouldLog: boolean | null = null
@@ -299,7 +299,7 @@ const logSecurityWarnings = function (
const getWebPreferences = async function () {
try {
return invoke<Electron.WebPreferences>('ELECTRON_BROWSER_GET_LAST_WEB_PREFERENCES')
return ipcRendererInternal.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 { invoke, invokeSync } from '@electron/internal/renderer/ipc-renderer-internal-utils'
import * as ipcRendererUtils 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 invoke('ELECTRON_GUEST_VIEW_MANAGER_CREATE_GUEST', params)
return ipcRendererInternal.invoke('ELECTRON_GUEST_VIEW_MANAGER_CREATE_GUEST', params)
}
export function createGuestSync (params: Record<string, any>): number {
return invokeSync('ELECTRON_GUEST_VIEW_MANAGER_CREATE_GUEST', params)
return ipcRendererUtils.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')
}
invoke('ELECTRON_GUEST_VIEW_MANAGER_ATTACH_GUEST', embedderFrameId, elementInstanceId, guestInstanceId, params)
ipcRendererInternal.invoke('ELECTRON_GUEST_VIEW_MANAGER_ATTACH_GUEST', embedderFrameId, elementInstanceId, guestInstanceId, params)
}
export const guestViewInternalModule = {

View File

@@ -1,4 +1,4 @@
import * as ipcRendererUtils from '@electron/internal/renderer/ipc-renderer-internal-utils'
import { ipcRendererInternal } from '@electron/internal/renderer/ipc-renderer-internal'
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]
ipcRendererUtils.invoke('ELECTRON_GUEST_VIEW_MANAGER_CALL', guestInstanceId, method, args)
ipcRendererInternal.invoke('ELECTRON_GUEST_VIEW_MANAGER_CALL', guestInstanceId, method, args)
}
}

View File

@@ -1,5 +1,6 @@
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'
@@ -253,7 +254,7 @@ export const setupMethods = (WebViewElement: typeof ElectronInternal.WebViewElem
const createNonBlockHandler = function (method: string) {
return function (this: ElectronInternal.WebViewElement, ...args: Array<any>) {
return ipcRendererUtils.invoke('ELECTRON_GUEST_VIEW_MANAGER_CALL', this.getWebContentsId(), method, args)
return ipcRendererInternal.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 ipcRendererUtils.invoke('ELECTRON_GUEST_WINDOW_MANAGER_WEB_CONTENTS_METHOD', this.guestId, method, ...args)
return ipcRendererInternal.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) {
ipcRendererUtils.invoke('ELECTRON_GUEST_WINDOW_MANAGER_WINDOW_POSTMESSAGE', this.guestId, message, toString(targetOrigin), window.location.origin)
ipcRendererInternal.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 ipcRendererUtils.invoke('ELECTRON_GUEST_WINDOW_MANAGER_WINDOW_METHOD', this.guestId, method, ...args)
return ipcRendererInternal.invoke('ELECTRON_GUEST_WINDOW_MANAGER_WINDOW_METHOD', this.guestId, method, ...args)
}
private _invokeWebContentsMethod (method: string, ...args: any[]) {
return ipcRendererUtils.invoke('ELECTRON_GUEST_WINDOW_MANAGER_WEB_CONTENTS_METHOD', this.guestId, method, ...args)
return ipcRendererInternal.invoke('ELECTRON_GUEST_WINDOW_MANAGER_WEB_CONTENTS_METHOD', this.guestId, method, ...args)
}
}

View File

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

View File

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

View File

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

View File

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

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