Compare commits

...

163 Commits

Author SHA1 Message Date
Electron Bot
5be9dcad46 Bump v12.0.0-nightly.20201006 2020-10-06 07:31:08 -07:00
Milan Burda
db911f29ad refactor: remove duplicate <webview> event list (#25697) 2020-10-06 15:11:26 +02:00
marcin-prochownik
8207f6901d fix: access violation during redirects (intercepted requests) (#25393)
* fix: don't delete loader factory when request is pending

When intercepted request is pending we need to make sure that
loader factory is not deleted, especially when redirect occurs.
Otherwise, it may cause access violation.

* fix: added logic that removes requests from collection

* fix: fixed lint errors

* fix: fixed review remark

* fix: fixed review remarks

Removed intercepted_requests_ collection
and leverage pending_receivers_.

* fix: brought back removed line
2020-10-06 16:20:56 +09:00
Egor Stronhin
125c5a6e9b docs: end listener must be placed before data listener (#25568) 2020-10-06 10:27:30 +09:00
Milan Burda
b33f22601e refactor: check ELECTRON_ENABLE_LOGGING via native implementation (#25623) 2020-10-06 09:58:31 +09:00
marcin-prochownik
fec1c0b68b fix: passing content-length down the stream for intercepted requests (#25324)
* fix: pass content length if avilable in headers

* fix: fixed unit test after changes

	video is being played for standard scheme when
	content-length is available

* fix: fixed review remakrs

added is_string check and changed stol to StringToInt64

* fix: fix test case name

* fix: fixed typo
2020-10-06 09:53:13 +09:00
Keeley Hammond
6356cd4018 fix: allow ClientRequest responses to be throttled (#25531)
* fix: allow net streams to be throttled [WIP]

* fix: handle resume throttling within IncomingMessage [WIP]

* fix: fix urlLoader typing, add throttle test

* fix: fix lint and increase test timeout for Linux

* fix: increase test chunk limit to 20 and timeout to 2000

Co-authored-by: Jeremy Rose <nornagon@nornagon.net>
2020-10-06 09:47:41 +09:00
David Sanders
53ee708fe8 build: python3 compat and fix line endings on Win (#25767) 2020-10-06 09:40:04 +09:00
Asher Jacob
cba19f06f1 docs: added additional instructions to RUN the application (#25743)
In the existing documentation only "npm start" is given as the
instruction to run the project, however the definition of the 'start'
script is not mentioned anywhere. Hence I feel it is important for the
users to know the exact contents of the 'start' scirpt and have
accordingly updated the documentation.
2020-10-05 13:34:35 -07:00
David Sanders
ee9045c2e7 docs: trim trailing whitespace (#25768) 2020-10-05 13:01:40 -07:00
Cheng Zhao
57dc170e81 fix: no more need to hijack process.stdout on Win32 (#25765) 2020-10-05 10:10:38 -07:00
David Sanders
9717dff4fa docs: link ProtocolRequest doc (#25761) 2020-10-05 11:18:18 -04:00
David Sanders
bbdca48cdb fix: output Unix-style paths for git diffs on Win (#25763) 2020-10-05 10:40:40 -04:00
David Sanders
818751ff87 build: fix typos in script messages (#25766) 2020-10-05 10:38:50 -04:00
Erick Zhao
15d7d4b40f docs: add Discord Server to README (#25751) 2020-10-05 10:36:53 -04:00
Electron Bot
30465790b5 Bump v12.0.0-nightly.20201005 2020-10-05 07:32:53 -07:00
David Sanders
c075d14920 fix: python3 compatibility (#25762) 2020-10-05 15:00:35 +09:00
Chris Patterson
4ccc9e4205 docs: update snapcraft tutorial background information (#25747)
- Remove outdated comment about macOS.
- Refer to Snapcraft's installation documentation for up-to-date installation instructions.
2020-10-05 15:00:23 +09:00
Cody
77e2e47504 docs: fix spelling error in updates tutorial (#25725) 2020-10-05 14:59:24 +09:00
Milan Burda
508b8d902b chore: move remote module fixtures for easier deletion when removed (#25736) 2020-10-05 10:22:35 +09:00
Jeremy Rose
485adae94c fix: nativeImage.crop().toBitmap() returning garbage (#25757) 2020-10-05 10:15:16 +09:00
Samuel Attard
a189dc779e feat: add webContents.forcefullyCrashRenderer() to forcefully terminate a renderer process (#25580)
* feat: add webContents.forcefullyCrashRenderer() to forcefully terminate a renderer process

* chore: fix up docs and tests
2020-10-02 14:50:24 -07:00
Jeremy Rose
d64b9c20bd build: fix mergeShasums (#25752) 2020-10-02 13:26:29 -07:00
Samuel Attard
ac6bf0b268 build: use https for sysroot download (#25754) 2020-10-02 13:25:30 -07:00
Shelley Vohr
8ac71fd349 chore: fix nmv for Electron v12 (#25749) 2020-10-02 12:50:56 -07:00
Milan Burda
e1a19d735e chore: convert guest-window-manager.js to TypeScript (#25709) 2020-10-02 20:18:42 +02:00
Electron Bot
7e88585bfb Bump v12.0.0-nightly.20201002 2020-10-02 07:32:53 -07:00
Milan Burda
8df4faa8f0 chore: cleanup typings/internal-electron.d.ts (#25711) 2020-10-02 04:52:29 +02:00
Milan Burda
17c7c5cfdd fix: crash when application launched from UNUserNotificationCenter notification (#25702) 2020-10-02 04:52:07 +02:00
Milan Burda
5387b5b9b2 docs: rename launch-failure -> launch-failed to match C++ code (#25726) 2020-10-01 22:34:42 +02:00
Jeremy Rose
822b044068 fix: suppress worldSafe warning emitted from security checks (#25692) 2020-10-01 08:59:52 -07:00
Electron Bot
e2132acc5c Bump v12.0.0-nightly.20201001 2020-10-01 07:32:02 -07:00
Samuel Attard
3142b1181b build: move to ACR for docker image storage (#25710) 2020-09-30 15:25:27 -07:00
Jeremy Rose
7027217dbb build: use aws-sdk-js instead of boto (#25693) 2020-09-30 13:30:10 -07:00
Robert Borg
e9876aecf9 fix: gdi printing in silent printing mode (#25679)
for windows print_text_with_gdi is set to the value of is_modifiable
but this code path is not taken for silent printing
2020-09-30 11:42:57 -07:00
John Kleinschmidt
077c37c682 ci: fixup doc only check on Windows (#25700) 2020-09-30 14:36:44 -04:00
John Kleinschmidt
4316c4125f chore: force homebrew cache to update (#25703) 2020-09-30 13:47:25 -04:00
Charles Kerr
2b3b3fea2e chore: fix package.json reference to atom directory (#25682) 2020-09-30 08:58:45 -07:00
Electron Bot
a8d542337c Bump v12.0.0-nightly.20200930 2020-09-30 07:32:17 -07:00
Samuel Maddock
462de5f97a chore(extensions): remove unused features json (#25660) 2020-09-29 20:03:35 -07:00
bitdisaster
b43859f098 feat: custom toast xml and failure reporting for notifications (#25401)
* allow custom toast xml and report failures

* docs

* tests

* don't use namespaces

* lint doesn't like trailing commas

* addressing feedback
2020-09-29 12:20:10 -07:00
Cheng Zhao
d2282ac51a fix: submenu should be autoreleased (#25617) 2020-09-29 12:56:46 -04:00
Valentin Hăloiu
01dc50d829 refactor: use chromium x11 error handler (#25611) 2020-09-29 12:05:34 -04:00
Jeremy Rose
0e7d59dd79 feat: [net] add "credentials" option to net.request (#25284)
* feat: [net] add "credentials" option to net.request

* remove debugging log

* add tests
2020-09-29 12:03:33 -04:00
Cheng Zhao
8970c80520 docs: command line flags for GPU controls (#25589) 2020-09-29 11:49:09 -04:00
Shelley Vohr
99a4284174 refactor: remove unnecessary copied helper (#25668) 2020-09-29 11:40:31 -04:00
Electron Bot
f3c53c1f10 Bump v12.0.0-nightly.20200929 2020-09-29 07:31:26 -07:00
John Kleinschmidt
ebc7d54765 chore: add got for release script (#25671)
* chore: add got for release script

* Use same version of got we used to use
2020-09-28 21:10:28 -04:00
CezaryKulakowski
b85195ee5f fix: ensure ready-to-show event is fired (#25632) 2020-09-28 13:36:45 -07:00
Jeremy Rose
ac25f4d2ff docs: clarify example in message-channel-main (#25625) 2020-09-28 10:58:32 -07:00
John Kleinschmidt
fd63510ca9 feat: add serial api support (#25237)
* feat: add serial api support

resolves #22478

* Put serial port support behind a flag and mark as experimental

* Update docs/api/session.md

Co-authored-by: Jeremy Rose <jeremya@chromium.org>

* Use enable-blink-features=Serial instead of enable-experimental-web-platform-features

* Set enableBlinkFeatures on webPreferences instead of commandline

Co-authored-by: Jeremy Rose <jeremya@chromium.org>
2020-09-28 12:22:03 -04:00
Electron Bot
bed50bb73c Bump v12.0.0-nightly.20200928 2020-09-28 07:32:56 -07:00
Shelley Vohr
69ee443c50 fix: crash in printing on Windows (#25622) 2020-09-27 19:00:05 -07:00
Electron Bot
4c9638e2b5 Bump v12.0.0-nightly.20200925 2020-09-25 07:31:34 -07:00
Jeremy Rose
3ceaf4aa54 docs: document process.crashReporter apis in node children (#25579) 2020-09-24 08:22:50 -07:00
Milan Burda
1f856c25a9 chore: improve renderer crash logging (#25592) 2020-09-24 08:22:17 -07:00
Electron Bot
dcd6e1f2b8 Bump v12.0.0-nightly.20200924 2020-09-24 07:32:22 -07:00
Shelley Vohr
b807cabe1b chore: remove custom Node.js debugger (#25587) 2020-09-23 20:35:56 -07:00
Electron Bot
b980d1bd6b chore: bump node in DEPS to v14.12.0 (#25593) 2020-09-23 19:24:34 -07:00
Joe Duncko
6fb7066904 docs: pepper flash plugin info appears at chrome://version now (#25445)
`chrome://flash` doesn't seem to exist anymore, but similar information
appears at `chrome://version`.
2020-09-23 13:25:27 -07:00
Jeremy Rose
27ea3fc069 feat: allow setting SSL config (#25461)
* feat: allow setting SSL config

* lint

* configure system network context with min TLS1.2

* fix

* note defaults
2020-09-23 16:22:10 -04:00
Charles Kerr
515e85079f chore: fix minor script warnings (#25575) 2020-09-23 13:21:34 -07:00
Shelley Vohr
353c63e47a build: fix Node.js filename generation (#25577) 2020-09-23 12:48:23 -07:00
Samuel Maddock
9d0d9a1664 feat(extensions): expose ExtensionRegistryObserver events in Session (#25385)
* feat(extensions): expose ExtensionRegistryObserver events in Session

Extensions can be loaded and unloaded for various reasons. In some cases this can
occur by no means of the Electron programmer, such as in the case of chrome.runtime.reload().

In order to be able to manage state about extensions outside of Electron's APIs, events
reloaded to loading and unloaded are needed.

* docs(extensions): elaborate on extension-loaded/unloaded details

* fix: remove scoped extension registry observer

* docs: update extension-unloaded
2020-09-23 15:29:08 -04:00
Jeremy Rose
881ac995da fix: decompress devtools discovery html (#25576) 2020-09-23 11:47:44 -07:00
Samuel Attard
3503d3745b fix: order menu items before filtering excess separators (#25563) 2020-09-23 10:39:08 -07:00
Electron Bot
a0b238a998 Bump v12.0.0-nightly.20200923 2020-09-23 07:31:26 -07:00
liulun
6aaaabd90f docs: add more info about downloadItem.setSavePath api (#25402)
* docs: add more info about downloadItem.setSavePath api

add more info about downloadItem.setSavePath api

* Update docs/api/download-item.md

^_^

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

Co-authored-by: Samuel Attard <samuel.r.attard@gmail.com>
2020-09-23 11:02:05 +09:00
Cheng Zhao
22c6c891be fix: unsubscribe from observers when window is closing (#25554) 2020-09-23 10:53:32 +09:00
Milan Burda
29c6864ee1 docs: remove unused StreamProtocolResponse / StringProtocolResponse (#25573) 2020-09-23 10:48:22 +09:00
Jaroslav Maslo
4f54d71518 docs: fix incorrect dialog.showMessageBox() docs (#25549) 2020-09-23 10:35:00 +09:00
dmitryk
0d72bf3ed2 docs: remove deprecated options for the findInPage method. (#25574) 2020-09-22 11:55:56 -07:00
Shelley Vohr
6acf34fa4c feat: add macOS fast user switching evt (#25321) 2020-09-22 10:12:39 -07:00
Electron Bot
f6f05c34e6 Bump v12.0.0-nightly.20200922 2020-09-22 07:32:18 -07:00
Electron Bot
d2a82dbd1d chore: bump node to v14.11.0 (master) (#25489) 2020-09-22 07:11:56 -07:00
Samuel Attard
dae60e01d4 build: use newer xCode image (#25564)
* build: use newer xCode image

* build: log changed file paths
2020-09-22 02:19:00 -07:00
Cheng Zhao
c50ded2b71 feat: add BrowserWindow.isTabletMode API (#25209) 2020-09-22 14:40:42 +09:00
Samuel Attard
2dd7ad268b build: add --only support to the nan test runner (#25560) 2020-09-21 16:37:14 -07:00
Shelley Vohr
15c30c5649 fix: check printer list when no default printers (#25515) 2020-09-21 13:42:27 -07:00
Michaela Laurencin
ea76788b67 refactor: remove native_browser_view web contents get function (#25526) 2020-09-21 10:39:58 -07:00
Electron Bot
a80c35d161 Bump v12.0.0-nightly.20200921 2020-09-21 07:32:16 -07:00
Electron Bot
69f1731bbb chore: bump chromium to ec5bc1743792d64724693eb357083 (master) (#24984)
* chore: bump chromium in DEPS to cbdeef954dfc34e94c8ca9cf72ad326b4a121158

* chore: bump chromium in DEPS to 29723f905baeab1d4228eef2c31cdb341ebeffe0

* chore: bump chromium in DEPS to 44d6d78e852137fff58c14ed26ab1e803e5bf822

* update patches

* chore: bump chromium in DEPS to 8a3a0fccb39d6b8334c9a0496c0d5056e50cdb3f

* chore: update patches

* refactor: fix PrintBackend::CreateInstance() calls

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

* chore: bump chromium in DEPS to b9ebec3bcb1cabdd1426f367636f54cc98e0500e

* chore: remove patches to code that was deleted upstream

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

* Remove uses of kCGColorSpaceITUR_2020_PQ_EOTF/HLG

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

just garden variety code shear

* chore: update patch indices

* Move ColorModel to //printing/mojom/print.mojom

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

sync with printing ColorModel changes: moved to mojo, different naming scheme

* chore: bump chromium in DEPS to 56c4b4d2ce5ba941acd2e0fdb5100e8a48847134

* chore: bump chromium in DEPS to 130501f220b684a79dc82c17e236e63ac1f2a093

* Convert PrintHostMsg_DidGetPrintedPagesCount to Mojo

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

Update argument list to Print()

* chore: update patch indices

* DumpAccTree: convert utf16 to utf8 in PropertyFilter

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

* chore: bump chromium in DEPS to 3058368c6646e0dc8be6f8ea838b0343428b7998

* chore: bump chromium in DEPS to f51b4e6555364363c61438dac7afd988c8347bfc

* chore: bump chromium in DEPS to 2dcc6f8fc23ac41b2499eb69dee0b4017e9d1046

* update patches

* chore: bump chromium in DEPS to 2d8e98ecedc7e4905540b053bc1c87e964715be5

* update patches

* 2345900: Move content::RecordContentToVisibleTimeRequest struct to mojo

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

* update patches

* 2345900: Move content::RecordContentToVisibleTimeRequest struct to mojo

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

* 2367394: Remove net::LOAD_DO_NOT_SEND_COOKIES and net::LOAD_DO_NOT_SEND_AUTH_DATA.

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

* 2373227: [XProto] Consolidate all <X11/*> includes to //ui/gfx/x/x11.h

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

* fixup! 2373227: [XProto] Consolidate all <X11/*> includes to //ui/gfx/x/x11.h

* chore: bump chromium in DEPS to c090e3f960520cbd2328608b97f87238c76d6143

* update patches

* chore: bump chromium in DEPS to 13a25e0a755de9a14271022c595f3d2e29829e1a

* chore: bump chromium in DEPS to 6adbb767b012c41efaeab0d1bdbb3eefed0977bc

* chore: bump chromium in DEPS to 339ec5455c5932ef1322ea9953a6349b0732199e

* chore: bump chromium in DEPS to 20291807c33f7ef4ef4f57d62075e099b027bfe6

* chore: bump chromium in DEPS to 226fbd1b8b17d4ac84fdb9548ef3a1c646878d47

* update patches

* fixup disable_color_correct_rendering patch

* chore: bump chromium in DEPS to 577c45979cad4359f2e206d68efd9317d3d79315

* update patches

* viz: Rename RenderPass to CompositorRenderPass (and related types).

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

* chore: bump chromium in DEPS to 37e2ad5303f2c03a1b5d8eda65341bf2561196cd

* update patches

* add kOmitCookies_Electron

* update patch

* chore: bump chromium in DEPS to 256e42409ea63a7e71016de07818a983a97db463

* update patches

* fix worker script ready hook

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

* Fixup printing page ranges patch

* [printing] Move PrintMsg_PrintPages_Params to print.mojom

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

* Add MIME sniffer overloads that take base::StringPieces

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

* [printing] Move PrintHostMsg_PreviewIds to print.mojom

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

* fixup test due to new DCHECK

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

* stop sending cookies when useSessionCookies is false

* chore: bump chromium in DEPS to dd429dbc556449951ee8160d8a4d61fd95a139d5

* update patches

* chore: bump chromium in DEPS to 5202bde3f9f44c2065f5dacf27e7000dd19e4e4d

* chore: bump chromium in DEPS to 099e8e07b89da65932431bb0fd51b6f7f5344c19

* chore: bump chromium in DEPS to 104e5da2a43b759732d5b94bfc750b3a9a639653

* chore: bump chromium in DEPS to a4519ce657af25834e355315fd7fefa77b13426a

* update patches

* Make FileURLLoaderFactory always owned by its |receivers_|.

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

* Make FileURLLoaderFactory always owned by its |receivers_|.

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

* chore: bump chromium in DEPS to 1b62e9e8c8eaf6b8e3a9c77ee67a4c1bfa6a4d6b

* chore: update patches

* fixup! Make FileURLLoaderFactory always owned by its |receivers_|.

* chore: update patches

- mac: Disable CoreServices _CSCheckFix.
  https://chromium-review.googlesource.com/c/chromium/src/+/2401334
- [XProto] Remove bad DCHECK in x11_error_tracker.cc
  https://chromium-review.googlesource.com/c/chromium/src/+/2402304
- Move content/browser/frame_host/* over to content/browser/renderer_host/
  https://chromium-review.googlesource.com/c/chromium/src/+/2401303

* Refactor WebContentSettingsClient to dedupe AllowXYZ methods

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

* Introduce NonNetworkURLLoaderFactoryBase class.

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

* [XProto] Remove usage of all Xlib headers

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

* fixup! chore: update patches

* chore: bump chromium in DEPS to c1df55fbeb8207d036a604f59e4ea4e8ee79930a

* chore: update patches

* Move content::WebPreferences struct to Blink

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

* chore: bump chromium in DEPS to 57a23ec4884fff6c2f8d9b8536131cdc9b551ec2

* Set appid on Pip windows.

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

* fixup! Set appid on Pip windows.

* fix: add a patch to remove deprecated factory

* chore: bump chromium in DEPS to 1a9ddb7ea43955877823d5c4dcbf241b64228635

* fix compilation on windows

* chore: bump chromium in DEPS to 234e6c6a77f61ffad9335099d9b13892cf88fd44

* chore: update patches

* chore: bump chromium in DEPS to 7631eb0a9f57a8a47d3c28e1d265961b3a4d6b2b

* chore: update patches

* chore: bump chromium in DEPS to f9c34cd485845b95c2d17a7f55fdf92cda9a1b3a

* chore: update patches

* chore: implement GetSurveyAPIKey

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

* chore: replace CreateWebUIURLLoader with CreateWebUIURLLoaderFactory

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

* chore: bump chromium in DEPS to 5bdbd2373da884adf41c087be1465fcc344d168c

* chore: update node patches for common.gypi

* chore: update patches

* chore: non_network_url_loader_factory_base was moved

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

* 2415752: Reland "Reland "OOR-CORS: Remove BlinkCORS supporting code outside Blink""

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

* chore: bump chromium in DEPS to b943d006a33ec5bc1743792d64724693eb357083

* fix: replace x11::None with x11::Window::None

* chore: update patches

* chore: update patches

* fix: cast x11::Window to int

* 2402123: Use end date when deleting http auth cache

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

* 2320268: Migrate DragHostMsg_StartDragging to Mojo

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

* 2401303: Move content/browser/frame_host/* over to content/browser/renderer_host/

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

* chore: fix lint

* chore: fix build

* Update config.yml

Co-authored-by: Electron Bot <anonymous@electronjs.org>
Co-authored-by: Charles Kerr <charles@charleskerr.com>
Co-authored-by: Jeremy Rose <nornagon@nornagon.net>
Co-authored-by: John Kleinschmidt <jkleinsc@github.com>
Co-authored-by: deepak1556 <hop2deep@gmail.com>
Co-authored-by: Samuel Attard <samuel.r.attard@gmail.com>
Co-authored-by: Samuel Attard <sattard@slack-corp.com>
2020-09-21 01:00:36 -07:00
Milan Burda
e50d6e47c4 fix: NOTREACHED in content::ChildProcessHost::GetChildPath when enable_plugins=false (#25525) 2020-09-20 19:08:15 -07:00
Valentin Hăloiu
efd003d277 refactor: replace USE_X11 with OS_LINUX for sharing code with Ozone (#25522) 2020-09-21 09:11:59 +09:00
Shelley Vohr
137fc65e2f fix: app.importCertificate crash on Linux (#25523) 2020-09-18 20:10:41 -06:00
Jeremy Rose
ecb7f877a3 chore: add @nornagon as codeowner of remote (#25500) 2020-09-18 15:25:07 -07:00
Electron Bot
735d8b84f0 Bump v12.0.0-nightly.20200918 2020-09-18 07:31:48 -07:00
Shelley Vohr
a65f7f7d42 fix: close window when leave fs crash (#25468) 2020-09-17 17:40:07 -06:00
bitdisaster
2cfa41e6e0 feat: read/write Toast Activator CLSID in shortcuts (#25493)
* read/write Toast Activator CLSID

* docs

* tests

* tweaks
2020-09-17 15:17:44 -07:00
Shelley Vohr
77038b7bda chore: upgrade to Node.js v14.9.0 (#25249) 2020-09-17 16:08:57 -06:00
Electron Bot
4d1dab849f Bump v12.0.0-nightly.20200917 2020-09-17 07:32:08 -07:00
Cheng Zhao
0b055b2fb8 test: retry the "v8 samples" test for a few times (#25477) 2020-09-17 10:04:53 +09:00
mlaurencin
53aaeb7a16 fix: prevent destroyed view references from causing crashes (#25411)
Closes #21666.

This PR is fixing crashes caused by referencing and attempting to modify previously destroyed views.
Before, when a view was destroyed and then the contents were referenced for modification, the system would crash as undefined memory was accessed. This fix explicitly makes the pointer to the destroyed view's contents null, so that this will not happen.
2020-09-16 18:10:49 -06:00
Milan Burda
e0a25cb1e3 build: fix build with enable_pdf_viewer=false (#25494) 2020-09-17 01:15:01 +03:00
Cheng Zhao
993eab691f fix: disable CORS when webSecurity is disabled (#25463) 2020-09-16 14:55:53 -07:00
Jeremy Rose
a200b15600 docs: update menu example to avoid remote (#25291) 2020-09-16 14:32:32 -07:00
Jeremy Rose
ba55aaa53b fix: check for destroyed webcontents in converter (#25431) 2020-09-16 12:25:49 -07:00
Electron Bot
1ba46a91b6 Bump v12.0.0-nightly.20200916 2020-09-16 07:31:16 -07:00
Shelley Vohr
fa7a29e84b chore: log hint on renderer crash (#25317) 2020-09-15 13:01:50 -06:00
Cheng Zhao
e5933c6910 fix: ensure ready-to-show event is fired (#25448)
* fix: ensure ready-to-show event is fired

* test: acutally draw something when capturePage
2020-09-15 12:48:39 -06:00
Cheng Zhao
2091fd7dd9 test: make a few tests hide their windows (#25466) 2020-09-15 12:48:12 -06:00
Samuel Maddock
45170fdbd7 fix(extensions): define platform info to prevent renderer crash (#25357) 2020-09-15 10:29:32 -06:00
Electron Bot
fbf32f697f Bump v12.0.0-nightly.20200915 2020-09-15 07:31:30 -07:00
Jeremy Rose
459a95aaec fix: call node::Stop on exit (#25430) 2020-09-14 14:08:46 -07:00
Samuel Attard
b1d8057ec9 chore: update dependencies (#25456) 2020-09-14 14:00:15 -07:00
Jeremy Rose
87d67a9365 refactor: use owner window for BrowserWindow.fromWebContents (#25408) 2020-09-14 13:49:57 -07:00
Jeremy Rose
9f4a097e03 feat: remove getMediaSourceIdForWebContents() (#25414)
This reverts commit 204f001c5d.
2020-09-14 10:38:05 -07:00
Jeremy Rose
5de7eb3618 docs: remove references to remote from docs (#25416) 2020-09-14 10:36:54 -07:00
Charles Kerr
7f885bd266 chore: remove unused code from our js scripts (#25419) 2020-09-14 10:22:13 -07:00
Electron Bot
bc9816b206 Bump v12.0.0-nightly.20200914 2020-09-14 07:33:06 -07:00
overkill
633e5d8503 chore: change == None to is None (#25202)
According to LGTM, this change will improve code efficiency.
https://lgtm.com/rules/7900090/
2020-09-13 20:43:16 -06:00
Charles Kerr
9b08fbefe5 chore: remove unused imports in our python scripts (#25406)
Seen at https://lgtm.com/projects/g/electron/electron/?mode=list&id=py%2Funused-import
and confirmed with manual inspection.
2020-09-14 10:25:49 +09:00
Charles Kerr
70e3aa0182 refactor: add a wrapper for wrangling uv handles. (#25332)
* refactor: add a wrapper for wrangling uv handles.

Part 1 of a fix for #25248, #22069.

Place the uv_asyncs owned by NodeBindings, ElectronBindings inside a new
UvHandle wrapper class which manages uv_handles' need for their closed()
callback to be invoked before the handles' memory can be freed.

* chore: make lint happy

* refactor: use DCHECK_EQ() instead of DCHECK()

* refactor: fix oops
2020-09-14 09:53:50 +09:00
Chris Davis
a3389d017f fix: Ensure electron delay loads the same modules as chromium (#25428)
* Ensure electron delay loads the appropriate modules as chromium on windows

This change adds the same module delay load list that chromium uses for electron.  Some modules were already getting delay loaded from other build files in chromium but not the main list via //build/config/win:delayloads.  We do not include the list of delay loads in delayloads_not_for_child_dll as those have issues being loaded in sandboxes processes.  This will reduce the overall reference set impact of the electron processes.

* fix: Ensure win modules are properly delayloaded

* chore: fix linting

Co-authored-by: Samuel Attard <samuel.r.attard@gmail.com>
2020-09-11 23:01:41 -07:00
Jeremy Rose
ce86591459 chore: add wg-security as required reviewer for rpc-server changes (#25415) 2020-09-11 11:34:31 -07:00
Electron Bot
7d56ca7360 Bump v12.0.0-nightly.20200911 2020-09-11 07:31:17 -07:00
Jeremy Rose
cd455c8b40 test: reduce flakiness in pdf test (#25407) 2020-09-10 16:47:36 -07:00
John Kleinschmidt
acf5d487d2 fix: crash on nativeImage on Windows on ARM (#25396)
* fix: nativeImage on WOA

* Remove old ldflag

* maybe this will work ¯\_(ツ)_/¯
2020-09-10 14:42:41 -04:00
Jeremy Rose
dd781c4f63 chore: deprecate remote (#25293) 2020-09-10 09:17:17 -07:00
Electron Bot
98683190b4 Bump v12.0.0-nightly.20200910 2020-09-10 07:32:25 -07:00
Samuel Maddock
1815b95e74 refactor(extensions): break load warnings into newlines (#25358) 2020-09-10 11:39:45 +09:00
Valentin Hăloiu
a829ae56b2 build: use python 2 shebang for git scripts (#25335) 2020-09-10 10:05:19 +09:00
Electron Bot
e6fbbf4325 Bump v12.0.0-nightly.20200909 2020-09-09 07:31:32 -07:00
Shelley Vohr
f6df79b927 fix: bind fake mojo service for badging (#25294)
* fix: bind fake mojo service for badging

* Add a test
2020-09-08 11:13:56 -04:00
Samuel Maddock
5a8046c994 fix(extensions): devtools now open for background pages (#22217)
refactor(extensions): remove unused InitWithBrowserContext method

fix(extensions): release background page WebContents to avoid crash

The background page WebContents instance is managed by the ExtensionHost.

fix(extensions): open background page devtools detached by default

test(extensions): add background page devtools test

chore: test fix for null web_contents()

fix: close background page devtools in test after opening
2020-09-08 20:55:40 +09:00
Erick Zhao
ae5776041e docs: full links to MD files in development README (#24963) 2020-09-08 20:37:47 +09:00
Erick Zhao
f7d9d68e14 docs: clarify a11y docs (#24973)
* docs: remove misleading sentence in a11y docs

* Update accessibility.md

* link
2020-09-08 20:37:00 +09:00
Jeremy Rose
2c5c51afb9 fix: update node certdata to NSS 3.56 (#25313) 2020-09-08 20:28:04 +09:00
Samuel Maddock
860e14c0da chore(extensions): remove old renderer code (#25347) 2020-09-08 20:11:38 +09:00
Electron Bot
31322400e7 Bump v12.0.0-nightly.20200907 2020-09-07 07:31:59 -07:00
Samuel Attard
4ad9bcb8b5 fix: handle electron script errors better (#25328) 2020-09-04 14:53:49 -07:00
Electron Bot
29c1248e96 Bump v12.0.0-nightly.20200904 2020-09-04 07:31:11 -07:00
Samuel Attard
a6b9f9d8e5 fix: only focus a webContents if the window was not initially hidden (#25292) 2020-09-04 15:57:29 +09:00
Jeremy Rose
d305fe7d30 docs: breaking changes for moveItemToTrash (#25286) 2020-09-03 12:44:16 -07:00
Jeremy Rose
4dc09ea9dc feat: [crashReporter] enable compression by default (#25288) 2020-09-03 12:43:58 -07:00
Charles Kerr
4484e95fc8 chore: graceful handling of notes with sub-lists (#25279)
* chore: graceful handling of notes with sub-lists

Handle multine release notes that contain their own bullet points.

Also, if a release note begins with a bullet point, remove it because it
will confuse the markdown parser to have two bullet points.
2020-09-03 14:42:48 -05:00
Robo
03e60cce8b fix: avoid creating client_id file for empty DIR_CRASH_DUMPS (#25296) 2020-09-03 11:52:43 -07:00
Electron Bot
733d56e908 Bump v12.0.0-nightly.20200903 2020-09-03 07:32:01 -07:00
Cheng Zhao
43485b8705 fix: multiple dock icons when calling dock.show/hide (#25269)
* fix: mulitple dock icons when calling dock.show/hide

* test: run dock.show tests after dock.hide tests
2020-09-03 20:46:24 +09:00
Jeremy Rose
bda6378685 chore: remove "no breaking changes" warning in PR template (#25285) 2020-09-02 11:56:10 -07:00
Jeremy Rose
1b6534b326 feat: add shell.trashItem() to replace shell.moveItemToTrash() (#25114) 2020-09-02 10:32:33 -07:00
Shelley Vohr
e9e7eee25e fix: provide asynchronous cleanup hooks in n-api (#25135) 2020-09-02 10:22:05 -07:00
Electron Bot
7e698df8f3 Bump v12.0.0-nightly.20200902 2020-09-02 07:32:22 -07:00
morgan-sam
e0611d0946 docs: setZoomLevel chromium zoom policy (#25105) 2020-09-02 10:06:58 +09:00
Samuel Attard
184e72fafd revert: "fix: reply notifs sometimes destroyed too early" (#25247)
* Revert "fix: reply notifs sometimes destroyed too early (#25086)"

This reverts commit bea6c9e4e1.

* nothing
2020-09-02 10:02:47 +09:00
Eryk Rakowski
3745b76da8 feat(extensions): add support for some chrome.management APIs (#25098)
* fix: initialize management policy

* fix(extensions): crash when using chrome.management

* test: add tests

* docs: add a note about chrome.management

* fix: lint errors

* fix: lint errors

* fix: remove favicon_service include

* fix: add missing management permission

* docs: more supported apis

* fix: extensions.md line endings
2020-09-02 09:59:56 +09:00
Jeremy Rose
bf7dbff858 docs: note remote deprecation in docs/api/remote (#24941) 2020-08-31 11:27:00 -07:00
John Kleinschmidt
7c10f86c6e ci: cleanup up test app directories (#25145)
* ci: cleanup up test app directories

* ci: use electron prefix for a testing apps so that the can be cleaned up

* Revert "ci: cleanup up test app directories"

This reverts commit a47daba812.

* fixup test due to app name change
2020-08-31 14:07:12 -04:00
Electron Bot
9803e4d526 Bump v12.0.0-nightly.20200831 2020-08-31 07:32:25 -07:00
Robo
068b464e13 fix: client area inset calculation when maximized for framless windows (#25052)
* adopt per monitor scale factor

* fix: client area inset calculation when maximized

* address review feedback

* pass correct glass insets to GetDwmFrameInsetsInPixels

* remove unused code

* Windows 8 and 10 use the same DWM frame calculation

Co-authored-by: Cheng Zhao <zcbenz@gmail.com>
2020-08-31 16:55:50 +09:00
Milan Burda
a09694ae85 chore: replace CRLF with LF (#25161)
* chore: replace CRLF with LF

* chore: replace CRLF with LF in docs and tests

Co-authored-by: Cheng Zhao <zcbenz@gmail.com>
2020-08-31 16:52:11 +09:00
Cheng Zhao
e06a1c2746 docs: fix supported platforms of powerMonitor (#25149) 2020-08-31 16:46:10 +09:00
Shelley Vohr
c5320b3951 fix: save dialog extensions should be deterministic (#25164) 2020-08-28 09:40:47 -07:00
Electron Bot
6cc960f214 Bump v12.0.0-nightly.20200828 2020-08-28 07:32:29 -07:00
Shelley Vohr
a4b6fce907 fix: honor pageRanges when printing (#25064) 2020-08-27 20:21:29 -07:00
Cheng Zhao
8f727b3569 fix: do not reset process_id in URLLoaderFactoryParams (#25139) 2020-08-28 10:43:08 +09:00
Shelley Vohr
95073decd3 chore: remove bv before setting owner window (#25172) 2020-08-27 16:24:52 -07:00
Shelley Vohr
e8ef1ef252 chore: wrap add/remove view in extra check (#25166) 2020-08-27 13:04:06 -07:00
Samuel Attard
075502477e chore: we do not use the nightly tag on npm (#25147) 2020-08-27 12:11:27 -07:00
Milan Burda
97755bbd85 fix: resolve RegisterSuspendResumeNotification dynamically (#25162) 2020-08-27 11:20:15 -07:00
Markus Olsson
bab69ae4d2 fix: make shell.moveItemToTrash return false on Windows when move unsuccessful (#25124) 2020-08-27 09:55:33 -07:00
Electron Bot
443540fd13 Bump v12.0.0-nightly.20200827 2020-08-27 07:31:51 -07:00
Cheng Zhao
5e1950ceff chore: force source code and markdown files to use LF line ending (#25134) 2020-08-27 10:25:39 +09:00
498 changed files with 9863 additions and 6276 deletions

View File

@@ -69,7 +69,7 @@ parameters:
# Build machines configs.
docker-image: &docker-image
docker:
- image: electronjs/build:d09fd95029bd8c1c73069888231b29688ef385ed
- image: electron.azurecr.io/build:4cec2c5ab66765caa724e37bae2bffb9b29722a5
machine-linux-medium: &machine-linux-medium
<<: *docker-image
@@ -85,17 +85,17 @@ machine-linux-2xlarge: &machine-linux-2xlarge
machine-mac: &machine-mac
macos:
xcode: "11.5.0"
xcode: "12.2.0"
machine-mac-large: &machine-mac-large
resource_class: large
macos:
xcode: "11.5.0"
xcode: "12.2.0"
machine-mac-large-arm: &machine-mac-large-arm
resource_class: large
macos:
xcode: "12.0.0-large"
xcode: "12.2.0"
# Build configurations options.
env-testing-build: &env-testing-build
@@ -322,13 +322,13 @@ step-restore-brew-cache: &step-restore-brew-cache
paths:
- /usr/local/Homebrew
keys:
- v1-brew-cache-{{ arch }}
- v2-brew-cache-{{ arch }}
step-save-brew-cache: &step-save-brew-cache
save_cache:
paths:
- /usr/local/Homebrew
key: v1-brew-cache-{{ arch }}
key: v2-brew-cache-{{ arch }}
name: Persisting brew cache
step-get-more-space-on-mac: &step-get-more-space-on-mac
@@ -1494,7 +1494,6 @@ commands:
- run:
name: Preserve vendor dirs for release
command: |
mv src/electron/vendor/boto .
mv src/electron/vendor/requests .
- run:
name: Wipe Electron
@@ -1507,9 +1506,7 @@ commands:
- run:
name: Preserve vendor dirs for release
command: |
rm -rf src/electron/vendor/boto
rm -rf src/electron/vendor/requests
mv boto src/electron/vendor
mv requests src/electron/vendor/requests
- *step-generate-deps-hash-cleanly
- *step-mark-sync-done
@@ -1705,7 +1702,7 @@ jobs:
<<: *machine-linux-2xlarge
environment:
<<: *env-linux-2xlarge
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_arm=True --custom-var=checkout_arm64=True --custom-var=checkout_boto=True --custom-var=checkout_requests=True'
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_arm=True --custom-var=checkout_arm64=True --custom-var=checkout_requests=True'
steps:
- electron-build:
persist: false
@@ -1764,7 +1761,7 @@ jobs:
<<: *env-linux-2xlarge
<<: *env-testing-build
<<: *env-macos-build
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_mac=True --custom-var=host_os=mac --custom-var=checkout_boto=True --custom-var=checkout_requests=True'
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_mac=True --custom-var=host_os=mac --custom-var=checkout_requests=True'
steps:
- electron-build:
persist: false
@@ -1857,7 +1854,7 @@ jobs:
<<: *machine-linux-2xlarge
environment:
<<: *env-linux-2xlarge-release
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_boto=True --custom-var=checkout_requests=True'
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_requests=True'
<<: *env-release-build
<<: *env-enable-sccache
UPLOAD_TO_S3: << pipeline.parameters.upload-to-s3 >>
@@ -1919,7 +1916,7 @@ jobs:
<<: *machine-linux-2xlarge
environment:
<<: *env-linux-2xlarge-release
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_boto=True --custom-var=checkout_requests=True'
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_requests=True'
<<: *env-ia32
<<: *env-release-build
<<: *env-enable-sccache
@@ -1945,7 +1942,7 @@ jobs:
checkout: false
linux-arm-testing:
<<: *machine-linux-xlarge
<<: *machine-linux-2xlarge
environment:
<<: *env-global
<<: *env-arm
@@ -1990,7 +1987,7 @@ jobs:
<<: *env-release-build
<<: *env-enable-sccache
<<: *env-32bit-release
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_arm=True --custom-var=checkout_boto=True --custom-var=checkout_requests=True'
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_arm=True --custom-var=checkout_requests=True'
UPLOAD_TO_S3: << pipeline.parameters.upload-to-s3 >>
steps:
- electron-publish:
@@ -2012,7 +2009,7 @@ jobs:
checkout: false
linux-arm64-testing:
<<: *machine-linux-xlarge
<<: *machine-linux-2xlarge
environment:
<<: *env-global
<<: *env-arm64
@@ -2064,7 +2061,7 @@ jobs:
<<: *env-arm64
<<: *env-release-build
<<: *env-enable-sccache
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_arm64=True --custom-var=checkout_boto=True --custom-var=checkout_requests=True'
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_arm64=True --custom-var=checkout_requests=True'
UPLOAD_TO_S3: << pipeline.parameters.upload-to-s3 >>
steps:
- electron-publish:
@@ -2126,7 +2123,7 @@ jobs:
<<: *env-mac-large-release
<<: *env-release-build
<<: *env-enable-sccache
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_boto=True --custom-var=checkout_requests=True'
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_requests=True'
UPLOAD_TO_S3: << pipeline.parameters.upload-to-s3 >>
steps:
- electron-publish:
@@ -2140,7 +2137,7 @@ jobs:
<<: *env-release-build
<<: *env-enable-sccache
<<: *env-apple-silicon
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_boto=True --custom-var=checkout_requests=True'
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_requests=True'
UPLOAD_TO_S3: << pipeline.parameters.upload-to-s3 >>
steps:
- electron-publish:
@@ -2234,7 +2231,7 @@ jobs:
<<: *env-mas
<<: *env-release-build
<<: *env-enable-sccache
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_boto=True --custom-var=checkout_requests=True'
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_requests=True'
UPLOAD_TO_S3: << pipeline.parameters.upload-to-s3 >>
steps:
- electron-publish:
@@ -2248,7 +2245,7 @@ jobs:
<<: *env-mas-apple-silicon
<<: *env-release-build
<<: *env-enable-sccache
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_boto=True --custom-var=checkout_requests=True'
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_requests=True'
UPLOAD_TO_S3: << pipeline.parameters.upload-to-s3 >>
steps:
- electron-publish:

10
.gitattributes vendored
View File

@@ -2,3 +2,13 @@
# files to be checked out with LF endings even if core.autocrlf is true.
*.patch text eol=lf
patches/**/.patches merge=union
# Source code and markdown files should always use LF as line ending.
*.cc text eol=lf
*.mm text eol=lf
*.h text eol=lf
*.js text eol=lf
*.ts text eol=lf
*.py text eol=lf
*.ps1 text eol=lf
*.md text eol=lf

9
.github/CODEOWNERS vendored
View File

@@ -10,3 +10,12 @@ DEPS @electron/wg-upgrades
# Releases WG
/npm/ @electron/wg-releases
/script/release @electron/wg-releases
# Security WG
/lib/browser/rpc-server.ts @electron/wg-security
# Remote Change Disliker
/lib/browser/remote/ @nornagon
/lib/renderer/remote/ @nornagon
/lib/renderer/api/remote.ts @nornagon
/docs/api/remote.md @nornagon

View File

@@ -15,7 +15,6 @@ Contributors guide: https://github.com/electron/electron/blob/master/CONTRIBUTIN
- [ ] relevant documentation is changed or added
- [ ] PR title follows semantic [commit guidelines](https://github.com/electron/electron/blob/master/docs/development/pull-requests.md#commit-message-guidelines)
- [ ] [PR release notes](https://github.com/electron/clerk/blob/master/README.md) describe the change in a way relevant to app developers, and are [capitalized, punctuated, and past tense](https://github.com/electron/clerk/blob/master/README.md#examples).
- [ ] This is **NOT A BREAKING CHANGE**. Breaking changes may not be merged to master until 11-x-y is branched.
#### Release Notes

View File

@@ -531,7 +531,9 @@ source_set("electron_lib") {
]
}
configs += [ ":gio_unix" ]
configs += [ "//build/config/linux:x11" ]
if (use_x11) {
deps += [ "//ui/gfx/x" ]
}
defines += [
# Disable warnings for g_settings_list_schemas.
"GLIB_DISABLE_DEPRECATION_WARNINGS",
@@ -642,6 +644,7 @@ source_set("electron_lib") {
"shell/common/extensions/api",
"shell/common/extensions/api:extensions_features",
"//chrome/browser/resources:component_extension_resources",
"//components/update_client:update_client",
"//components/zoom",
"//extensions/browser",
"//extensions/browser:core_api_provider",
@@ -1138,22 +1141,25 @@ if (is_mac) {
"//components/crash/core/app:run_as_crashpad_handler",
]
ldflags = []
libs = [
"comctl32.lib",
"uiautomationcore.lib",
"wtsapi32.lib",
]
configs += [ "//build/config/win:windowed" ]
ldflags = [
# Windows 7 doesn't have these DLLs.
# TODO: are there other DLLs we need to list here to be win7
# compatible?
"/DELAYLOAD:api-ms-win-core-winrt-l1-1-0.dll",
"/DELAYLOAD:api-ms-win-core-winrt-string-l1-1-0.dll",
configs -= [ "//build/config/win:console" ]
configs += [
"//build/config/win:windowed",
"//build/config/win:delayloads",
]
if (target_cpu == "arm64") {
configs -= [ "//build/config/win:cfi_linker" ]
ldflags += [ "/guard:cf,nolongjmp" ]
}
# This is to support renaming of electron.exe. node-gyp has hard-coded
# executable names which it will recognise as node. This module definition
# file claims that the electron executable is in fact named "node.exe",

23
DEPS
View File

@@ -14,19 +14,17 @@ gclient_gn_args = [
vars = {
'chromium_version':
'b04584161e07d4ac110045b7647fa8a81f5f0709',
'b943d006a33ec5bc1743792d64724693eb357083',
'node_version':
'v12.18.3',
'v14.12.0',
'nan_version':
'2c4ee8a32a299eada3cd6e468bbd0a473bfea96d',
'squirrel.mac_version':
'44468f858ce0d25c27bd5e674abfa104e0119738',
'boto_version': 'f7574aa6cc2c819430c1f05e9a1a1a666ef8169b',
'pyyaml_version': '3.12',
'requests_version': 'e4d59bedfd3c7f4f254f4f5d036587bcd8152458',
'boto_git': 'https://github.com/boto',
'chromium_git': 'https://chromium.googlesource.com',
'electron_git': 'https://github.com/electron',
'nodejs_git': 'https://github.com/nodejs',
@@ -40,9 +38,6 @@ vars = {
# To be able to build clean Chromium from sources.
'apply_patches': True,
# Python interface to Amazon Web Services. Is used for releases only.
'checkout_boto': False,
# To allow in-house builds to checkout those manually.
'checkout_chromium': True,
'checkout_node': True,
@@ -99,10 +94,6 @@ deps = {
'url': (Var("yaml_git")) + '/pyyaml.git@' + (Var("pyyaml_version")),
'condition': 'checkout_pyyaml and process_deps',
},
'src/electron/vendor/boto': {
'url': Var('boto_git') + '/boto.git' + '@' + Var('boto_version'),
'condition': 'checkout_boto and process_deps',
},
'src/electron/vendor/requests': {
'url': Var('requests_git') + '/requests.git' + '@' + Var('requests_version'),
'condition': 'checkout_requests and process_deps',
@@ -150,16 +141,6 @@ hooks = [
'import os, subprocess; os.chdir(os.path.join("src", "electron")); subprocess.check_call(["python", "script/lib/npx.py", "yarn@' + (Var("yarn_version")) + '", "install", "--frozen-lockfile"]);',
],
},
{
'name': 'setup_boto',
'pattern': 'src/electron',
'condition': 'checkout_boto and process_deps',
'action': [
'python3',
'-c',
'import os, subprocess; os.chdir(os.path.join("src", "electron", "vendor", "boto")); subprocess.check_call(["python", "setup.py", "build"]);',
],
},
{
'name': 'setup_requests',
'pattern': 'src/electron',

View File

@@ -1 +1 @@
11.0.0-nightly.20200826
12.0.0-nightly.20201006

View File

@@ -4,6 +4,7 @@
[![CircleCI Build Status](https://circleci.com/gh/electron/electron/tree/master.svg?style=shield)](https://circleci.com/gh/electron/electron/tree/master)
[![AppVeyor Build Status](https://ci.appveyor.com/api/projects/status/4lggi9dpjc1qob7k/branch/master?svg=true)](https://ci.appveyor.com/project/electron-bot/electron-ljo26/branch/master)
[![devDependency Status](https://david-dm.org/electron/electron/dev-status.svg)](https://david-dm.org/electron/electron?type=dev)
[![Electron Discord Invite](https://img.shields.io/discord/745037351163527189?color=%237289DA&label=chat&logo=discord&logoColor=white)](https://discord.com/invite/electron)
:memo: Available Translations: 🇨🇳 🇹🇼 🇧🇷 🇪🇸 🇰🇷 🇯🇵 🇷🇺 🇫🇷 🇹🇭 🇳🇱 🇹🇷 🇮🇩 🇺🇦 🇨🇿 🇮🇹 🇵🇱.
View these docs in other languages at [electron/i18n](https://github.com/electron/i18n/tree/master/content/).

View File

@@ -53,7 +53,9 @@ build_script:
} else {
node script/yarn.js install --frozen-lockfile
if ($(node script/doc-only-change.js --prNumber=$env:APPVEYOR_PULL_REQUEST_NUMBER --prBranch=$env:APPVEYOR_REPO_BRANCH;$LASTEXITCODE -eq 0)) {
$result = node script/doc-only-change.js --prNumber=$env:APPVEYOR_PULL_REQUEST_NUMBER --prBranch=$env:APPVEYOR_REPO_BRANCH
Write-Output $result
if ($result.ExitCode -eq 0) {
Write-warning "Skipping build for doc only change"; Exit-AppveyorBuild
}
}
@@ -67,7 +69,7 @@ build_script:
- ps: $env:SCCACHE_PATH="$pwd\src\electron\external_binaries\sccache.exe"
- ps: >-
if ($env:GN_CONFIG -eq 'release') {
$env:GCLIENT_EXTRA_ARGS="$env:GCLIENT_EXTRA_ARGS --custom-var=checkout_boto=True --custom-var=checkout_requests=True"
$env:GCLIENT_EXTRA_ARGS="$env:GCLIENT_EXTRA_ARGS --custom-var=checkout_requests=True"
} else {
$env:NINJA_STATUS="[%r processes, %f/%t @ %o/s : %es] "
}

View File

@@ -2,7 +2,7 @@ is_electron_build = true
root_extra_deps = [ "//electron" ]
# Registry of NMVs --> https://github.com/nodejs/node/blob/master/doc/abi_version_registry.json
node_module_version = 82
node_module_version = 87
v8_promise_internal_field_count = 1
v8_typed_array_max_size_in_heap = 0

View File

@@ -11,7 +11,6 @@ import find_depot_tools
from vs_toolchain import \
SetEnvironmentAndGetRuntimeDllDirs, \
SetEnvironmentAndGetSDKDir, \
GetVisualStudioVersion, \
NormalizePath
sys.path.append("%s/win_toolchain" % find_depot_tools.add_depot_tools_to_path())

View File

@@ -1,6 +1,5 @@
import sys
import os
import subprocess
def main(argv):
cwd = argv[1]

View File

@@ -10,10 +10,9 @@ config.output = {
filename: path.basename(outPath)
};
const { wrapInitWithProfilingTimeout } = config;
delete config.wrapInitWithProfilingTimeout;
const { wrapInitWithProfilingTimeout, wrapInitWithTryCatch, ...webpackConfig } = config;
webpack(config, (err, stats) => {
webpack(webpackConfig, (err, stats) => {
if (err) {
console.error(err);
process.exit(1);
@@ -21,9 +20,17 @@ webpack(config, (err, stats) => {
console.error(stats.toString('normal'));
process.exit(1);
} else {
let contents = fs.readFileSync(outPath, 'utf8');
if (wrapInitWithTryCatch) {
contents = `try {
${contents}
} catch (err) {
console.error('Electron ${webpackConfig.output.filename} script failed to run');
console.error(err);
}`;
}
if (wrapInitWithProfilingTimeout) {
const contents = fs.readFileSync(outPath, 'utf8');
const newContents = `function ___electron_webpack_init__() {
contents = `function ___electron_webpack_init__() {
${contents}
};
if ((globalThis.process || binding.process).argv.includes("--profile-electron-init")) {
@@ -31,8 +38,8 @@ if ((globalThis.process || binding.process).argv.includes("--profile-electron-in
} else {
___electron_webpack_init__();
}`;
fs.writeFileSync(outPath, newContents);
}
fs.writeFileSync(outPath, contents);
process.exit(0);
}
});

View File

@@ -69,7 +69,8 @@ module.exports = ({
loadElectronFromAlternateTarget,
targetDeletesNodeGlobals,
target,
wrapInitWithProfilingTimeout
wrapInitWithProfilingTimeout,
wrapInitWithTryCatch
}) => {
let entry = path.resolve(electronRoot, 'lib', target, 'init.ts');
if (!fs.existsSync(entry)) {
@@ -87,6 +88,7 @@ module.exports = ({
filename: `${target}.bundle.js`
},
wrapInitWithProfilingTimeout,
wrapInitWithTryCatch,
resolve: {
alias: {
'@electron/internal': path.resolve(electronRoot, 'lib'),

View File

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

View File

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

View File

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

View File

@@ -2,5 +2,6 @@ module.exports = require('./webpack.config.base')({
target: 'worker',
loadElectronFromAlternateTarget: 'renderer',
alwaysHasNode: true,
targetDeletesNodeGlobals: true
targetDeletesNodeGlobals: true,
wrapInitWithTryCatch: true
});

View File

@@ -266,6 +266,15 @@ static_library("chrome") {
]
}
}
sources += [ "//chrome/browser/hang_monitor/hang_crash_dump.h" ]
if (is_mac) {
sources += [ "//chrome/browser/hang_monitor/hang_crash_dump_mac.cc" ]
} else if (is_win) {
sources += [ "//chrome/browser/hang_monitor/hang_crash_dump_win.cc" ]
} else {
sources += [ "//chrome/browser/hang_monitor/hang_crash_dump.cc" ]
}
}
source_set("plugins") {

View File

@@ -36,6 +36,7 @@ net::NSSCertDatabase* GetNSSCertDatabaseForResourceContext(
// Linux has only a single persistent slot compared to ChromeOS's separate
// public and private slot.
// Redirect any slot usage to this persistent slot on Linux.
crypto::EnsureNSSInit();
g_nss_cert_database = new net::NSSCertDatabase(
crypto::ScopedPK11Slot(PK11_GetInternalKeySlot()) /* public slot */,
crypto::ScopedPK11Slot(PK11_GetInternalKeySlot()) /* private slot */);

View File

@@ -56,7 +56,7 @@ an issue:
* [Accessibility](tutorial/accessibility.md)
* [Spectron](tutorial/accessibility.md#spectron)
* [Devtron](tutorial/accessibility.md#devtron)
* [Enabling Accessibility](tutorial/accessibility.md#enabling-accessibility)
* [Manually Enabling Accessibility Features](tutorial/accessibility.md#manually-enabling-accessibility-features)
* [Testing and Debugging](tutorial/application-debugging.md)
* [Debugging the Main Process](tutorial/debugging-main-process.md)
* [Debugging the Main Process with Visual Studio Code](tutorial/debugging-main-process-vscode.md)

View File

@@ -402,7 +402,7 @@ Returns:
* `killed` - Process was sent a SIGTERM or otherwise killed externally
* `crashed` - Process crashed
* `oom` - Process ran out of memory
* `launch-failure` - Process never successfully launched
* `launch-failed` - Process never successfully launched
* `integrity-failure` - Windows code integrity checks failed
Emitted when the renderer process unexpectedly disappears. This is normally
@@ -428,7 +428,7 @@ Returns:
* `killed` - Process was sent a SIGTERM or otherwise killed externally
* `crashed` - Process crashed
* `oom` - Process ran out of memory
* `launch-failure` - Process never successfully launched
* `launch-failed` - Process never successfully launched
* `integrity-failure` - Windows code integrity checks failed
* `exitCode` Number - The exit code for the process
(e.g. status from waitpid if on posix, from GetExitCodeProcess on Windows).
@@ -501,7 +501,7 @@ Returns:
Emitted when `desktopCapturer.getSources()` is called in the renderer process of `webContents`.
Calling `event.preventDefault()` will make it return empty sources.
### Event: 'remote-require'
### Event: 'remote-require' _Deprecated_
Returns:
@@ -513,7 +513,7 @@ Emitted when `remote.require()` is called in the renderer process of `webContent
Calling `event.preventDefault()` will prevent the module from being returned.
Custom value can be returned by setting `event.returnValue`.
### Event: 'remote-get-global'
### Event: 'remote-get-global' _Deprecated_
Returns:
@@ -525,7 +525,7 @@ Emitted when `remote.getGlobal()` is called in the renderer process of `webConte
Calling `event.preventDefault()` will prevent the global from being returned.
Custom value can be returned by setting `event.returnValue`.
### Event: 'remote-get-builtin'
### Event: 'remote-get-builtin' _Deprecated_
Returns:
@@ -537,7 +537,7 @@ Emitted when `remote.getBuiltin()` is called in the renderer process of `webCont
Calling `event.preventDefault()` will prevent the module from being returned.
Custom value can be returned by setting `event.returnValue`.
### Event: 'remote-get-current-window'
### Event: 'remote-get-current-window' _Deprecated_
Returns:
@@ -548,7 +548,7 @@ Emitted when `remote.getCurrentWindow()` is called in the renderer process of `w
Calling `event.preventDefault()` will prevent the object from being returned.
Custom value can be returned by setting `event.returnValue`.
### Event: 'remote-get-current-web-contents'
### Event: 'remote-get-current-web-contents' _Deprecated_
Returns:

View File

@@ -8,9 +8,6 @@ Process: [Main](../glossary.md#main-process)
// In the main process.
const { BrowserWindow } = require('electron')
// Or use `remote` from the renderer process.
// const { BrowserWindow } = require('electron').remote
const win = new BrowserWindow({ width: 800, height: 600 })
// Load a remote URL
@@ -1349,6 +1346,17 @@ Enters or leaves kiosk mode.
Returns `Boolean` - Whether the window is in kiosk mode.
#### `win.isTabletMode()` _Windows_
Returns `Boolean` - Whether the window is in Windows 10 tablet mode.
Since Windows 10 users can [use their PC as tablet](https://support.microsoft.com/en-us/help/17210/windows-10-use-your-pc-like-a-tablet),
under this mode apps can choose to optimize their UI for tablets, such as
enlarging the titlebar and hiding titlebar buttons.
This API returns whether the window is in tablet mode, and the `resize` event
can be be used to listen to changes to tablet mode.
#### `win.getMediaSourceId()`
Returns `String` - Window id in the format of DesktopCapturerSource's id. For example "window:1234:0".

View File

@@ -13,30 +13,40 @@ interface and is therefore an [EventEmitter][event-emitter].
the request URL. If it is an object, it is expected to fully specify an HTTP request via the
following properties:
* `method` String (optional) - The HTTP request method. Defaults to the GET
method.
method.
* `url` String (optional) - The request URL. Must be provided in the absolute
form with the protocol scheme specified as http or https.
form with the protocol scheme specified as http or https.
* `session` Session (optional) - The [`Session`](session.md) instance with
which the request is associated.
which the request is associated.
* `partition` String (optional) - The name of the [`partition`](session.md)
with which the request is associated. Defaults to the empty string. The
`session` option prevails on `partition`. Thus if a `session` is explicitly
specified, `partition` is ignored.
with which the request is associated. Defaults to the empty string. The
`session` option supersedes `partition`. Thus if a `session` is explicitly
specified, `partition` is ignored.
* `credentials` String (optional) - Can be `include` or `omit`. Whether to
send [credentials](https://fetch.spec.whatwg.org/#credentials) with this
request. If set to `include`, credentials from the session associated with
the request will be used. If set to `omit`, credentials will not be sent
with the request (and the `'login'` event will not be triggered in the
event of a 401). This matches the behavior of the
[fetch](https://fetch.spec.whatwg.org/#concept-request-credentials-mode)
option of the same name. If this option is not specified, authentication
data from the session will be sent, and cookies will not be sent (unless
`useSessionCookies` is set).
* `useSessionCookies` Boolean (optional) - Whether to send cookies with this
request from the provided session. This will make the `net` request's
cookie behavior match a `fetch` request. Default is `false`.
* `protocol` String (optional) - The protocol scheme in the form 'scheme:'.
Currently supported values are 'http:' or 'https:'. Defaults to 'http:'.
request from the provided session. If `credentials` is specified, this
option has no effect. Default is `false`.
* `protocol` String (optional) - Can be `http:` or `https:`. The protocol
scheme in the form 'scheme:'. Defaults to 'http:'.
* `host` String (optional) - The server host provided as a concatenation of
the hostname and the port number 'hostname:port'.
the hostname and the port number 'hostname:port'.
* `hostname` String (optional) - The server host name.
* `port` Integer (optional) - The server's listening port number.
* `path` String (optional) - The path part of the request URL.
* `redirect` String (optional) - The redirect mode for this request. Should be
one of `follow`, `error` or `manual`. Defaults to `follow`. When mode is `error`,
any redirection will be aborted. When mode is `manual` the redirection will be
cancelled unless [`request.followRedirect`](#requestfollowredirect) is invoked
synchronously during the [`redirect`](#event-redirect) event.
* `redirect` String (optional) - Can be `follow`, `error` or `manual`. The
redirect mode for this request. When mode is `error`, any redirection will
be aborted. When mode is `manual` the redirection will be cancelled unless
[`request.followRedirect`](#requestfollowredirect) is invoked synchronously
during the [`redirect`](#event-redirect) event. Defaults to `follow`.
`options` properties such as `protocol`, `host`, `hostname`, `port` and `path`
strictly follow the Node.js model as described in the

View File

@@ -198,6 +198,14 @@ logging level for all code in the source files under a `foo/bar` directory.
This switch only works when `--enable-logging` is also passed.
### --force_high_performance_gpu
Force using discrete GPU when there are multiple GPUs available.
### --force_low_power_gpu
Force using integrated GPU when there are multiple GPUs available.
## Node.js Flags
Electron supports some of the [CLI flags][node-cli] supported by Node.js.

View File

@@ -39,6 +39,37 @@ is an implementation detail driven by Chromium, and it may change in future. In
particular, crashpad is newer and will likely eventually replace breakpad on
all platforms.
### Note about Node child processes on Linux
If you are using the Node.js `child_process` module and want to report crashes
from those processes on Linux, there is an extra step you will need to take to
properly initialize the crash reporter in the child process. This is not
necessary on Mac or Windows, as those platforms use Crashpad, which
automatically monitors child processes.
Since `require('electron')` is not available in Node child processes, the
following APIs are available on the `process` object in Node child processes.
Note that, on Linux, each Node child process has its own separate instance of
the breakpad crash reporter. This is dissimilar to renderer child processes,
which have a "stub" breakpad reporter which returns information to the main
process for reporting.
#### `process.crashReporter.start(options)`
See [`crashReporter.start()`](#crashreporterstartoptions).
#### `process.crashReporter.getParameters()`
See [`crashReporter.getParameters()`](#crashreportergetparameters).
#### `process.crashReporter.addExtraParameter(key, value)`
See [`crashReporter.addExtraParameter(key, value)`](#crashreporteraddextraparameterkey-value).
#### `process.crashReporter.removeExtraParameter(key)`
See [`crashReporter.removeExtraParameter(key)`](#crashreporterremoveextraparameterkey).
## Methods
The `crashReporter` module has the following methods:
@@ -59,7 +90,7 @@ The `crashReporter` module has the following methods:
* `rateLimit` Boolean (optional) _macOS_ _Windows_ - If true, limit the
number of crashes uploaded to 1/hour. Default is `false`.
* `compress` Boolean (optional) - If true, crash reports will be compressed
and uploaded with `Content-Encoding: gzip`. Default is `false`.
and uploaded with `Content-Encoding: gzip`. Default is `true`.
* `extra` Record<String, String> (optional) - Extra string key/value
annotations that will be sent along with crash reports that are generated
in the main process. Only string values are supported. Crashes generated in

View File

@@ -72,50 +72,6 @@ const constraints = {
}
```
This example shows how to capture a video from a [WebContents](web-contents.md)
```javascript
// In the renderer process.
const { desktopCapturer, remote } = require('electron')
desktopCapturer.getMediaSourceIdForWebContents(remote.getCurrentWebContents().id).then(async mediaSourceId => {
try {
const stream = await navigator.mediaDevices.getUserMedia({
audio: {
mandatory: {
chromeMediaSource: 'tab',
chromeMediaSourceId: mediaSourceId
}
},
video: {
mandatory: {
chromeMediaSource: 'tab',
chromeMediaSourceId: mediaSourceId,
minWidth: 1280,
maxWidth: 1280,
minHeight: 720,
maxHeight: 720
}
}
})
handleStream(stream)
} catch (e) {
handleError(e)
}
})
function handleStream (stream) {
const video = document.querySelector('video')
video.srcObject = stream
video.onloadedmetadata = (e) => video.play()
}
function handleError (e) {
console.log(e)
}
```
## Methods
The `desktopCapturer` module has the following methods:
@@ -138,15 +94,6 @@ Returns `Promise<DesktopCapturerSource[]>` - Resolves with an array of [`Desktop
**Note** Capturing the screen contents requires user consent on macOS 10.15 Catalina or higher,
which can detected by [`systemPreferences.getMediaAccessStatus`].
### `desktopCapturer.getMediaSourceIdForWebContents(webContentsId)`
* `webContentsId` number - Id of the WebContents to get stream of
Returns `Promise<string>` - Resolves with the identifier of a WebContents stream, this identifier can be
used with [`navigator.mediaDevices.getUserMedia`].
The identifier is **only valid for 10 seconds**.
The identifier may be empty if not requested from a renderer process.
[`navigator.mediaDevices.getUserMedia`]: https://developer.mozilla.org/en/docs/Web/API/MediaDevices/getUserMedia
[`systemPreferences.getMediaAccessStatus`]: system-preferences.md#systempreferencesgetmediaaccessstatusmediatype-macos

View File

@@ -11,14 +11,6 @@ const { dialog } = require('electron')
console.log(dialog.showOpenDialog({ properties: ['openFile', 'multiSelections'] }))
```
The Dialog is opened from Electron's main thread. If you want to use the dialog
object from a renderer process, remember to access it using the remote:
```javascript
const { dialog } = require('electron').remote
console.log(dialog)
```
## Methods
The `dialog` module has the following methods:
@@ -314,7 +306,7 @@ Returns `Promise<Object>` - resolves with a promise containing the following pro
* `checkboxChecked` Boolean - The checked state of the checkbox if
`checkboxLabel` was set. Otherwise `false`.
Shows a message box, it will block the process until the message box is closed.
Shows a message box.
The `browserWindow` argument allows the dialog to attach itself to a parent window, making it modal.

View File

@@ -79,6 +79,7 @@ The `downloadItem` object has the following methods:
* `path` String - Set the save file path of the download item.
The API is only available in session's `will-download` callback function.
If `path` doesn't exist, Electron will try to make the directory recursively.
If user doesn't set the save path via the API, Electron will use the original
routine to determine the save path; this usually prompts a save dialog.

View File

@@ -74,6 +74,7 @@ The following methods of `chrome.runtime` are supported:
- `chrome.runtime.getBackgroundPage`
- `chrome.runtime.getManifest`
- `chrome.runtime.getPlatformInfo`
- `chrome.runtime.getURL`
- `chrome.runtime.connect`
- `chrome.runtime.sendMessage`
@@ -102,3 +103,15 @@ The following methods of `chrome.tabs` are supported:
> **Note:** In Chrome, passing `-1` as a tab ID signifies the "currently active
> tab". Since Electron has no such concept, passing `-1` as a tab ID is not
> supported and will raise an error.
### `chrome.management`
The following methods of `chrome.management` are supported:
- `chrome.management.getAll`
- `chrome.management.get`
- `chrome.management.getSelf`
- `chrome.management.getPermissionWarningsById`
- `chrome.management.getPermissionWarningsByManifest`
- `chrome.management.onEnabled`
- `chrome.management.onDisabled`

View File

@@ -112,13 +112,19 @@ optional parameter can be used to forward mouse move messages to the web page,
allowing events such as `mouseleave` to be emitted:
```javascript
const win = require('electron').remote.getCurrentWindow()
const { ipcRenderer } = require('electron')
const el = document.getElementById('clickThroughElement')
el.addEventListener('mouseenter', () => {
win.setIgnoreMouseEvents(true, { forward: true })
ipcRenderer.send('set-ignore-mouse-events', true, { forward: true })
})
el.addEventListener('mouseleave', () => {
win.setIgnoreMouseEvents(false)
ipcRenderer.send('set-ignore-mouse-events', false)
})
// Main process
const { ipcMain } = require('electron')
ipcMain.on('set-ignore-mouse-events', (event, ...args) => {
BrowserWindow.fromWebContents(event.sender).setIgnoreMouseEvents(...args)
})
```

View File

@@ -20,7 +20,7 @@ applicative code.
#### Event: 'end'
Indicates that response body has ended.
Indicates that response body has ended. Must be placed before 'data' event.
#### Event: 'aborted'

View File

@@ -141,13 +141,7 @@ can have a submenu.
## Examples
The `Menu` class is only available in the main process, but you can also use it
in the render process via the [`remote`](remote.md) module.
### Main process
An example of creating the application menu in the main process with the
simple template API:
An example of creating the application menu with the simple template API:
```javascript
const { app, Menu } = require('electron')
@@ -257,26 +251,36 @@ Menu.setApplicationMenu(menu)
### Render process
Below is an example of creating a menu dynamically in a web page
(render process) by using the [`remote`](remote.md) module, and showing it when
the user right clicks the page:
To create menus initiated by the renderer process, send the required
information to the main process using IPC and have the main process display the
menu on behalf of the renderer.
```html
<!-- index.html -->
<script>
const { remote } = require('electron')
const { Menu, MenuItem } = remote
const menu = new Menu()
menu.append(new MenuItem({ label: 'MenuItem1', click() { console.log('item 1 clicked') } }))
menu.append(new MenuItem({ type: 'separator' }))
menu.append(new MenuItem({ label: 'MenuItem2', type: 'checkbox', checked: true }))
Below is an example of showing a menu when the user right clicks the page:
```js
// renderer
window.addEventListener('contextmenu', (e) => {
e.preventDefault()
menu.popup({ window: remote.getCurrentWindow() })
}, false)
</script>
ipcRenderer.send('show-context-menu')
})
ipcRenderer.on('context-menu-command', (e, command) => {
// ...
})
// main
ipcMain.on('show-context-menu', (event) => {
const template = [
{
label: 'Menu Item 1',
click: () => { event.sender.send('context-menu-command', 'menu-item-1') }
},
{ type: 'separator' },
{ label: 'Menu Item 2', type: 'checkbox', checked: true }
]
const menu = Menu.buildFromTemplate(template)
menu.popup(BrowserWindow.fromWebContents(event.sender))
})
```
## Notes on macOS Application Menu

View File

@@ -13,9 +13,19 @@ Process: [Main](../glossary.md#main-process)
Example:
```js
// Main process
const { port1, port2 } = new MessageChannelMain()
w.webContents.postMessage('port', null, [port2])
port1.postMessage({ some: 'message' })
// Renderer process
const { ipcRenderer } = require('electron')
ipcRenderer.on('port', (e) => {
// e.ports is a list of ports sent along with this message
e.ports[0].on('message', (messageEvent) => {
console.log(messageEvent.data)
})
})
```
### Instance Properties

View File

@@ -29,9 +29,9 @@ Returns `Boolean` - Whether or not desktop notifications are supported on the cu
### `new Notification([options])`
* `options` Object (optional)
* `title` String - A title for the notification, which will be shown at the top of the notification window when it is shown.
* `title` String (optional) - A title for the notification, which will be shown at the top of the notification window when it is shown.
* `subtitle` String (optional) _macOS_ - A subtitle for the notification, which will be displayed below the title.
* `body` String - The body text of the notification, which will be displayed below the title or subtitle.
* `body` String (optional) - The body text of the notification, which will be displayed below the title or subtitle.
* `silent` Boolean (optional) - Whether or not to emit an OS notification noise when showing the notification.
* `icon` (String | [NativeImage](native-image.md)) (optional) - An icon to use in the notification.
* `hasReply` Boolean (optional) _macOS_ - Whether or not to add an inline reply option to the notification.
@@ -41,6 +41,7 @@ Returns `Boolean` - Whether or not desktop notifications are supported on the cu
* `urgency` String (optional) _Linux_ - The urgency level of the notification. Can be 'normal', 'critical', or 'low'.
* `actions` [NotificationAction[]](structures/notification-action.md) (optional) _macOS_ - Actions to add to the notification. Please read the available actions and limitations in the `NotificationAction` documentation.
* `closeButtonText` String (optional) _macOS_ - A custom title for the close button of an alert. An empty string will cause the default localized text to be used.
* `toastXml` String (optional) _Windows_ - A custom description of the Notification on Windows superseding all properties above. Provides full customization of design and behavior of the notification.
### Instance Events
@@ -94,6 +95,15 @@ Returns:
* `event` Event
* `index` Number - The index of the action that was activated.
#### Event: 'failed' _Windows_
Returns:
* `event` Event
* `error` String - The error encountered during execution of the `show()` method.
Emitted when an error is encountered while creating and showing the native notification.
### Instance Methods
Objects created with `new Notification` have the following instance methods:
@@ -162,6 +172,10 @@ If `timeoutType` is set to 'never', the notification never expires. It stays ope
A [`NotificationAction[]`](structures/notification-action.md) property representing the actions of the notification.
#### `notification.toastXml` _Windows_
A `String` property representing the custom Toast XML of the notification.
### Playing Sounds
On macOS, you can specify the name of the sound you'd like to play when the

View File

@@ -8,19 +8,19 @@ Process: [Main](../glossary.md#main-process)
The `powerMonitor` module emits the following events:
### Event: 'suspend'
### Event: 'suspend' _macOS_ _Windows_
Emitted when the system is suspending.
### Event: 'resume'
### Event: 'resume' _macOS_ _Windows_
Emitted when system is resuming.
### Event: 'on-ac' _Windows_
### Event: 'on-ac' _macOS_ _Windows_
Emitted when the system changes to AC power.
### Event: 'on-battery' _Windows_
### Event: 'on-battery' _macOS_ _Windows_
Emitted when system changes to battery power.
@@ -39,6 +39,14 @@ Emitted when the system is about to lock the screen.
Emitted as soon as the systems screen is unlocked.
### Event: 'user-did-become-active' _macOS_
Emitted when a login session is activated. See [documentation](https://developer.apple.com/documentation/appkit/nsworkspacesessiondidbecomeactivenotification?language=objc) for more information.
### Event: 'user-did-resign-active' _macOS_
Emitted when a login session is deactivated. See [documentation](https://developer.apple.com/documentation/appkit/nsworkspacesessiondidresignactivenotification?language=objc) for more information.
## Methods
The `powerMonitor` module has the following methods:

View File

@@ -112,7 +112,7 @@ expect streaming responses.
* `scheme` String
* `handler` Function
* `request` ProtocolRequest
* `request` [ProtocolRequest](structures/protocol-request.md)
* `callback` Function
* `response` (String | [ProtocolResponse](structures/protocol-response.md))
@@ -133,7 +133,7 @@ from protocols that follow the "generic URI syntax" like `file:`.
* `scheme` String
* `handler` Function
* `request` ProtocolRequest
* `request` [ProtocolRequest](structures/protocol-request.md)
* `callback` Function
* `response` (Buffer | [ProtocolResponse](structures/protocol-response.md))
@@ -157,7 +157,7 @@ protocol.registerBufferProtocol('atom', (request, callback) => {
* `scheme` String
* `handler` Function
* `request` ProtocolRequest
* `request` [ProtocolRequest](structures/protocol-request.md)
* `callback` Function
* `response` (String | [ProtocolResponse](structures/protocol-response.md))
@@ -173,7 +173,7 @@ property.
* `scheme` String
* `handler` Function
* `request` ProtocolRequest
* `request` [ProtocolRequest](structures/protocol-request.md)
* `callback` Function
* `response` ProtocolResponse
@@ -188,7 +188,7 @@ should be called with an object that has the `url` property.
* `scheme` String
* `handler` Function
* `request` ProtocolRequest
* `request` [ProtocolRequest](structures/protocol-request.md)
* `callback` Function
* `response` (ReadableStream | [ProtocolResponse](structures/protocol-response.md))
@@ -251,7 +251,7 @@ Returns `Boolean` - Whether `scheme` is already registered.
* `scheme` String
* `handler` Function
* `request` ProtocolRequest
* `request` [ProtocolRequest](structures/protocol-request.md)
* `callback` Function
* `response` (String | [ProtocolResponse](structures/protocol-response.md))
@@ -264,7 +264,7 @@ which sends a file as a response.
* `scheme` String
* `handler` Function
* `request` ProtocolRequest
* `request` [ProtocolRequest](structures/protocol-request.md)
* `callback` Function
* `response` (String | [ProtocolResponse](structures/protocol-response.md))
@@ -277,7 +277,7 @@ which sends a `String` as a response.
* `scheme` String
* `handler` Function
* `request` ProtocolRequest
* `request` [ProtocolRequest](structures/protocol-request.md)
* `callback` Function
* `response` (Buffer | [ProtocolResponse](structures/protocol-response.md))
@@ -290,7 +290,7 @@ which sends a `Buffer` as a response.
* `scheme` String
* `handler` Function
* `request` ProtocolRequest
* `request` [ProtocolRequest](structures/protocol-request.md)
* `callback` Function
* `response` [ProtocolResponse](structures/protocol-response.md)
@@ -303,7 +303,7 @@ which sends a new HTTP request as a response.
* `scheme` String
* `handler` Function
* `request` ProtocolRequest
* `request` [ProtocolRequest](structures/protocol-request.md)
* `callback` Function
* `response` (ReadableStream | [ProtocolResponse](structures/protocol-response.md))

View File

@@ -4,6 +4,16 @@
Process: [Renderer](../glossary.md#renderer-process)
> ⚠️ WARNING ⚠️
> The `remote` module is [deprecated](https://github.com/electron/electron/issues/21408).
> Instead of `remote`, use [`ipcRenderer`](ipc-renderer.md) and
> [`ipcMain`](ipc-main.md).
>
> Read more about why the `remote` module is deprecated [here](https://medium.com/@nornagon/electrons-remote-module-considered-harmful-70d69500f31).
>
> If you still want to use `remote` despite the performance and security
> concerns, see [@electron/remote](https://github.com/electron/remote).
The `remote` module provides a simple way to do inter-process communication
(IPC) between the renderer process (web page) and the main process.
@@ -140,11 +150,32 @@ console.log(app)
The `remote` module has the following methods:
### `remote.require(module)`
### `remote.getCurrentWindow()`
* `module` String
Returns [`BrowserWindow`](browser-window.md) - The window to which this web page
belongs.
Returns `any` - The object returned by `require(module)` in the main process.
**Note:** Do not use `removeAllListeners` on [`BrowserWindow`](browser-window.md).
Use of this can remove all [`blur`](https://developer.mozilla.org/en-US/docs/Web/Events/blur)
listeners, disable click events on touch bar buttons, and other unintended
consequences.
### `remote.getCurrentWebContents()`
Returns [`WebContents`](web-contents.md) - The web contents of this web page.
### `remote.getGlobal(name)`
* `name` String
Returns `any` - The global variable of `name` (e.g. `global[name]`) in the main
process.
## Properties
### `remote.require`
A `NodeJS.Require` function equivalent to `require(module)` in the main process.
Modules specified by their relative path will resolve relative to the entrypoint
of the main process.
@@ -176,28 +207,6 @@ module.exports = 'bar'
const foo = require('electron').remote.require('./foo') // bar
```
### `remote.getCurrentWindow()`
Returns [`BrowserWindow`](browser-window.md) - The window to which this web page
belongs.
**Note:** Do not use `removeAllListeners` on [`BrowserWindow`](browser-window.md).
Use of this can remove all [`blur`](https://developer.mozilla.org/en-US/docs/Web/Events/blur)
listeners, disable click events on touch bar buttons, and other unintended
consequences.
### `remote.getCurrentWebContents()`
Returns [`WebContents`](web-contents.md) - The web contents of this web page.
### `remote.getGlobal(name)`
* `name` String
Returns `any` - The global variable of `name` (e.g. `global[name]`) in the main
process.
## Properties
### `remote.process` _Readonly_

View File

@@ -88,26 +88,17 @@ and preload.js:
```js
// This file is loaded whenever a javascript context is created. It runs in a
// private scope that can access a subset of Electron renderer APIs. We must be
// careful to not leak any objects into the global scope!
const { ipcRenderer, remote } = require('electron')
const fs = remote.require('fs')
// read a configuration file using the `fs` module
const buf = fs.readFileSync('allowed-popup-urls.json')
const allowedUrls = JSON.parse(buf.toString('utf8'))
// private scope that can access a subset of Electron renderer APIs. Without
// contextIsolation enabled, it's possible to accidentally leak privileged
// globals like ipcRenderer to web content.
const { ipcRenderer } = require('electron')
const defaultWindowOpen = window.open
function customWindowOpen (url, ...args) {
if (allowedUrls.indexOf(url) === -1) {
ipcRenderer.sendSync('blocked-popup-notification', location.origin, url)
return null
}
return defaultWindowOpen(url, ...args)
window.open = function customWindowOpen (url, ...args) {
ipcRenderer.send('report-window-open', location.origin, url, args)
return defaultWindowOpen(url + '?from_electron=1', ...args)
}
window.open = customWindowOpen
```
Important things to notice in the preload script:
@@ -115,8 +106,6 @@ Important things to notice in the preload script:
- Even though the sandboxed renderer doesn't have Node.js running, it still has
access to a limited node-like environment: `Buffer`, `process`, `setImmediate`,
`clearImmediate` and `require` are available.
- The preload script can indirectly access all APIs from the main process through the
`remote` and `ipcRenderer` modules.
- The preload script must be contained in a single script, but it is possible to have
complex preload code composed with multiple modules by using a tool like
webpack or browserify. An example of using browserify is below.
@@ -144,15 +133,12 @@ following modules:
- `desktopCapturer`
- `ipcRenderer`
- `nativeImage`
- `remote`
- `webFrame`
- `events`
- `timers`
- `url`
More may be added as needed to expose more Electron APIs in the sandbox, but any
module in the main process can already be used through
`electron.remote.require`.
More may be added as needed to expose more Electron APIs in the sandbox.
## Rendering untrusted content

View File

@@ -91,6 +91,40 @@ session.defaultSession.on('will-download', (event, item, webContents) => {
})
```
#### Event: 'extension-loaded'
Returns:
* `event` Event
* `extension` [Extension](structures/extension.md)
Emitted after an extension is loaded. This occurs whenever an extension is
added to the "enabled" set of extensions. This includes:
- Extensions being loaded from `Session.loadExtension`.
- Extensions being reloaded:
* from a crash.
* if the extension requested it ([`chrome.runtime.reload()`](https://developer.chrome.com/extensions/runtime#method-reload)).
#### Event: 'extension-unloaded'
Returns:
* `event` Event
* `extension` [Extension](structures/extension.md)
Emitted after an extension is unloaded. This occurs when
`Session.removeExtension` is called.
#### Event: 'extension-ready'
Returns:
* `event` Event
* `extension` [Extension](structures/extension.md)
Emitted after an extension is loaded and all necessary browser state is
initialized to support the start of the extension's background page.
#### Event: 'preconnect'
Returns:
@@ -144,6 +178,76 @@ Emitted when a hunspell dictionary file download fails. For details
on the failure you should collect a netlog and inspect the download
request.
#### Event: 'select-serial-port' _Experimental_
Returns:
* `event` Event
* `portList` [SerialPort[]](structures/serial-port.md)
* `webContents` [WebContents](web-contents.md)
* `callback` Function
* `portId` String
Emitted when a serial port needs to be selected when a call to
`navigator.serial.requestPort` is made. `callback` should be called with
`portId` to be selected, passing an empty string to `callback` will
cancel the request. Additionally, permissioning on `navigator.serial` can
be managed by using [ses.setPermissionCheckHandler(handler)](#sessetpermissioncheckhandlerhandler)
with the `serial` permission.
Because this is an experimental feature it is disabled by default. To enable this feature, you
will need to use the `--enable-features=ElectronSerialChooser` command line switch. Additionally
because this is an experimental Chromium feature you will need to set `enableBlinkFeatures: 'Serial'`
on the `webPreferences` property when opening a BrowserWindow.
```javascript
const { app, BrowserWindow } = require('electron')
let win = null
app.commandLine.appendSwitch('enable-features', 'ElectronSerialChooser')
app.whenReady().then(() => {
win = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
enableBlinkFeatures: 'Serial'
}
})
win.webContents.session.on('select-serial-port', (event, portList, callback) => {
event.preventDefault()
const selectedPort = portList.find((device) => {
return device.vendorId === 0x2341 && device.productId === 0x0043
})
if (!selectedPort) {
callback('')
} else {
callback(result1.portId)
}
})
})
```
#### Event: 'serial-port-added' _Experimental_
Returns:
* `event` Event
* `port` [SerialPort](structures/serial-port.md)
* `webContents` [WebContents](web-contents.md)
Emitted after `navigator.serial.requestPort` has been called and `select-serial-port` has fired if a new serial port becomes available. For example, this event will fire when a new USB device is plugged in.
#### Event: 'serial-port-removed' _Experimental_
Returns:
* `event` Event
* `port` [SerialPort](structures/serial-port.md)
* `webContents` [WebContents](web-contents.md)
Emitted after `navigator.serial.requestPort` has been called and `select-serial-port` has fired if a serial port has been removed. For example, this event will fire when a USB device is unplugged.
### Instance Methods
The following methods are available on instances of `Session`:
@@ -386,7 +490,7 @@ session.fromPartition('some-partition').setPermissionRequestHandler((webContents
* `handler` Function<Boolean> | null
* `webContents` [WebContents](web-contents.md) - WebContents checking the permission. Please note that if the request comes from a subframe you should use `requestingUrl` to check the request origin.
* `permission` String - Enum of 'media'.
* `permission` String - Type of permission check. Valid values are `midiSysex`, `notifications`, `geolocation`, `media`,`mediaKeySystem`,`midi`, `pointerLock`, `fullscreen`, `openExternal`, or `serial`.
* `requestingOrigin` String - The origin URL of the permission check
* `details` Object - Some properties are only available on certain permission types.
* `securityOrigin` String - The security origin of the `media` check.
@@ -458,6 +562,20 @@ will be temporary.
Returns `String` - The user agent for this session.
#### `ses.setSSLConfig(config)`
* `config` Object
* `minVersion` String - Can be `tls1`, `tls1.1`, `tls1.2` or `tls1.3`. The
minimum SSL version to allow when connecting to remote servers. Defaults to
`tls1`.
* `maxVersion` String - Can be `tls1.2` or `tls1.3`. The maximum SSL version
to allow when connecting to remote servers. Defaults to `tls1.3`.
Sets the SSL configuration for the session. All subsequent network requests
will use the new configuration. Existing network connections (such as WebSocket
connections) will not be terminated, but old sockets in the pool will not be
reused for new connections.
#### `ses.getBlobData(identifier)`
* `identifier` String - Valid UUID.

View File

@@ -45,15 +45,27 @@ Returns `Promise<void>`
Open the given external protocol URL in the desktop's default manner. (For example, mailto: URLs in the user's default mail agent).
### `shell.moveItemToTrash(fullPath[, deleteOnFail])`
### `shell.moveItemToTrash(fullPath[, deleteOnFail])` _Deprecated_
* `fullPath` String
* `deleteOnFail` Boolean (optional) - Whether or not to unilaterally remove the item if the Trash is disabled or unsupported on the volume. _macOS_
Returns `Boolean` - Whether the item was successfully moved to the trash or otherwise deleted.
> NOTE: This method is deprecated. Use `shell.trashItem` instead.
Move the given file to trash and returns a boolean status for the operation.
### `shell.trashItem(path)`
* `path` String - path to the item to be moved to the trash.
Returns `Promise<void>` - Resolves when the operation has been completed.
Rejects if there was an error while deleting the requested item.
This moves a path to the OS-specific trash location (Trash on macOS, Recycle
Bin on Windows, and a desktop-environment-specific location on Linux).
### `shell.beep()`
Play the beep sound.

View File

@@ -0,0 +1,8 @@
# SerialPort Object
* `portId` String - Unique identifier for the port
* `portName` String - Name of the port
* `displayName` String - Addtional information for the port
* `persistentId` String - This platform-specific identifier, if present, can be used to identify the device across restarts of the application and operating system.
* `vendorId` String - Optional USB vendor ID
* `productId` String - Optional USB product ID

View File

@@ -13,3 +13,5 @@ target's icon.
DLL or EXE. Default is 0.
* `appUserModelId` String (optional) - The Application User Model ID. Default
is empty.
* `toastActivatorClsid` String (optional) - The Application Toast Activator CLSID. Needed
for participating in Action Center.

View File

@@ -1,5 +0,0 @@
# StreamProtocolResponse Object
* `statusCode` Number (optional) - The HTTP response code.
* `headers` Record<String, String | String[]> (optional) - An object containing the response headers.
* `data` ReadableStream | null - A Node.js readable stream representing the response body.

View File

@@ -1,5 +0,0 @@
# StringProtocolResponse Object
* `mimeType` String (optional) - MIME type of the response.
* `charset` String (optional) - Charset of the response.
* `data` String | null - A string representing the response body.

View File

@@ -9,7 +9,7 @@ the [native modules](../tutorial/using-native-node-modules.md)).
Electron also provides some extra built-in modules for developing native
desktop applications. Some modules are only available in the main process, some
are only available in the renderer process (web page), and some can be used in
both processes.
either process type.
The basic rule is: if a module is [GUI][gui] or low-level system related, then
it should be only available in the main process. You need to be familiar with
@@ -29,15 +29,15 @@ app.whenReady().then(() => {
```
The renderer process is no different than a normal web page, except for the
extra ability to use node modules:
extra ability to use node modules if `nodeIntegration` is enabled:
```html
<!DOCTYPE html>
<html>
<body>
<script>
const { app } = require('electron').remote
console.log(app.getVersion())
const fs = require('fs')
console.log(fs.readFileSync(__filename, 'utf8'))
</script>
</body>
</html>

View File

@@ -364,7 +364,7 @@ Returns:
* `killed` - Process was sent a SIGTERM or otherwise killed externally
* `crashed` - Process crashed
* `oom` - Process ran out of memory
* `launch-failure` - Process never successfully launched
* `launch-failed` - Process never successfully launched
* `integrity-failure` - Windows code integrity checks failed
Emitted when the renderer process unexpectedly disappears. This is normally
@@ -784,7 +784,7 @@ Returns:
Emitted when `desktopCapturer.getSources()` is called in the renderer process.
Calling `event.preventDefault()` will make it return empty sources.
#### Event: 'remote-require'
#### Event: 'remote-require' _Deprecated_
Returns:
@@ -795,7 +795,7 @@ Emitted when `remote.require()` is called in the renderer process.
Calling `event.preventDefault()` will prevent the module from being returned.
Custom value can be returned by setting `event.returnValue`.
#### Event: 'remote-get-global'
#### Event: 'remote-get-global' _Deprecated_
Returns:
@@ -806,7 +806,7 @@ Emitted when `remote.getGlobal()` is called in the renderer process.
Calling `event.preventDefault()` will prevent the global from being returned.
Custom value can be returned by setting `event.returnValue`.
#### Event: 'remote-get-builtin'
#### Event: 'remote-get-builtin' _Deprecated_
Returns:
@@ -817,7 +817,7 @@ Emitted when `remote.getBuiltin()` is called in the renderer process.
Calling `event.preventDefault()` will prevent the module from being returned.
Custom value can be returned by setting `event.returnValue`.
#### Event: 'remote-get-current-window'
#### Event: 'remote-get-current-window' _Deprecated_
Returns:
@@ -827,7 +827,7 @@ Emitted when `remote.getCurrentWindow()` is called in the renderer process.
Calling `event.preventDefault()` will prevent the object from being returned.
Custom value can be returned by setting `event.returnValue`.
#### Event: 'remote-get-current-web-contents'
#### Event: 'remote-get-current-web-contents' _Deprecated_
Returns:
@@ -998,6 +998,34 @@ Navigates to the specified offset from the "current entry".
Returns `Boolean` - Whether the renderer process has crashed.
#### `contents.forcefullyCrashRenderer()`
Forcefully terminates the renderer process that is currently hosting this
`webContents`. This will cause the `render-process-gone` event to be emitted
with the `reason=killed || reason=crashed`. Please note that some webContents share renderer
processes and therefore calling this method may also crash the host process
for other webContents as well.
Calling `reload()` immediately after calling this
method will force the reload to occur in a new process. This should be used
when this process is unstable or unusable, for instance in order to recover
from the `unresponsive` event.
```js
contents.on('unresponsive', async () => {
const { response } = await dialog.showMessageBox({
message: 'App X has become unresponsive',
title: 'Do you want to try forcefully reloading the app?',
buttons: ['OK', 'Cancel'],
cancelId: 1
})
if (response === 0) {
contents.forcefullyCrashRenderer()
contents.reload()
}
})
```
#### `contents.setUserAgent(userAgent)`
* `userAgent` String
@@ -1117,6 +1145,10 @@ increment above or below represents zooming 20% larger or smaller to default
limits of 300% and 50% of original size, respectively. The formula for this is
`scale := 1.2 ^ level`.
> **NOTE**: The zoom policy at the Chromium level is same-origin, meaning that the
> zoom level for a specific domain propagates across all instances of windows with
> the same domain. Differentiating the window URLs will make zoom work per-window.
#### `contents.getZoomLevel()`
Returns `Number` - the current zoom level.
@@ -1208,12 +1240,6 @@ Inserts `text` to the focused element.
defaults to `false`.
* `matchCase` Boolean (optional) - Whether search should be case-sensitive,
defaults to `false`.
* `wordStart` Boolean (optional) - Whether to look only at the start of words.
defaults to `false`.
* `medialCapitalAsWordStart` Boolean (optional) - When combined with `wordStart`,
accepts a match in the middle of a word if the match begins with an
uppercase letter followed by a lowercase or non-letter.
Accepts several other intra-word matches, defaults to `false`.
Returns `Integer` - The request id used for the request.
@@ -1296,9 +1322,9 @@ Returns [`PrinterInfo[]`](structures/printer-info.md)
* `pagesPerSheet` Number (optional) - The number of pages to print per page sheet.
* `collate` Boolean (optional) - Whether the web page should be collated.
* `copies` Number (optional) - The number of copies of the web page to print.
* `pageRanges` Record<string, number> (optional) - The page range to print.
* `from` Number - the start page.
* `to` Number - the end page.
* `pageRanges` Object[] (optional) - The page range to print. On macOS, only one range is honored.
* `from` Number - Index of the first page to print (0-based).
* `to` Number - Index of the last page to print (inclusive) (0-based).
* `duplexMode` String (optional) - Set the duplex mode of the printed web page. Can be `simplex`, `shortEdge`, or `longEdge`.
* `dpi` Record<string, number> (optional)
* `horizontal` Number (optional) - The horizontal dpi.
@@ -1324,10 +1350,10 @@ Example usage:
const options = {
silent: true,
deviceName: 'My-Printer',
pageRanges: {
pageRanges: [{
from: 0,
to: 1
}
}]
}
win.webContents.print(options, (success, errorType) => {
if (!success) console.log(errorType)
@@ -1345,8 +1371,8 @@ win.webContents.print(options, (success, errorType) => {
default margin, 1 for no margin, and 2 for minimum margin.
* `scaleFactor` Number (optional) - The scale factor of the web page. Can range from 0 to 100.
* `pageRanges` Record<string, number> (optional) - The page range to print.
* `from` Number - zero-based index of the first page to print.
* `to` Number - zero-based index of the last page to print (inclusive).
* `from` Number - Index of the first page to print (0-based).
* `to` Number - Index of the last page to print (inclusive) (0-based).
* `pageSize` String | Size (optional) - Specify page size of the generated PDF. Can be `A3`,
`A4`, `A5`, `Legal`, `Letter`, `Tabloid` or an Object containing `height` and `width` in microns.
* `printBackground` Boolean (optional) - Whether to print CSS backgrounds.
@@ -1453,7 +1479,7 @@ An example of showing devtools in a `<webview>` tag:
<webview id="browser" src="https://github.com"></webview>
<webview id="devtools" src="about:blank"></webview>
<script>
const { webContents } = require('electron').remote
const { ipcRenderer } = require('electron')
const emittedOnce = (element, eventName) => new Promise(resolve => {
element.addEventListener(eventName, event => resolve(event), { once: true })
})
@@ -1462,16 +1488,26 @@ An example of showing devtools in a `<webview>` tag:
const browserReady = emittedOnce(browserView, 'dom-ready')
const devtoolsReady = emittedOnce(devtoolsView, 'dom-ready')
Promise.all([browserReady, devtoolsReady]).then(() => {
const browser = webContents.fromId(browserView.getWebContentsId())
const devtools = webContents.fromId(devtoolsView.getWebContentsId())
browser.setDevToolsWebContents(devtools)
browser.openDevTools()
const targetId = browserView.getWebContentsId()
const devtoolsId = devtoolsView.getWebContentsId()
ipcRenderer.send('open-devtools', targetId, devtoolsId)
})
</script>
</body>
</html>
```
```js
// Main process
const { ipcMain, webContents } = require('electron')
ipcMain.on('open-devtools', (event, targetContentsId, devtoolsContentsId) => {
const target = webContents.fromId(targetContentsId)
const devtools = webContents.fromId(devtoolsContentsId)
target.setDevToolsWebContents(devtools)
target.openDevTools()
})
```
An example of showing devtools in a `BrowserWindow`:
```js

View File

@@ -41,6 +41,10 @@ Changes the zoom level to the specified level. The original size is 0 and each
increment above or below represents zooming 20% larger or smaller to default
limits of 300% and 50% of original size, respectively.
> **NOTE**: The zoom policy at the Chromium level is same-origin, meaning that the
> zoom level for a specific domain propagates across all instances of windows with
> the same domain. Differentiating the window URLs will make zoom work per-window.
### `webFrame.getZoomLevel()`
Returns `Number` - The current zoom level.

View File

@@ -137,7 +137,7 @@ This option is disabled by default in the guest page.
```
A `Boolean`. When this attribute is `false` the guest page in `webview` will not have access
to the [`remote`](remote.md) module. The remote module is available by default.
to the [`remote`](remote.md) module. The remote module is unavailable by default.
### `plugins`
@@ -519,12 +519,6 @@ Inserts `text` to the focused element.
defaults to `false`.
* `matchCase` Boolean (optional) - Whether search should be case-sensitive,
defaults to `false`.
* `wordStart` Boolean (optional) - Whether to look only at the start of words.
defaults to `false`.
* `medialCapitalAsWordStart` Boolean (optional) - When combined with `wordStart`,
accepts a match in the middle of a word if the match begins with an
uppercase letter followed by a lowercase or non-letter.
Accepts several other intra-word matches, defaults to `false`.
Returns `Integer` - The request id used for the request.
@@ -560,9 +554,9 @@ Stops any `findInPage` request for the `webview` with the provided `action`.
* `pagesPerSheet` Number (optional) - The number of pages to print per page sheet.
* `collate` Boolean (optional) - Whether the web page should be collated.
* `copies` Number (optional) - The number of copies of the web page to print.
* `pageRanges` Record<string, number> (optional) - The page range to print.
* `from` Number - zero-based index of the first page to print.
* `to` Number - zero-based index of the last page to print (inclusive).
* `pageRanges` Object[] (optional) - The page range to print.
* `from` Number - Index of the first page to print (0-based).
* `to` Number - Index of the last page to print (inclusive) (0-based).
* `duplexMode` String (optional) - Set the duplex mode of the printed web page. Can be `simplex`, `shortEdge`, or `longEdge`.
* `dpi` Record<string, number> (optional)
* `horizontal` Number (optional) - The horizontal dpi.
@@ -587,9 +581,9 @@ Prints `webview`'s web page. Same as `webContents.print([options])`.
default margin, 1 for no margin, and 2 for minimum margin.
and `width` in microns.
* `scaleFactor` Number (optional) - The scale factor of the web page. Can range from 0 to 100.
* `pageRanges` Record<string, number> (optional) - The page range to print.
* `from` Number - the first page to print.
* `to` Number - the last page to print (inclusive).
* `pageRanges` Record<string, number> (optional) - The page range to print. On macOS, only the first range is honored.
* `from` Number - Index of the first page to print (0-based).
* `to` Number - Index of the last page to print (inclusive) (0-based).
* `pageSize` String | Size (optional) - Specify page size of the generated PDF. Can be `A3`,
`A4`, `A5`, `Legal`, `Letter`, `Tabloid` or an Object containing `height`
* `printBackground` Boolean (optional) - Whether to print CSS backgrounds.
@@ -648,6 +642,10 @@ increment above or below represents zooming 20% larger or smaller to default
limits of 300% and 50% of original size, respectively. The formula for this is
`scale := 1.2 ^ level`.
> **NOTE**: The zoom policy at the Chromium level is same-origin, meaning that the
> zoom level for a specific domain propagates across all instances of windows with
> the same domain. Differentiating the window URLs will make zoom work per-window.
### `<webview>.getZoomFactor()`
Returns `Number` - the current zoom factor.

View File

@@ -12,6 +12,20 @@ This document uses the following convention to categorize breaking changes:
- **Deprecated:** An API was marked as deprecated. The API will continue to function, but will emit a deprecation warning, and will be removed in a future release.
- **Removed:** An API or feature was removed, and is no longer supported by Electron.
## Planned Breaking API Changes (13.0)
### Removed: `shell.moveItemToTrash()`
The deprecated synchronous `shell.moveItemToTrash()` API has been removed. Use
the asynchronous `shell.trashItem()` instead.
```js
// Removed in Electron 13
shell.moveItemToTrash(path)
// Replace with
shell.trashItem(path).then(/* ... */)
```
## Planned Breaking API Changes (12.0)
### Default Changed: `contextIsolation` defaults to `true`
@@ -50,6 +64,37 @@ If your crash ingestion server does not support compressed payloads, you can
turn off compression by specifying `{ compress: false }` in the crash reporter
options.
### Deprecated: `remote` module
The `remote` module is deprecated in Electron 12, and will be removed in
Electron 14. It is replaced by the
[`@electron/remote`](https://github.com/electron/remote) module.
```js
// Deprecated in Electron 12:
const { BrowserWindow } = require('electron').remote
```
```js
// Replace with:
const { BrowserWindow } = require('@electron/remote')
// In the main process:
require('@electron/remote/main').initialize()
```
### Deprecated: `shell.moveItemToTrash()`
The synchronous `shell.moveItemToTrash()` has been replaced by the new,
asynchronous `shell.trashItem()`.
```js
// Deprecated in Electron 12
shell.moveItemToTrash(path)
// Replace with
shell.trashItem(path).then(/* ... */)
```
## Planned Breaking API Changes (11.0)
There are no breaking changes planned for 11.0.

View File

@@ -4,8 +4,8 @@ These guides are intended for people working on the Electron project itself.
For guides on Electron app development, see
[/docs/README.md](../README.md#guides-and-tutorials).
* [Code of Conduct](../../CODE_OF_CONDUCT.md)
* [Contributing to Electron](../../CONTRIBUTING.md)
* [Code of Conduct](https://github.com/electron/electron/blob/master/CODE_OF_CONDUCT.md)
* [Contributing to Electron](https://github.com/electron/electron/blob/master/CONTRIBUTING.md)
* [Issues](issues.md)
* [Pull Requests](pull-requests.md)
* [Documentation Styleguide](coding-style.md#documentation)

View File

@@ -69,8 +69,7 @@ way of figuring out which is which.
### Which Process Should I Attach to?
Code executed within the main process (that is, code found in or eventually run
by your main JavaScript file) as well as code called using the remote
(`require('electron').remote`) will run inside the main process, while other
by your main JavaScript file) will run inside the main process, while other
code will execute inside its respective renderer process.
You can be attached to multiple programs when you are debugging, but only one

View File

@@ -101,33 +101,5 @@ script/ - The set of all scripts Electron runs for a variety of purposes.
* **tools** - Helper scripts used by GN files.
* Scripts put here should never be invoked by users directly, unlike those in `script`.
* **typings** - TypeScript typings for Electron's internal code.
* **vendor** - Source code for some third party dependencies, including `boto` and `requests`.
* **vendor** - Source code for some third party dependencies.
## Keeping Git Submodules Up to Date
The Electron repository has a few vendored dependencies, found in the
[/vendor][vendor] directory. Occasionally you might see a message like this
when running `git status`:
```sh
$ git status
modified: vendor/depot_tools (new commits)
modified: vendor/boto (new commits)
```
To update these vendored dependencies, run the following command:
```sh
git submodule update --init --recursive
```
If you find yourself running this command often, you can create an alias for it
in your `~/.gitconfig` file:
```sh
[alias]
su = submodule update --init --recursive
```
[vendor]: https://github.com/electron/electron/tree/master/vendor

View File

@@ -1,7 +1,11 @@
const { BrowserWindow, app } = require('electron')
const { BrowserWindow, app, screen, ipcMain } = require('electron')
let mainWindow = null
ipcMain.handle('get-screen-size', () => {
return screen.getPrimaryDisplay().workAreaSize
})
function createWindow () {
const windowOptions = {
width: 600,

View File

@@ -1,5 +1,4 @@
const { desktopCapturer } = require('electron')
const { screen, shell } = require('electron').remote
const { desktopCapturer, shell, ipcRenderer } = require('electron')
const fs = require('fs')
const os = require('os')
@@ -8,9 +7,9 @@ const path = require('path')
const screenshot = document.getElementById('screen-shot')
const screenshotMsg = document.getElementById('screenshot-path')
screenshot.addEventListener('click', (event) => {
screenshot.addEventListener('click', async (event) => {
screenshotMsg.textContent = 'Gathering screens...'
const thumbSize = determineScreenShotSize()
const thumbSize = await determineScreenShotSize()
const options = { types: ['screen'], thumbnailSize: thumbSize }
desktopCapturer.getSources(options, (error, sources) => {
@@ -33,8 +32,8 @@ screenshot.addEventListener('click', (event) => {
})
})
function determineScreenShotSize () {
const screenSize = screen.getPrimaryDisplay().workAreaSize
async function determineScreenShotSize () {
const screenSize = await ipcRenderer.invoke('get-screen-size')
const maxDimension = Math.max(screenSize.width, screenSize.height)
return {
width: maxDimension * window.devicePixelRatio,

View File

@@ -1,95 +1,95 @@
// Modules to control application life and create native browser window
const { app, BrowserWindow, ipcMain, dialog } = require('electron')
// Keep a global reference of the window object, if you don't, the window will
// be closed automatically when the JavaScript object is garbage collected.
let mainWindow
function createWindow () {
// Create the browser window.
mainWindow = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
nodeIntegration: true
}
})
// and load the index.html of the app.
mainWindow.loadFile('index.html')
// Open the DevTools.
// mainWindow.webContents.openDevTools()
// Emitted when the window is closed.
mainWindow.on('closed', function () {
// Dereference the window object, usually you would store windows
// in an array if your app supports multi windows, this is the time
// when you should delete the corresponding element.
mainWindow = null
})
}
// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs.
app.whenReady().then(createWindow)
// Quit when all windows are closed.
app.on('window-all-closed', function () {
// On macOS it is common for applications and their menu bar
// to stay active until the user quits explicitly with Cmd + Q
if (process.platform !== 'darwin') {
app.quit()
}
})
app.on('activate', function () {
// On macOS it is common to re-create a window in the app when the
// dock icon is clicked and there are no other windows open.
if (mainWindow === null) {
createWindow()
}
})
ipcMain.on('open-error-dialog', event => {
dialog.showErrorBox('An Error Message', 'Demonstrating an error message.')
})
ipcMain.on('open-information-dialog', event => {
const options = {
type: 'info',
title: 'Information',
message: "This is an information dialog. Isn't it nice?",
buttons: ['Yes', 'No']
}
dialog.showMessageBox(options, index => {
event.sender.send('information-dialog-selection', index)
})
})
ipcMain.on('open-file-dialog', event => {
dialog.showOpenDialog(
{
properties: ['openFile', 'openDirectory']
},
files => {
if (files) {
event.sender.send('selected-directory', files)
}
}
)
})
ipcMain.on('save-dialog', event => {
const options = {
title: 'Save an Image',
filters: [{ name: 'Images', extensions: ['jpg', 'png', 'gif'] }]
}
dialog.showSaveDialog(options, filename => {
event.sender.send('saved-file', filename)
})
})
// In this file you can include the rest of your app's specific main process
// code. You can also put them in separate files and require them here.
// Modules to control application life and create native browser window
const { app, BrowserWindow, ipcMain, dialog } = require('electron')
// Keep a global reference of the window object, if you don't, the window will
// be closed automatically when the JavaScript object is garbage collected.
let mainWindow
function createWindow () {
// Create the browser window.
mainWindow = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
nodeIntegration: true
}
})
// and load the index.html of the app.
mainWindow.loadFile('index.html')
// Open the DevTools.
// mainWindow.webContents.openDevTools()
// Emitted when the window is closed.
mainWindow.on('closed', function () {
// Dereference the window object, usually you would store windows
// in an array if your app supports multi windows, this is the time
// when you should delete the corresponding element.
mainWindow = null
})
}
// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs.
app.whenReady().then(createWindow)
// Quit when all windows are closed.
app.on('window-all-closed', function () {
// On macOS it is common for applications and their menu bar
// to stay active until the user quits explicitly with Cmd + Q
if (process.platform !== 'darwin') {
app.quit()
}
})
app.on('activate', function () {
// On macOS it is common to re-create a window in the app when the
// dock icon is clicked and there are no other windows open.
if (mainWindow === null) {
createWindow()
}
})
ipcMain.on('open-error-dialog', event => {
dialog.showErrorBox('An Error Message', 'Demonstrating an error message.')
})
ipcMain.on('open-information-dialog', event => {
const options = {
type: 'info',
title: 'Information',
message: "This is an information dialog. Isn't it nice?",
buttons: ['Yes', 'No']
}
dialog.showMessageBox(options, index => {
event.sender.send('information-dialog-selection', index)
})
})
ipcMain.on('open-file-dialog', event => {
dialog.showOpenDialog(
{
properties: ['openFile', 'openDirectory']
},
files => {
if (files) {
event.sender.send('selected-directory', files)
}
}
)
})
ipcMain.on('save-dialog', event => {
const options = {
title: 'Save an Image',
filters: [{ name: 'Images', extensions: ['jpg', 'png', 'gif'] }]
}
dialog.showSaveDialog(options, filename => {
event.sender.send('saved-file', filename)
})
})
// In this file you can include the rest of your app's specific main process
// code. You can also put them in separate files and require them here.

View File

@@ -1,18 +1,18 @@
const { ipcRenderer, shell } = require('electron')
const links = document.querySelectorAll('a[href]')
const errorBtn = document.getElementById('error-dialog')
errorBtn.addEventListener('click', event => {
ipcRenderer.send('open-error-dialog')
})
Array.prototype.forEach.call(links, (link) => {
const url = link.getAttribute('href')
if (url.indexOf('http') === 0) {
link.addEventListener('click', (e) => {
e.preventDefault()
shell.openExternal(url)
})
}
const { ipcRenderer, shell } = require('electron')
const links = document.querySelectorAll('a[href]')
const errorBtn = document.getElementById('error-dialog')
errorBtn.addEventListener('click', event => {
ipcRenderer.send('open-error-dialog')
})
Array.prototype.forEach.call(links, (link) => {
const url = link.getAttribute('href')
if (url.indexOf('http') === 0) {
link.addEventListener('click', (e) => {
e.preventDefault()
shell.openExternal(url)
})
}
})

View File

@@ -1,70 +1,70 @@
// Modules to control application life and create native browser window
const { app, BrowserWindow, ipcMain, dialog } = require('electron')
// Keep a global reference of the window object, if you don't, the window will
// be closed automatically when the JavaScript object is garbage collected.
let mainWindow
function createWindow () {
// Create the browser window.
mainWindow = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
nodeIntegration: true
}
})
// and load the index.html of the app.
mainWindow.loadFile('index.html')
// Open the DevTools.
// mainWindow.webContents.openDevTools()
// Emitted when the window is closed.
mainWindow.on('closed', function () {
// Dereference the window object, usually you would store windows
// in an array if your app supports multi windows, this is the time
// when you should delete the corresponding element.
mainWindow = null
})
}
// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs.
app.whenReady().then(createWindow)
// Quit when all windows are closed.
app.on('window-all-closed', function () {
// On macOS it is common for applications and their menu bar
// to stay active until the user quits explicitly with Cmd + Q
if (process.platform !== 'darwin') {
app.quit()
}
})
app.on('activate', function () {
// On macOS it is common to re-create a window in the app when the
// dock icon is clicked and there are no other windows open.
if (mainWindow === null) {
createWindow()
}
})
ipcMain.on('open-information-dialog', event => {
const options = {
type: 'info',
title: 'Information',
message: "This is an information dialog. Isn't it nice?",
buttons: ['Yes', 'No']
}
dialog.showMessageBox(options, index => {
event.sender.send('information-dialog-selection', index)
})
})
// In this file you can include the rest of your app's specific main process
// code. You can also put them in separate files and require them here.
// Modules to control application life and create native browser window
const { app, BrowserWindow, ipcMain, dialog } = require('electron')
// Keep a global reference of the window object, if you don't, the window will
// be closed automatically when the JavaScript object is garbage collected.
let mainWindow
function createWindow () {
// Create the browser window.
mainWindow = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
nodeIntegration: true
}
})
// and load the index.html of the app.
mainWindow.loadFile('index.html')
// Open the DevTools.
// mainWindow.webContents.openDevTools()
// Emitted when the window is closed.
mainWindow.on('closed', function () {
// Dereference the window object, usually you would store windows
// in an array if your app supports multi windows, this is the time
// when you should delete the corresponding element.
mainWindow = null
})
}
// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs.
app.whenReady().then(createWindow)
// Quit when all windows are closed.
app.on('window-all-closed', function () {
// On macOS it is common for applications and their menu bar
// to stay active until the user quits explicitly with Cmd + Q
if (process.platform !== 'darwin') {
app.quit()
}
})
app.on('activate', function () {
// On macOS it is common to re-create a window in the app when the
// dock icon is clicked and there are no other windows open.
if (mainWindow === null) {
createWindow()
}
})
ipcMain.on('open-information-dialog', event => {
const options = {
type: 'info',
title: 'Information',
message: "This is an information dialog. Isn't it nice?",
buttons: ['Yes', 'No']
}
dialog.showMessageBox(options, index => {
event.sender.send('information-dialog-selection', index)
})
})
// In this file you can include the rest of your app's specific main process
// code. You can also put them in separate files and require them here.

View File

@@ -1,25 +1,25 @@
const { ipcRenderer, shell } = require('electron')
const informationBtn = document.getElementById('information-dialog')
const links = document.querySelectorAll('a[href]')
informationBtn.addEventListener('click', event => {
ipcRenderer.send('open-information-dialog')
})
ipcRenderer.on('information-dialog-selection', (event, index) => {
let message = 'You selected '
if (index === 0) message += 'yes.'
else message += 'no.'
document.getElementById('info-selection').innerHTML = message
})
Array.prototype.forEach.call(links, (link) => {
const url = link.getAttribute('href')
if (url.indexOf('http') === 0) {
link.addEventListener('click', (e) => {
e.preventDefault()
shell.openExternal(url)
})
}
const { ipcRenderer, shell } = require('electron')
const informationBtn = document.getElementById('information-dialog')
const links = document.querySelectorAll('a[href]')
informationBtn.addEventListener('click', event => {
ipcRenderer.send('open-information-dialog')
})
ipcRenderer.on('information-dialog-selection', (event, index) => {
let message = 'You selected '
if (index === 0) message += 'yes.'
else message += 'no.'
document.getElementById('info-selection').innerHTML = message
})
Array.prototype.forEach.call(links, (link) => {
const url = link.getAttribute('href')
if (url.indexOf('http') === 0) {
link.addEventListener('click', (e) => {
e.preventDefault()
shell.openExternal(url)
})
}
})

View File

@@ -1,70 +1,70 @@
// Modules to control application life and create native browser window
const { app, BrowserWindow, ipcMain, dialog } = require('electron')
// Keep a global reference of the window object, if you don't, the window will
// be closed automatically when the JavaScript object is garbage collected.
let mainWindow
function createWindow () {
// Create the browser window.
mainWindow = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
nodeIntegration: true
}
})
// and load the index.html of the app.
mainWindow.loadFile('index.html')
// Open the DevTools.
// mainWindow.webContents.openDevTools()
// Emitted when the window is closed.
mainWindow.on('closed', function () {
// Dereference the window object, usually you would store windows
// in an array if your app supports multi windows, this is the time
// when you should delete the corresponding element.
mainWindow = null
})
}
// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs.
app.whenReady().then(createWindow)
// Quit when all windows are closed.
app.on('window-all-closed', function () {
// On macOS it is common for applications and their menu bar
// to stay active until the user quits explicitly with Cmd + Q
if (process.platform !== 'darwin') {
app.quit()
}
})
app.on('activate', function () {
// On macOS it is common to re-create a window in the app when the
// dock icon is clicked and there are no other windows open.
if (mainWindow === null) {
createWindow()
}
})
ipcMain.on('open-file-dialog', event => {
dialog.showOpenDialog(
{
properties: ['openFile', 'openDirectory']
},
files => {
if (files) {
event.sender.send('selected-directory', files)
}
}
)
})
// In this file you can include the rest of your app's specific main process
// code. You can also put them in separate files and require them here.
// Modules to control application life and create native browser window
const { app, BrowserWindow, ipcMain, dialog } = require('electron')
// Keep a global reference of the window object, if you don't, the window will
// be closed automatically when the JavaScript object is garbage collected.
let mainWindow
function createWindow () {
// Create the browser window.
mainWindow = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
nodeIntegration: true
}
})
// and load the index.html of the app.
mainWindow.loadFile('index.html')
// Open the DevTools.
// mainWindow.webContents.openDevTools()
// Emitted when the window is closed.
mainWindow.on('closed', function () {
// Dereference the window object, usually you would store windows
// in an array if your app supports multi windows, this is the time
// when you should delete the corresponding element.
mainWindow = null
})
}
// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs.
app.whenReady().then(createWindow)
// Quit when all windows are closed.
app.on('window-all-closed', function () {
// On macOS it is common for applications and their menu bar
// to stay active until the user quits explicitly with Cmd + Q
if (process.platform !== 'darwin') {
app.quit()
}
})
app.on('activate', function () {
// On macOS it is common to re-create a window in the app when the
// dock icon is clicked and there are no other windows open.
if (mainWindow === null) {
createWindow()
}
})
ipcMain.on('open-file-dialog', event => {
dialog.showOpenDialog(
{
properties: ['openFile', 'openDirectory']
},
files => {
if (files) {
event.sender.send('selected-directory', files)
}
}
)
})
// In this file you can include the rest of your app's specific main process
// code. You can also put them in separate files and require them here.

View File

@@ -1,22 +1,22 @@
const { ipcRenderer, shell } = require('electron')
const selectDirBtn = document.getElementById('select-directory')
const links = document.querySelectorAll('a[href]')
selectDirBtn.addEventListener('click', event => {
ipcRenderer.send('open-file-dialog')
})
ipcRenderer.on('selected-directory', (event, path) => {
document.getElementById('selected-file').innerHTML = `You selected: ${path}`
})
Array.prototype.forEach.call(links, (link) => {
const url = link.getAttribute('href')
if (url.indexOf('http') === 0) {
link.addEventListener('click', (e) => {
e.preventDefault()
shell.openExternal(url)
})
}
})
const { ipcRenderer, shell } = require('electron')
const selectDirBtn = document.getElementById('select-directory')
const links = document.querySelectorAll('a[href]')
selectDirBtn.addEventListener('click', event => {
ipcRenderer.send('open-file-dialog')
})
ipcRenderer.on('selected-directory', (event, path) => {
document.getElementById('selected-file').innerHTML = `You selected: ${path}`
})
Array.prototype.forEach.call(links, (link) => {
const url = link.getAttribute('href')
if (url.indexOf('http') === 0) {
link.addEventListener('click', (e) => {
e.preventDefault()
shell.openExternal(url)
})
}
})

View File

@@ -1,66 +1,66 @@
// Modules to control application life and create native browser window
const { app, BrowserWindow, ipcMain, dialog } = require('electron')
// Keep a global reference of the window object, if you don't, the window will
// be closed automatically when the JavaScript object is garbage collected.
let mainWindow
function createWindow () {
// Create the browser window.
mainWindow = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
nodeIntegration: true
}
})
// and load the index.html of the app.
mainWindow.loadFile('index.html')
// Open the DevTools.
// mainWindow.webContents.openDevTools()
// Emitted when the window is closed.
mainWindow.on('closed', function () {
// Dereference the window object, usually you would store windows
// in an array if your app supports multi windows, this is the time
// when you should delete the corresponding element.
mainWindow = null
})
}
// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs.
app.whenReady().then(createWindow)
// Quit when all windows are closed.
app.on('window-all-closed', function () {
// On macOS it is common for applications and their menu bar
// to stay active until the user quits explicitly with Cmd + Q
if (process.platform !== 'darwin') {
app.quit()
}
})
app.on('activate', function () {
// On macOS it is common to re-create a window in the app when the
// dock icon is clicked and there are no other windows open.
if (mainWindow === null) {
createWindow()
}
})
ipcMain.on('save-dialog', event => {
const options = {
title: 'Save an Image',
filters: [{ name: 'Images', extensions: ['jpg', 'png', 'gif'] }]
}
dialog.showSaveDialog(options, filename => {
event.sender.send('saved-file', filename)
})
})
// In this file you can include the rest of your app's specific main process
// code. You can also put them in separate files and require them here.
// Modules to control application life and create native browser window
const { app, BrowserWindow, ipcMain, dialog } = require('electron')
// Keep a global reference of the window object, if you don't, the window will
// be closed automatically when the JavaScript object is garbage collected.
let mainWindow
function createWindow () {
// Create the browser window.
mainWindow = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
nodeIntegration: true
}
})
// and load the index.html of the app.
mainWindow.loadFile('index.html')
// Open the DevTools.
// mainWindow.webContents.openDevTools()
// Emitted when the window is closed.
mainWindow.on('closed', function () {
// Dereference the window object, usually you would store windows
// in an array if your app supports multi windows, this is the time
// when you should delete the corresponding element.
mainWindow = null
})
}
// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs.
app.whenReady().then(createWindow)
// Quit when all windows are closed.
app.on('window-all-closed', function () {
// On macOS it is common for applications and their menu bar
// to stay active until the user quits explicitly with Cmd + Q
if (process.platform !== 'darwin') {
app.quit()
}
})
app.on('activate', function () {
// On macOS it is common to re-create a window in the app when the
// dock icon is clicked and there are no other windows open.
if (mainWindow === null) {
createWindow()
}
})
ipcMain.on('save-dialog', event => {
const options = {
title: 'Save an Image',
filters: [{ name: 'Images', extensions: ['jpg', 'png', 'gif'] }]
}
dialog.showSaveDialog(options, filename => {
event.sender.send('saved-file', filename)
})
})
// In this file you can include the rest of your app's specific main process
// code. You can also put them in separate files and require them here.

View File

@@ -1,23 +1,23 @@
const { ipcRenderer, shell } = require('electron')
const saveBtn = document.getElementById('save-dialog')
const links = document.querySelectorAll('a[href]')
saveBtn.addEventListener('click', event => {
ipcRenderer.send('save-dialog')
})
ipcRenderer.on('saved-file', (event, path) => {
if (!path) path = 'No path'
document.getElementById('file-saved').innerHTML = `Path selected: ${path}`
})
Array.prototype.forEach.call(links, (link) => {
const url = link.getAttribute('href')
if (url.indexOf('http') === 0) {
link.addEventListener('click', (e) => {
e.preventDefault()
shell.openExternal(url)
})
}
const { ipcRenderer, shell } = require('electron')
const saveBtn = document.getElementById('save-dialog')
const links = document.querySelectorAll('a[href]')
saveBtn.addEventListener('click', event => {
ipcRenderer.send('save-dialog')
})
ipcRenderer.on('saved-file', (event, path) => {
if (!path) path = 'No path'
document.getElementById('file-saved').innerHTML = `Path selected: ${path}`
})
Array.prototype.forEach.call(links, (link) => {
const url = link.getAttribute('href')
if (url.indexOf('http') === 0) {
link.addEventListener('click', (e) => {
e.preventDefault()
shell.openExternal(url)
})
}
})

View File

@@ -1,56 +1,56 @@
// Modules to control application life and create native browser window
const { app, BrowserWindow } = require('electron')
// Keep a global reference of the window object, if you don't, the window will
// be closed automatically when the JavaScript object is garbage collected.
let mainWindow
function createWindow () {
// Create the browser window.
mainWindow = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
nodeIntegration: true
}
})
// and load the index.html of the app.
mainWindow.loadFile('index.html')
// Open the DevTools.
// mainWindow.webContents.openDevTools()
// Emitted when the window is closed.
mainWindow.on('closed', function () {
// Dereference the window object, usually you would store windows
// in an array if your app supports multi windows, this is the time
// when you should delete the corresponding element.
mainWindow = null
})
}
// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs.
app.whenReady().then(createWindow)
// Quit when all windows are closed.
app.on('window-all-closed', function () {
// On macOS it is common for applications and their menu bar
// to stay active until the user quits explicitly with Cmd + Q
if (process.platform !== 'darwin') {
app.quit()
}
})
app.on('activate', function () {
// On macOS it is common to re-create a window in the app when the
// dock icon is clicked and there are no other windows open.
if (mainWindow === null) {
createWindow()
}
})
// In this file you can include the rest of your app's specific main process
// Modules to control application life and create native browser window
const { app, BrowserWindow } = require('electron')
// Keep a global reference of the window object, if you don't, the window will
// be closed automatically when the JavaScript object is garbage collected.
let mainWindow
function createWindow () {
// Create the browser window.
mainWindow = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
nodeIntegration: true
}
})
// and load the index.html of the app.
mainWindow.loadFile('index.html')
// Open the DevTools.
// mainWindow.webContents.openDevTools()
// Emitted when the window is closed.
mainWindow.on('closed', function () {
// Dereference the window object, usually you would store windows
// in an array if your app supports multi windows, this is the time
// when you should delete the corresponding element.
mainWindow = null
})
}
// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs.
app.whenReady().then(createWindow)
// Quit when all windows are closed.
app.on('window-all-closed', function () {
// On macOS it is common for applications and their menu bar
// to stay active until the user quits explicitly with Cmd + Q
if (process.platform !== 'darwin') {
app.quit()
}
})
app.on('activate', function () {
// On macOS it is common to re-create a window in the app when the
// dock icon is clicked and there are no other windows open.
if (mainWindow === null) {
createWindow()
}
})
// In this file you can include the rest of your app's specific main process
// code. You can also put them in separate files and require them here.

View File

@@ -1,13 +1,13 @@
const { shell } = require('electron')
const os = require('os')
const exLinksBtn = document.getElementById('open-ex-links')
const fileManagerBtn = document.getElementById('open-file-manager')
fileManagerBtn.addEventListener('click', (event) => {
shell.showItemInFolder(os.homedir())
})
exLinksBtn.addEventListener('click', (event) => {
shell.openExternal('https://electronjs.org')
const { shell } = require('electron')
const os = require('os')
const exLinksBtn = document.getElementById('open-ex-links')
const fileManagerBtn = document.getElementById('open-file-manager')
fileManagerBtn.addEventListener('click', (event) => {
shell.showItemInFolder(os.homedir())
})
exLinksBtn.addEventListener('click', (event) => {
shell.openExternal('https://electronjs.org')
})

View File

@@ -1,56 +1,56 @@
// Modules to control application life and create native browser window
const { app, BrowserWindow } = require('electron')
// Keep a global reference of the window object, if you don't, the window will
// be closed automatically when the JavaScript object is garbage collected.
let mainWindow
function createWindow () {
// Create the browser window.
mainWindow = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
nodeIntegration: true
}
})
// and load the index.html of the app.
mainWindow.loadFile('index.html')
// Open the DevTools.
// mainWindow.webContents.openDevTools()
// Emitted when the window is closed.
mainWindow.on('closed', function () {
// Dereference the window object, usually you would store windows
// in an array if your app supports multi windows, this is the time
// when you should delete the corresponding element.
mainWindow = null
})
}
// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs.
app.whenReady().then(createWindow)
// Quit when all windows are closed.
app.on('window-all-closed', function () {
// On macOS it is common for applications and their menu bar
// to stay active until the user quits explicitly with Cmd + Q
if (process.platform !== 'darwin') {
app.quit()
}
})
app.on('activate', function () {
// On macOS it is common to re-create a window in the app when the
// dock icon is clicked and there are no other windows open.
if (mainWindow === null) {
createWindow()
}
})
// In this file you can include the rest of your app's specific main process
// Modules to control application life and create native browser window
const { app, BrowserWindow } = require('electron')
// Keep a global reference of the window object, if you don't, the window will
// be closed automatically when the JavaScript object is garbage collected.
let mainWindow
function createWindow () {
// Create the browser window.
mainWindow = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
nodeIntegration: true
}
})
// and load the index.html of the app.
mainWindow.loadFile('index.html')
// Open the DevTools.
// mainWindow.webContents.openDevTools()
// Emitted when the window is closed.
mainWindow.on('closed', function () {
// Dereference the window object, usually you would store windows
// in an array if your app supports multi windows, this is the time
// when you should delete the corresponding element.
mainWindow = null
})
}
// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs.
app.whenReady().then(createWindow)
// Quit when all windows are closed.
app.on('window-all-closed', function () {
// On macOS it is common for applications and their menu bar
// to stay active until the user quits explicitly with Cmd + Q
if (process.platform !== 'darwin') {
app.quit()
}
})
app.on('activate', function () {
// On macOS it is common to re-create a window in the app when the
// dock icon is clicked and there are no other windows open.
if (mainWindow === null) {
createWindow()
}
})
// In this file you can include the rest of your app's specific main process
// code. You can also put them in separate files and require them here.

View File

@@ -1,29 +1,29 @@
const basicNotification = {
title: 'Basic Notification',
body: 'Short message part'
}
const notification = {
title: 'Notification with image',
body: 'Short message plus a custom image',
icon: 'https://via.placeholder.com/150'
}
const basicNotificationButton = document.getElementById('basic-noti')
const notificationButton = document.getElementById('advanced-noti')
notificationButton.addEventListener('click', () => {
const myNotification = new window.Notification(notification.title, notification)
myNotification.onclick = () => {
console.log('Notification clicked')
}
})
basicNotificationButton.addEventListener('click', () => {
const myNotification = new window.Notification(basicNotification.title, basicNotification)
myNotification.onclick = () => {
console.log('Notification clicked')
}
})
const basicNotification = {
title: 'Basic Notification',
body: 'Short message part'
}
const notification = {
title: 'Notification with image',
body: 'Short message plus a custom image',
icon: 'https://via.placeholder.com/150'
}
const basicNotificationButton = document.getElementById('basic-noti')
const notificationButton = document.getElementById('advanced-noti')
notificationButton.addEventListener('click', () => {
const myNotification = new window.Notification(notification.title, notification)
myNotification.onclick = () => {
console.log('Notification clicked')
}
})
basicNotificationButton.addEventListener('click', () => {
const myNotification = new window.Notification(basicNotification.title, basicNotification)
myNotification.onclick = () => {
console.log('Notification clicked')
}
})

File diff suppressed because one or more lines are too long

View File

@@ -1,35 +1,35 @@
const { ipcRenderer, shell } = require('electron')
const trayBtn = document.getElementById('put-in-tray')
const links = document.querySelectorAll('a[href]')
let trayOn = false
trayBtn.addEventListener('click', function (event) {
if (trayOn) {
trayOn = false
document.getElementById('tray-countdown').innerHTML = ''
ipcRenderer.send('remove-tray')
} else {
trayOn = true
const message = 'Click demo again to remove.'
document.getElementById('tray-countdown').innerHTML = message
ipcRenderer.send('put-in-tray')
}
})
// Tray removed from context menu on icon
ipcRenderer.on('tray-removed', function () {
ipcRenderer.send('remove-tray')
trayOn = false
document.getElementById('tray-countdown').innerHTML = ''
})
Array.prototype.forEach.call(links, (link) => {
const url = link.getAttribute('href')
if (url.indexOf('http') === 0) {
link.addEventListener('click', (e) => {
e.preventDefault()
shell.openExternal(url)
})
}
const { ipcRenderer, shell } = require('electron')
const trayBtn = document.getElementById('put-in-tray')
const links = document.querySelectorAll('a[href]')
let trayOn = false
trayBtn.addEventListener('click', function (event) {
if (trayOn) {
trayOn = false
document.getElementById('tray-countdown').innerHTML = ''
ipcRenderer.send('remove-tray')
} else {
trayOn = true
const message = 'Click demo again to remove.'
document.getElementById('tray-countdown').innerHTML = message
ipcRenderer.send('put-in-tray')
}
})
// Tray removed from context menu on icon
ipcRenderer.on('tray-removed', function () {
ipcRenderer.send('remove-tray')
trayOn = false
document.getElementById('tray-countdown').innerHTML = ''
})
Array.prototype.forEach.call(links, (link) => {
const url = link.getAttribute('href')
if (url.indexOf('http') === 0) {
link.addEventListener('click', (e) => {
e.preventDefault()
shell.openExternal(url)
})
}
})

View File

@@ -1,23 +1,20 @@
const { app, BrowserWindow } = require('electron')
const { app, BrowserWindow, ipcMain } = require('electron')
let mainWindow = null
ipcMain.on('create-frameless-window', (event, {url}) => {
const win = new BrowserWindow({ frame: false })
win.loadURL(url)
})
function createWindow () {
const windowOptions = {
const mainWindow = new BrowserWindow({
width: 600,
height: 400,
title: 'Create a frameless window',
webPreferences: {
nodeIntegration: true
}
}
mainWindow = new BrowserWindow(windowOptions)
mainWindow.loadFile('index.html')
mainWindow.on('closed', () => {
mainWindow = null
})
mainWindow.loadFile('index.html')
}
app.whenReady().then(() => {

View File

@@ -1,12 +1,8 @@
const { BrowserWindow } = require('electron').remote
const { ipcRenderer } = require('electron')
const newWindowBtn = document.getElementById('frameless-window')
newWindowBtn.addEventListener('click', (event) => {
let win = new BrowserWindow({ frame: false })
win.on('close', () => { win = null })
win.loadURL('data:text/html,<h2>Hello World!</h2><a id="close" href="javascript:window.close()">Close this Window</a>')
win.show()
newWindowBtn.addEventListener('click', () => {
const url = 'data:text/html,<h2>Hello World!</h2><a id="close" href="javascript:window.close()">Close this Window</a>'
ipcRenderer.send('create-frameless-window', { url })
})

View File

@@ -1,56 +1,46 @@
// Modules to control application life and create native browser window
const { app, BrowserWindow } = require('electron')
// Keep a global reference of the window object, if you don't, the window will
// be closed automatically when the JavaScript object is garbage collected.
let mainWindow
function createWindow () {
// Create the browser window.
mainWindow = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
nodeIntegration: true
}
})
// and load the index.html of the app.
mainWindow.loadFile('index.html')
// Open the DevTools.
// mainWindow.webContents.openDevTools()
// Emitted when the window is closed.
mainWindow.on('closed', function () {
// Dereference the window object, usually you would store windows
// in an array if your app supports multi windows, this is the time
// when you should delete the corresponding element.
mainWindow = null
})
}
// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs.
app.whenReady().then(createWindow)
// Quit when all windows are closed.
app.on('window-all-closed', function () {
// On macOS it is common for applications and their menu bar
// to stay active until the user quits explicitly with Cmd + Q
if (process.platform !== 'darwin') {
app.quit()
}
})
app.on('activate', function () {
// On macOS it is common to re-create a window in the app when the
// dock icon is clicked and there are no other windows open.
if (mainWindow === null) {
createWindow()
}
})
// In this file you can include the rest of your app's specific main process
// Modules to control application life and create native browser window
const { app, BrowserWindow } = require('electron')
ipcMain.on('create-frameless-window', (event, {url}) => {
const win = new BrowserWindow({ frame: false })
win.loadURL(url)
})
function createWindow () {
// Create the browser window.
const mainWindow = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
nodeIntegration: true
}
})
// and load the index.html of the app.
mainWindow.loadFile('index.html')
}
// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs.
app.whenReady().then(createWindow)
// Quit when all windows are closed.
app.on('window-all-closed', function () {
// On macOS it is common for applications and their menu bar
// to stay active until the user quits explicitly with Cmd + Q
if (process.platform !== 'darwin') {
app.quit()
}
})
app.on('activate', function () {
// On macOS it is common to re-create a window in the app when the
// dock icon is clicked and there are no other windows open.
if (mainWindow === null) {
createWindow()
}
})
// In this file you can include the rest of your app's specific main process
// code. You can also put them in separate files and require them here.

View File

@@ -1,25 +1,8 @@
const { BrowserWindow } = require('electron').remote
const shell = require('electron').shell
const framelessWindowBtn = document.getElementById('frameless-window')
const links = document.querySelectorAll('a[href]')
framelessWindowBtn.addEventListener('click', (event) => {
const modalPath = 'https://electronjs.org'
let win = new BrowserWindow({ frame: false })
win.on('close', () => { win = null })
win.loadURL(modalPath)
win.show()
})
Array.prototype.forEach.call(links, (link) => {
const url = link.getAttribute('href')
if (url.indexOf('http') === 0) {
link.addEventListener('click', (e) => {
e.preventDefault()
shell.openExternal(url)
})
}
})
const { ipcRenderer } = require('electron')
const newWindowBtn = document.getElementById('frameless-window')
newWindowBtn.addEventListener('click', () => {
const url = 'data:text/html,<h2>Hello World!</h2><a id="close" href="javascript:window.close()">Close this Window</a>'
ipcRenderer.send('create-frameless-window', { url })
})

View File

@@ -1,56 +1,56 @@
// Modules to control application life and create native browser window
const { app, BrowserWindow } = require('electron')
// Keep a global reference of the window object, if you don't, the window will
// be closed automatically when the JavaScript object is garbage collected.
let mainWindow
function createWindow () {
// Create the browser window.
mainWindow = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
nodeIntegration: true
}
})
// and load the index.html of the app.
mainWindow.loadFile('index.html')
// Open the DevTools.
// mainWindow.webContents.openDevTools()
// Emitted when the window is closed.
mainWindow.on('closed', function () {
// Dereference the window object, usually you would store windows
// in an array if your app supports multi windows, this is the time
// when you should delete the corresponding element.
mainWindow = null
})
}
// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs.
app.whenReady().then(createWindow)
// Quit when all windows are closed.
app.on('window-all-closed', function () {
// On macOS it is common for applications and their menu bar
// to stay active until the user quits explicitly with Cmd + Q
if (process.platform !== 'darwin') {
app.quit()
}
})
app.on('activate', function () {
// On macOS it is common to re-create a window in the app when the
// dock icon is clicked and there are no other windows open.
if (mainWindow === null) {
createWindow()
}
})
// In this file you can include the rest of your app's specific main process
// Modules to control application life and create native browser window
const { app, BrowserWindow, ipcMain } = require('electron')
ipcMain.on('create-demo-window', (event) => {
const win = new BrowserWindow({ width: 400, height: 275 })
function updateReply() {
event.sender.send('bounds-changed', {
size: win.getSize(),
position: win.getPosition()
})
}
win.on('resize', updateReply)
win.on('move', updateReply)
win.loadURL('https://electronjs.org')
})
function createWindow () {
// Create the browser window.
mainWindow = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
nodeIntegration: true
}
})
// and load the index.html of the app.
mainWindow.loadFile('index.html')
}
// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs.
app.whenReady().then(createWindow)
// Quit when all windows are closed.
app.on('window-all-closed', function () {
// On macOS it is common for applications and their menu bar
// to stay active until the user quits explicitly with Cmd + Q
if (process.platform !== 'darwin') {
app.quit()
}
})
app.on('activate', function () {
// On macOS it is common to re-create a window in the app when the
// dock icon is clicked and there are no other windows open.
if (mainWindow === null) {
createWindow()
}
})
// In this file you can include the rest of your app's specific main process
// code. You can also put them in separate files and require them here.

View File

@@ -1,35 +1,25 @@
const { BrowserWindow } = require('electron').remote
const shell = require('electron').shell
const manageWindowBtn = document.getElementById('manage-window')
const links = document.querySelectorAll('a[href]')
let win
manageWindowBtn.addEventListener('click', (event) => {
const modalPath = 'https://electronjs.org'
win = new BrowserWindow({ width: 400, height: 275 })
win.on('resize', updateReply)
win.on('move', updateReply)
win.on('close', () => { win = null })
win.loadURL(modalPath)
win.show()
function updateReply () {
const manageWindowReply = document.getElementById('manage-window-reply')
const message = `Size: ${win.getSize()} Position: ${win.getPosition()}`
manageWindowReply.innerText = message
}
})
Array.prototype.forEach.call(links, (link) => {
const url = link.getAttribute('href')
if (url.indexOf('http') === 0) {
link.addEventListener('click', (e) => {
e.preventDefault()
shell.openExternal(url)
})
}
})
const { shell, ipcRenderer } = require('electron')
const manageWindowBtn = document.getElementById('manage-window')
const links = document.querySelectorAll('a[href]')
ipcRenderer.on('bounds-changed', (event, bounds) => {
const manageWindowReply = document.getElementById('manage-window-reply')
const message = `Size: ${bounds.size} Position: ${bounds.position}`
manageWindowReply.textContent = message
})
manageWindowBtn.addEventListener('click', (event) => {
ipcRenderer.send('create-demo-window')
})
Array.prototype.forEach.call(links, (link) => {
const url = link.getAttribute('href')
if (url.indexOf('http') === 0) {
link.addEventListener('click', (e) => {
e.preventDefault()
shell.openExternal(url)
})
}
})

View File

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

View File

@@ -1,13 +1,14 @@
// Modules to control application life and create native browser window
const { app, BrowserWindow } = require('electron')
const { app, BrowserWindow, ipcMain } = require('electron')
// Keep a global reference of the window object, if you don't, the window will
// be closed automatically when the JavaScript object is garbage collected.
let mainWindow
ipcMain.on('new-window', (event, { url, width, height }) => {
const win = new BrowserWindow({ width, height })
win.loadURL(url)
})
function createWindow () {
// Create the browser window.
mainWindow = new BrowserWindow({
const mainWindow = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
@@ -17,17 +18,6 @@ function createWindow () {
// and load the index.html of the app.
mainWindow.loadFile('index.html')
// Open the DevTools.
// mainWindow.webContents.openDevTools()
// Emitted when the window is closed.
mainWindow.on('closed', function () {
// Dereference the window object, usually you would store windows
// in an array if your app supports multi windows, this is the time
// when you should delete the corresponding element.
mainWindow = null
})
}
// This method will be called when Electron has finished

View File

@@ -1,16 +1,11 @@
const { BrowserWindow } = require('electron').remote
const { shell } = require('electron').remote
const { shell, ipcRenderer } = require('electron')
const newWindowBtn = document.getElementById('new-window')
const link = document.getElementById('browser-window-link')
newWindowBtn.addEventListener('click', (event) => {
let win = new BrowserWindow({ width: 400, height: 320 })
win.on('close', () => { win = null })
win.loadURL('https://electronjs.org')
win.show()
const url = 'https://electronjs.org'
ipcRenderer.send('new-window', { url, width: 400, height: 320 });
})
link.addEventListener('click', (e) => {

View File

@@ -1,56 +1,64 @@
// Modules to control application life and create native browser window
const { app, BrowserWindow } = require('electron')
// Keep a global reference of the window object, if you don't, the window will
// be closed automatically when the JavaScript object is garbage collected.
let mainWindow
function createWindow () {
// Create the browser window.
mainWindow = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
nodeIntegration: true
}
})
// and load the index.html of the app.
mainWindow.loadFile('index.html')
// Open the DevTools.
// mainWindow.webContents.openDevTools()
// Emitted when the window is closed.
mainWindow.on('closed', function () {
// Dereference the window object, usually you would store windows
// in an array if your app supports multi windows, this is the time
// when you should delete the corresponding element.
mainWindow = null
})
}
// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs.
app.whenReady().then(createWindow)
// Quit when all windows are closed.
app.on('window-all-closed', function () {
// On macOS it is common for applications and their menu bar
// to stay active until the user quits explicitly with Cmd + Q
if (process.platform !== 'darwin') {
app.quit()
}
})
app.on('activate', function () {
// On macOS it is common to re-create a window in the app when the
// dock icon is clicked and there are no other windows open.
if (mainWindow === null) {
createWindow()
}
})
// In this file you can include the rest of your app's specific main process
// Modules to control application life and create native browser window
const { app, BrowserWindow, ipcMain } = require('electron')
function createWindow () {
// Create the browser window.
const mainWindow = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
nodeIntegration: true
}
})
// and load the index.html of the app.
mainWindow.loadFile('index.html')
let demoWindow
ipcMain.on('show-demo-window', () => {
if (demoWindow) {
demoWindow.focus()
return
}
demoWindow = new BrowserWindow({ width: 600, height: 400 })
demoWindow.loadURL('https://electronjs.org')
demoWindow.on('close', () => {
mainWindow.webContents.send('window-close')
})
demoWindow.on('focus', () => {
mainWindow.webContents.send('window-focus')
})
demoWindow.on('blur', () => {
mainWindow.webContents.send('window-blur')
})
})
ipcMain.on('focus-demo-window', () => {
if (demoWindow) demoWindow.focus()
})
}
// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs.
app.whenReady().then(createWindow)
// Quit when all windows are closed.
app.on('window-all-closed', function () {
// On macOS it is common for applications and their menu bar
// to stay active until the user quits explicitly with Cmd + Q
if (process.platform !== 'darwin') {
app.quit()
}
})
app.on('activate', function () {
// On macOS it is common to re-create a window in the app when the
// dock icon is clicked and there are no other windows open.
if (mainWindow === null) {
createWindow()
}
})
// In this file you can include the rest of your app's specific main process
// code. You can also put them in separate files and require them here.

View File

@@ -1,48 +1,39 @@
const { BrowserWindow } = require('electron').remote
const shell = require('electron').shell
const listenToWindowBtn = document.getElementById('listen-to-window')
const focusModalBtn = document.getElementById('focus-on-modal-window')
const links = document.querySelectorAll('a[href]')
let win
listenToWindowBtn.addEventListener('click', () => {
const modalPath = 'https://electronjs.org'
win = new BrowserWindow({ width: 600, height: 400 })
const hideFocusBtn = () => {
focusModalBtn.classList.add('disappear')
focusModalBtn.classList.remove('smooth-appear')
focusModalBtn.removeEventListener('click', clickHandler)
}
const showFocusBtn = (btn) => {
if (!win) return
focusModalBtn.classList.add('smooth-appear')
focusModalBtn.classList.remove('disappear')
focusModalBtn.addEventListener('click', clickHandler)
}
win.on('focus', hideFocusBtn)
win.on('blur', showFocusBtn)
win.on('close', () => {
hideFocusBtn()
win = null
})
win.loadURL(modalPath)
win.show()
const clickHandler = () => { win.focus() }
})
Array.prototype.forEach.call(links, (link) => {
const url = link.getAttribute('href')
if (url.indexOf('http') === 0) {
link.addEventListener('click', (e) => {
e.preventDefault()
shell.openExternal(url)
})
}
})
const { shell, ipcRenderer } = require('electron')
const listenToWindowBtn = document.getElementById('listen-to-window')
const focusModalBtn = document.getElementById('focus-on-modal-window')
const hideFocusBtn = () => {
focusModalBtn.classList.add('disappear')
focusModalBtn.classList.remove('smooth-appear')
focusModalBtn.removeEventListener('click', focusWindow)
}
const showFocusBtn = (btn) => {
focusModalBtn.classList.add('smooth-appear')
focusModalBtn.classList.remove('disappear')
focusModalBtn.addEventListener('click', focusWindow)
}
const focusWindow = () => {
ipcRenderer.send('focus-demo-window')
}
ipcRenderer.on('window-focus', hideFocusBtn)
ipcRenderer.on('window-close', hideFocusBtn)
ipcRenderer.on('window-blur', showFocusBtn)
listenToWindowBtn.addEventListener('click', () => {
ipcRenderer.send('show-demo-window')
})
const links = document.querySelectorAll('a[href]')
Array.prototype.forEach.call(links, (link) => {
const url = link.getAttribute('href')
if (url.indexOf('http') === 0) {
link.addEventListener('click', (e) => {
e.preventDefault()
shell.openExternal(url)
})
}
})

View File

@@ -1,6 +1,6 @@
# Accessibility
Making accessible applications is important and we're happy to introduce new
Making accessible applications is important and we're happy to provide
functionality to [Devtron][devtron] and [Spectron][spectron] that gives
developers the opportunity to make their apps better for everyone.
@@ -11,7 +11,7 @@ websites because they're both ultimately HTML. With Electron apps, however,
you can't use the online resources for accessibility audits because your app
doesn't have a URL to point the auditor to.
These new features bring those auditing tools to your Electron app. You can
These features bring those auditing tools to your Electron app. You can
choose to add audits to your tests with Spectron or use them within DevTools
with Devtron. Read on for a summary of the tools.
@@ -32,7 +32,7 @@ You can read more about this feature in [Spectron's documentation][spectron-a11y
## Devtron
In Devtron, there is a new accessibility tab which will allow you to audit a
In Devtron, there is an accessibility tab which will allow you to audit a
page in your app, sort and filter the results.
![devtron screenshot][devtron-screenshot]
@@ -44,26 +44,29 @@ audit rules this library uses on that [repository's wiki][a11y-devtools-wiki].
If you know of other great accessibility tools for Electron, add them to the
accessibility documentation with a pull request.
## Enabling Accessibility
## Manually enabling accessibility features
Electron applications keep accessibility disabled by default for performance
reasons but there are multiple ways to enable it.
Electron applications will automatically enable accessibility features in the
presence of assistive technology (e.g. [JAWS](https://www.freedomscientific.com/products/software/jaws/)
on Windows or [VoiceOver](https://help.apple.com/voiceover/mac/10.15/) on macOS).
See Chrome's [accessibility documentation][a11y-docs] for more details.
### Inside Application
You can also manually toggle these features either within your Electron application
or by setting flags in third-party native software.
By using [`app.setAccessibilitySupportEnabled(enabled)`][setAccessibilitySupportEnabled],
you can expose accessibility switch to users in the application preferences.
User's system assistive utilities have priority over this setting and will
override it.
### Using Electron's API
### Assistive Technology
By using the [`app.setAccessibilitySupportEnabled(enabled)`][setAccessibilitySupportEnabled]
API, you can manually expose Chrome's accessibility tree to users in the application preferences.
Note that the user's system assistive utilities have priority over this setting and
will override it.
Electron application will enable accessibility automatically when it detects
assistive technology (Windows) or VoiceOver (macOS). See Chrome's
[accessibility documentation][a11y-docs] for more details.
### Within third-party software
On macOS, third-party assistive technology can switch accessibility inside
Electron applications by setting the attribute `AXManualAccessibility`
#### macOS
On macOS, third-party assistive technology can toggle accessibility features inside
Electron applications by setting the `AXManualAccessibility` attribute
programmatically:
```objc

View File

@@ -32,7 +32,7 @@ into a cohesive package so that anyone can jump right in to Electron
development.
Forge comes with [a ready-to-use template](https://electronforge.io/templates) using Webpack as a bundler. It includes an example typescript configuration and provides two configuration files to enable easy customization. It uses the same core modules used by the
greater Electron community (like [`electron-packager`](https://github.com/electron/electron-packager))  
greater Electron community (like [`electron-packager`](https://github.com/electron/electron-packager))
changes made by Electron maintainers (like Slack) benefit Forge's users, too.
You can find more information and documentation on [electronforge.io](https://electronforge.io/).

View File

@@ -188,6 +188,15 @@ Once you've created your initial `main.js`, `index.html`, and `package.json`
files, you can try your app by running `npm start` from your application's
directory.
**Note**: If you are building this project without downloading the example
repository, your `start` script in `package.json` should look like this
```json
"scripts": {
"start": "electron ."
}
```
## Trying this Example
Clone and run the code in this tutorial by using the

View File

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

View File

@@ -19,16 +19,9 @@ There are three ways to create a `.snap` file:
2) Using `electron-installer-snap`, which takes `electron-packager`'s output.
3) Using an already created `.deb` package.
In all cases, you will need to have the `snapcraft` tool installed. We
recommend building on Ubuntu 16.04 (or the current LTS).
```sh
snap install snapcraft --classic
```
While it _is possible_ to install `snapcraft` on macOS using Homebrew, it
is not able to build `snap` packages and is focused on managing packages
in the store.
In some cases, you will need to have the `snapcraft` tool installed.
Instructions to install `snapcraft` for your particular distribution are
available [here](https://snapcraft.io/docs/installing-snapcraft).
## Using `electron-installer-snap`

View File

@@ -132,7 +132,7 @@ autoUpdater.on('error', message => {
})
```
## Handing Updates Manually
## Handling Updates Manually
Because the requests made by Auto Update aren't under your direct control, you may find situations that are difficult to handle (such as if the update server is behind authentication). The `url` field does support files, which means that with some effort, you can sidestep the server-communication aspect of the process. [Here's an example of how this could work](https://github.com/electron/electron/issues/5020#issuecomment-477636990).

View File

@@ -7,7 +7,7 @@ and then enable it in your application.
## Prepare a Copy of Flash Plugin
On macOS and Linux, the details of the Pepper Flash plugin can be found by
navigating to `chrome://flash` in the Chrome browser. Its location and version
navigating to `chrome://version` in the Chrome browser. Its location and version
are useful for Electron's Pepper Flash support. You can also copy it to another
location.

View File

@@ -55,7 +55,6 @@ template("electron_extra_paks") {
output = "${invoker.output_dir}/resources.pak"
sources = [
"$root_gen_dir/chrome/dev_ui_browser_resources.pak",
"$root_gen_dir/chrome/print_preview_pdf_resources.pak",
"$root_gen_dir/components/components_resources.pak",
"$root_gen_dir/content/browser/resources/media/media_internals_resources.pak",
"$root_gen_dir/content/browser/tracing/tracing_resources.pak",
@@ -71,7 +70,6 @@ template("electron_extra_paks") {
]
deps = [
"//chrome/browser:dev_ui_browser_resources",
"//chrome/browser/resources:print_preview_pdf_resources",
"//components/resources",
"//content:content_resources",
"//content:dev_ui_content_resources",
@@ -96,6 +94,10 @@ template("electron_extra_paks") {
sources +=
[ "$root_gen_dir/content/browser/devtools/devtools_resources.pak" ]
deps += [ "//content/browser/devtools:devtools_resources" ]
if (enable_pdf_viewer) {
sources += [ "$root_gen_dir/chrome/print_preview_pdf_resources.pak" ]
deps += [ "//chrome/browser/resources:print_preview_pdf_resources" ]
}
if (enable_print_preview) {
sources += [ "$root_gen_dir/chrome/print_preview_resources.pak" ]
deps += [ "//chrome/browser/resources:print_preview_resources" ]

View File

@@ -115,12 +115,11 @@ auto_filenames = {
"docs/api/structures/referrer.md",
"docs/api/structures/scrubber-item.md",
"docs/api/structures/segmented-control-segment.md",
"docs/api/structures/serial-port.md",
"docs/api/structures/service-worker-info.md",
"docs/api/structures/shared-worker-info.md",
"docs/api/structures/shortcut-details.md",
"docs/api/structures/size.md",
"docs/api/structures/stream-protocol-response.md",
"docs/api/structures/string-protocol-response.md",
"docs/api/structures/task.md",
"docs/api/structures/thumbar-button.md",
"docs/api/structures/trace-categories-and-options.md",
@@ -141,6 +140,7 @@ auto_filenames = {
"lib/common/api/shell.ts",
"lib/common/define-properties.ts",
"lib/common/type-utils.ts",
"lib/common/web-view-events.ts",
"lib/common/web-view-methods.ts",
"lib/common/webpack-globals-provider.ts",
"lib/renderer/api/context-bridge.ts",
@@ -229,7 +229,7 @@ auto_filenames = {
"lib/browser/desktop-capturer.ts",
"lib/browser/devtools.ts",
"lib/browser/guest-view-manager.js",
"lib/browser/guest-window-manager.js",
"lib/browser/guest-window-manager.ts",
"lib/browser/init.ts",
"lib/browser/ipc-main-impl.ts",
"lib/browser/ipc-main-internal-utils.ts",
@@ -248,6 +248,7 @@ auto_filenames = {
"lib/common/parse-features-string.ts",
"lib/common/reset-search-paths.ts",
"lib/common/type-utils.ts",
"lib/common/web-view-events.ts",
"lib/common/web-view-methods.ts",
"lib/common/webpack-globals-provider.ts",
"lib/renderer/ipc-renderer-internal-utils.ts",
@@ -269,6 +270,7 @@ auto_filenames = {
"lib/common/init.ts",
"lib/common/reset-search-paths.ts",
"lib/common/type-utils.ts",
"lib/common/web-view-events.ts",
"lib/common/web-view-methods.ts",
"lib/common/webpack-globals-provider.ts",
"lib/common/webpack-provider.ts",

View File

@@ -256,8 +256,6 @@ filenames = {
"shell/browser/net/web_request_api_interface.h",
"shell/browser/network_hints_handler_impl.cc",
"shell/browser/network_hints_handler_impl.h",
"shell/browser/node_debugger.cc",
"shell/browser/node_debugger.h",
"shell/browser/notifications/linux/libnotify_notification.cc",
"shell/browser/notifications/linux/libnotify_notification.h",
"shell/browser/notifications/linux/notification_presenter_linux.cc",
@@ -301,6 +299,14 @@ filenames = {
"shell/browser/relauncher_linux.cc",
"shell/browser/relauncher_mac.cc",
"shell/browser/relauncher_win.cc",
"shell/browser/serial/electron_serial_delegate.cc",
"shell/browser/serial/electron_serial_delegate.h",
"shell/browser/serial/serial_chooser_context.cc",
"shell/browser/serial/serial_chooser_context.h",
"shell/browser/serial/serial_chooser_context_factory.cc",
"shell/browser/serial/serial_chooser_context_factory.h",
"shell/browser/serial/serial_chooser_controller.cc",
"shell/browser/serial/serial_chooser_controller.h",
"shell/browser/session_preferences.cc",
"shell/browser/session_preferences.h",
"shell/browser/special_storage_policy.cc",
@@ -446,6 +452,7 @@ filenames = {
"shell/common/api/electron_api_clipboard.h",
"shell/common/api/electron_api_clipboard_mac.mm",
"shell/common/api/electron_api_command_line.cc",
"shell/common/api/electron_api_environment.cc",
"shell/common/api/electron_api_key_weak_map.h",
"shell/common/api/electron_api_native_image.cc",
"shell/common/api/electron_api_native_image.h",
@@ -490,6 +497,7 @@ filenames = {
"shell/common/gin_converters/file_path_converter.h",
"shell/common/gin_converters/gfx_converter.cc",
"shell/common/gin_converters/gfx_converter.h",
"shell/common/gin_converters/guid_converter.h",
"shell/common/gin_converters/gurl_converter.h",
"shell/common/gin_converters/image_converter.cc",
"shell/common/gin_converters/image_converter.h",
@@ -565,7 +573,9 @@ filenames = {
"shell/common/node_util.h",
"shell/common/options_switches.cc",
"shell/common/options_switches.h",
"shell/common/platform_util.cc",
"shell/common/platform_util.h",
"shell/common/platform_util_internal.h",
"shell/common/platform_util_linux.cc",
"shell/common/platform_util_mac.mm",
"shell/common/platform_util_win.cc",
@@ -625,6 +635,8 @@ filenames = {
"shell/browser/extensions/api/resources_private/resources_private_api.h",
"shell/browser/extensions/api/runtime/electron_runtime_api_delegate.cc",
"shell/browser/extensions/api/runtime/electron_runtime_api_delegate.h",
"shell/browser/extensions/api/management/electron_management_api_delegate.cc",
"shell/browser/extensions/api/management/electron_management_api_delegate.h",
"shell/browser/extensions/api/tabs/tabs_api.cc",
"shell/browser/extensions/api/tabs/tabs_api.h",
"shell/browser/extensions/api/streams_private/streams_private_api.cc",

View File

@@ -28,9 +28,11 @@ Object.setPrototypeOf(BrowserWindow.prototype, BaseWindow.prototype);
// Though this hack is only needed on macOS when the app is launched from
// Finder, we still do it on all platforms in case of other bugs we don't
// know.
this.webContents.once('load-url' as any, function (this: WebContents) {
this.focus();
});
if (this.webContents._initiallyShown) {
this.webContents.once('load-url' as any, function (this: WebContents) {
this.focus();
});
}
// Redirect focus/blur event to app instance too.
this.on('blur', (event: Event) => {
@@ -90,11 +92,7 @@ BrowserWindow.getFocusedWindow = () => {
};
BrowserWindow.fromWebContents = (webContents: WebContents) => {
for (const window of BrowserWindow.getAllWindows()) {
if (window.webContents && window.webContents.equal(webContents)) return window;
}
return null;
return webContents.getOwnerBrowserWindow();
};
BrowserWindow.fromBrowserView = (browserView: BrowserView) => {

View File

@@ -13,7 +13,7 @@ class CrashReporter {
submitURL,
uploadToServer = true,
rateLimit = false,
compress = false
compress = true
} = options || {};
if (submitURL == null) throw new Error('submitURL is a required option to crashReporter.start');

View File

@@ -157,9 +157,12 @@ function sortGroups<T> (groups: {id?: T}[][]) {
return sortedGroupIndexes.map(i => groups[i]);
}
export function sortMenuItems (menuItems: {type?: string, id?: string}[]) {
const isSeparator = (item: {type?: string}) => item.type === 'separator';
const separators = menuItems.filter(i => i.type === 'separator');
export function sortMenuItems (menuItems: (Electron.MenuItemConstructorOptions | Electron.MenuItem)[]) {
const isSeparator = (i: Electron.MenuItemConstructorOptions | Electron.MenuItem) => {
const opts = i as Electron.MenuItemConstructorOptions;
return i.type === 'separator' && !opts.before && !opts.after && !opts.beforeGroupContaining && !opts.afterGroupContaining;
};
const separators = menuItems.filter(isSeparator);
// Split the items into their implicit groups based upon separators.
const groups = splitArray(menuItems, isSeparator);

View File

@@ -182,11 +182,11 @@ Menu.buildFromTemplate = function (template) {
throw new TypeError('Invalid template for MenuItem: must have at least one of label, role or type');
}
const filtered = removeExtraSeparators(template);
const sorted = sortTemplate(filtered);
const sorted = sortTemplate(template);
const filtered = removeExtraSeparators(sorted);
const menu = new Menu();
sorted.forEach(item => {
filtered.forEach(item => {
if (item instanceof MenuItem) {
menu.append(item);
} else {

View File

@@ -2,6 +2,7 @@ import * as url from 'url';
import { Readable, Writable } from 'stream';
import { app } from 'electron/main';
import type { ClientRequestConstructorOptions, UploadProgress } from 'electron/main';
const {
isValidHeaderName,
isValidHeaderValue,
@@ -37,12 +38,14 @@ class IncomingMessage extends Readable {
_shouldPush: boolean;
_data: (Buffer | null)[];
_responseHead: NodeJS.ResponseHead;
_resume: (() => void) | null;
constructor (responseHead: NodeJS.ResponseHead) {
super();
this._shouldPush = false;
this._data = [];
this._responseHead = responseHead;
this._resume = null;
}
get statusCode () {
@@ -102,7 +105,9 @@ class IncomingMessage extends Readable {
throw new Error('HTTP trailers are not supported');
}
_storeInternalData (chunk: Buffer | null) {
_storeInternalData (chunk: Buffer | null, resume: (() => void) | null) {
// save the network callback for use in _pushInternalData
this._resume = resume;
this._data.push(chunk);
this._pushInternalData();
}
@@ -112,6 +117,12 @@ class IncomingMessage extends Readable {
const chunk = this._data.shift();
this._shouldPush = this.push(chunk);
}
if (this._shouldPush && this._resume) {
this._resume();
// Reset the callback, so that a new one is used for each
// batch of throttled data
this._resume = null;
}
}
_read () {
@@ -243,7 +254,8 @@ function parseOptions (optionsIn: ClientRequestConstructorOptions | string): Nod
redirectPolicy,
extraHeaders: options.headers || {},
body: null as any,
useSessionCookies: options.useSessionCookies || false
useSessionCookies: options.useSessionCookies,
credentials: options.credentials
};
for (const [name, value] of Object.entries(urlLoaderOptions.extraHeaders!)) {
if (!isValidHeaderName(name)) {
@@ -362,7 +374,7 @@ export class ClientRequest extends Writable implements Electron.ClientRequest {
delete this._urlLoaderOptions.extraHeaders[key];
}
_write (chunk: Buffer, encoding: string, callback: () => void) {
_write (chunk: Buffer, encoding: BufferEncoding, callback: () => void) {
this._firstWrite = true;
if (!this._body) {
this._body = new SlurpStream();
@@ -402,11 +414,11 @@ export class ClientRequest extends Writable implements Electron.ClientRequest {
const response = this._response = new IncomingMessage(responseHead);
this.emit('response', response);
});
this._urlLoader.on('data', (event, data) => {
this._response!._storeInternalData(Buffer.from(data));
this._urlLoader.on('data', (event, data, resume) => {
this._response!._storeInternalData(Buffer.from(data), resume);
});
this._urlLoader.on('complete', () => {
if (this._response) { this._response._storeInternalData(null); }
if (this._response) { this._response._storeInternalData(null, null); }
});
this._urlLoader.on('error', (event, netErrorString) => {
const error = new Error(netErrorString);
@@ -481,6 +493,14 @@ export class ClientRequest extends Writable implements Electron.ClientRequest {
}
_die (err?: Error) {
// Node.js assumes that any stream which is ended is no longer capable of emitted events
// which is a faulty assumption for the case of an object that is acting like a stream
// (our urlRequest). If we don't emit here, this causes errors since we *do* expect
// that error events can be emitted after urlRequest.end().
if ((this as any)._writableState.destroyed && err) {
this.emit('error', err);
}
this.destroy(err);
if (this._urlLoader) {
this._urlLoader.cancel();

View File

@@ -121,7 +121,7 @@ const defaultPrintingSetting = {
// JavaScript implementations of WebContents.
const binding = process._linkedBinding('electron_browser_web_contents');
const { WebContents } = binding as { WebContents: { prototype: Electron.WebContentsInternal } };
const { WebContents } = binding as { WebContents: { prototype: Electron.WebContents } };
WebContents.prototype.send = function (channel, ...args) {
if (typeof channel !== 'string') {
@@ -200,7 +200,7 @@ for (const method of webFrameMethods) {
};
}
const waitTillCanExecuteJavaScript = async (webContents: Electron.WebContentsInternal) => {
const waitTillCanExecuteJavaScript = async (webContents: Electron.WebContents) => {
if (webContents.getURL() && !webContents.isLoadingMainFrame()) return;
return new Promise((resolve) => {
@@ -461,6 +461,13 @@ const addReturnValueToEvent = (event: any) => {
});
};
const commandLine = process._linkedBinding('electron_common_command_line');
const environment = process._linkedBinding('electron_common_environment');
const loggingEnabled = () => {
return environment.hasVar('ELECTRON_ENABLE_LOGGING') || commandLine.hasSwitch('enable-logging');
};
// Add JavaScript wrappers for WebContents class.
WebContents.prototype._init = function () {
// The navigation controller.
@@ -487,7 +494,7 @@ WebContents.prototype._init = function () {
this.setMaxListeners(0);
// Dispatch IPC messages to the ipc module.
this.on('-ipc-message' as any, function (this: Electron.WebContentsInternal, event: any, internal: boolean, channel: string, args: any[]) {
this.on('-ipc-message' as any, function (this: Electron.WebContents, event: any, internal: boolean, channel: string, args: any[]) {
if (internal) {
addReplyInternalToEvent(event);
ipcMainInternal.emit(channel, event, ...args);
@@ -512,7 +519,7 @@ WebContents.prototype._init = function () {
}
});
this.on('-ipc-message-sync' as any, function (this: Electron.WebContentsInternal, event: any, internal: boolean, channel: string, args: any[]) {
this.on('-ipc-message-sync' as any, function (this: Electron.WebContents, event: any, internal: boolean, channel: string, args: any[]) {
addReturnValueToEvent(event);
if (internal) {
addReplyInternalToEvent(event);
@@ -545,19 +552,24 @@ WebContents.prototype._init = function () {
app.emit('renderer-process-crashed', event, this, ...args);
});
this.on('render-process-gone', (event, ...args) => {
app.emit('render-process-gone', event, this, ...args);
this.on('render-process-gone', (event, details) => {
app.emit('render-process-gone', event, this, details);
// Log out a hint to help users better debug renderer crashes.
if (loggingEnabled()) {
console.info(`Renderer process ${details.reason} - see https://www.electronjs.org/docs/tutorial/application-debugging for potential debugging information.`);
}
});
// The devtools requests the webContents to reload.
this.on('devtools-reload-page', function (this: Electron.WebContentsInternal) {
this.on('devtools-reload-page', function (this: Electron.WebContents) {
this.reload();
});
if (this.getType() !== 'remote') {
// Make new windows requested by links behave like "window.open".
this.on('-new-window' as any, (event: any, url: string, frameName: string, disposition: string,
rawFeatures: string, referrer: string, postData: string) => {
rawFeatures: string, referrer: string, postData: Electron.UploadRawData[]) => {
const { options, webPreferences, additionalFeatures } = parseFeatures(rawFeatures);
const mergedOptions = {
show: true,
@@ -573,9 +585,9 @@ WebContents.prototype._init = function () {
// Create a new browser window for the native implementation of
// "window.open", used in sandbox and nativeWindowOpen mode.
this.on('-add-new-contents' as any, (event: any, webContents: Electron.WebContentsInternal, disposition: string,
this.on('-add-new-contents' as any, (event: any, webContents: Electron.WebContents, disposition: string,
userGesture: boolean, left: number, top: number, width: number, height: number, url: string, frameName: string,
referrer: string, rawFeatures: string, postData: string) => {
referrer: string, rawFeatures: string, postData: Electron.UploadRawData[]) => {
if ((disposition !== 'foreground-tab' && disposition !== 'new-window' &&
disposition !== 'background-tab')) {
event.preventDefault();
@@ -606,6 +618,15 @@ WebContents.prototype._init = function () {
app.emit('login', event, this, ...args);
});
this.on('ready-to-show' as any, () => {
const owner = this.getOwnerBrowserWindow();
if (owner && !owner.isDestroyed()) {
process.nextTick(() => {
owner.emit('ready-to-show');
});
}
});
const event = process._linkedBinding('electron_browser_event').createEmpty();
app.emit('web-contents-created', event, this);

View File

@@ -1,7 +1,4 @@
const {
createDesktopCapturer,
getMediaSourceIdForWebContents: getMediaSourceIdForWebContentsBinding
} = process._linkedBinding('electron_browser_desktop_capturer');
const { createDesktopCapturer } = process._linkedBinding('electron_browser_desktop_capturer');
const deepEqual = (a: ElectronInternal.GetSourcesOptions, b: ElectronInternal.GetSourcesOptions) => JSON.stringify(a) === JSON.stringify(b);
@@ -80,7 +77,3 @@ export const getSourcesImpl = (event: Electron.IpcMainEvent | null, args: Electr
return getSources;
};
export const getMediaSourceIdForWebContents = (event: Electron.IpcMainEvent, webContentsId: number) => {
return getMediaSourceIdForWebContentsBinding(event.sender.id, webContentsId);
};

View File

@@ -5,46 +5,13 @@ const { ipcMainInternal } = require('@electron/internal/browser/ipc-main-interna
const ipcMainUtils = require('@electron/internal/browser/ipc-main-internal-utils');
const { parseWebViewWebPreferences } = require('@electron/internal/common/parse-features-string');
const { syncMethods, asyncMethods, properties } = require('@electron/internal/common/web-view-methods');
const { webViewEvents } = require('@electron/internal/common/web-view-events');
const { serialize } = require('@electron/internal/common/type-utils');
// Doesn't exist in early initialization.
let webViewManager = null;
const supportedWebViewEvents = [
'load-commit',
'did-attach',
'did-finish-load',
'did-fail-load',
'did-frame-finish-load',
'did-start-loading',
'did-stop-loading',
'dom-ready',
'console-message',
'context-menu',
'devtools-opened',
'devtools-closed',
'devtools-focused',
'will-navigate',
'did-start-navigation',
'did-navigate',
'did-frame-navigate',
'did-navigate-in-page',
'focus-change',
'close',
'crashed',
'render-process-gone',
'plugin-crashed',
'destroyed',
'page-title-updated',
'page-favicon-updated',
'enter-html-full-screen',
'leave-html-full-screen',
'media-started-playing',
'media-paused',
'found-in-page',
'did-change-theme-color',
'update-target-url'
];
const supportedWebViewEvents = Object.keys(webViewEvents);
const guestInstances = {};
const embedderElementsMap = {};
@@ -119,7 +86,9 @@ const createGuest = function (embedder, params) {
});
};
for (const event of supportedWebViewEvents) {
fn(event);
if (event !== 'new-window') {
fn(event);
}
}
guest.on('new-window', function (event, url, frameName, disposition, options, additionalFeatures, referrer) {
@@ -420,10 +389,4 @@ const getGuest = function (guestInstanceId) {
if (guestInstance != null) return guestInstance.guest;
};
// Returns the embedder of the guest.
const getEmbedder = function (guestInstanceId) {
const guestInstance = guestInstances[guestInstanceId];
if (guestInstance != null) return guestInstance.embedder;
};
exports.isWebViewTagEnabled = isWebViewTagEnabled;

View File

@@ -1,14 +1,13 @@
'use strict';
import * as electron from 'electron/main';
import { ipcMainInternal } from '@electron/internal/browser/ipc-main-internal';
import * as ipcMainUtils from '@electron/internal/browser/ipc-main-internal-utils';
import { parseFeatures } from '@electron/internal/common/parse-features-string';
const electron = require('electron');
const { BrowserWindow } = electron;
const { isSameOrigin } = process._linkedBinding('electron_common_v8_util');
const { ipcMainInternal } = require('@electron/internal/browser/ipc-main-internal');
const ipcMainUtils = require('@electron/internal/browser/ipc-main-internal-utils');
const { parseFeatures } = require('@electron/internal/common/parse-features-string');
const { BrowserWindow } = electron;
const hasProp = {}.hasOwnProperty;
const frameToGuest = new Map();
const frameToGuest = new Map<string, Electron.BrowserWindow>();
// Security options that child windows will always inherit from parent windows
const inheritedWebPreferences = new Map([
@@ -24,7 +23,7 @@ const inheritedWebPreferences = new Map([
]);
// Copy attribute of |parent| to |child| if it is not defined in |child|.
const mergeOptions = function (child, parent, visited) {
const mergeOptions = function (child: Record<string, any>, parent: Record<string, any>, visited?: Set<Record<string, any>>) {
// Check for circular reference.
if (visited == null) visited = new Set();
if (visited.has(parent)) return;
@@ -48,7 +47,7 @@ const mergeOptions = function (child, parent, visited) {
};
// Merge |options| with the |embedder|'s window's options.
const mergeBrowserWindowOptions = function (embedder, options) {
const mergeBrowserWindowOptions = function (embedder: Electron.WebContents, options: Record<string, any>) {
if (options.webPreferences == null) {
options.webPreferences = {};
}
@@ -75,7 +74,7 @@ const mergeBrowserWindowOptions = function (embedder, options) {
// Inherit certain option values from parent window
const webPreferences = embedder.getLastWebPreferences();
for (const [name, value] of inheritedWebPreferences) {
if (webPreferences[name] === value) {
if ((webPreferences as any)[name] === value) {
options.webPreferences[name] = value;
}
}
@@ -90,7 +89,7 @@ const mergeBrowserWindowOptions = function (embedder, options) {
const MULTIPART_CONTENT_TYPE = 'multipart/form-data';
const URL_ENCODED_CONTENT_TYPE = 'application/x-www-form-urlencoded';
function makeContentTypeHeader ({ contentType, boundary }) {
function makeContentTypeHeader ({ contentType, boundary }: { contentType: string, boundary?: string }) {
const header = `content-type: ${contentType};`;
if (contentType === MULTIPART_CONTENT_TYPE) {
return `${header} boundary=${boundary}`;
@@ -99,7 +98,7 @@ function makeContentTypeHeader ({ contentType, boundary }) {
}
// Figure out appropriate headers for post data.
const parseContentTypeFormat = function (postData) {
const parseContentTypeFormat = function (postData: Electron.UploadRawData[]) {
if (postData.length) {
// For multipart forms, the first element will start with the boundary
// notice, which looks something like `------WebKitFormBoundary12345678`
@@ -123,7 +122,7 @@ const parseContentTypeFormat = function (postData) {
};
// Setup a new guest with |embedder|
const setupGuest = function (embedder, frameName, guest, options) {
const setupGuest = function (embedder: Electron.WebContents, frameName: string, guest: Electron.BrowserWindow) {
// When |embedder| is destroyed we should also destroy attached guest, and if
// guest is closed by user then we should prevent |embedder| from double
// closing guest.
@@ -134,9 +133,9 @@ const setupGuest = function (embedder, frameName, guest, options) {
};
const closedByUser = function () {
embedder._sendInternal('ELECTRON_GUEST_WINDOW_MANAGER_WINDOW_CLOSED_' + guestId);
embedder.removeListener('current-render-view-deleted', closedByEmbedder);
embedder.removeListener('current-render-view-deleted' as any, closedByEmbedder);
};
embedder.once('current-render-view-deleted', closedByEmbedder);
embedder.once('current-render-view-deleted' as any, closedByEmbedder);
guest.once('closed', closedByUser);
if (frameName) {
frameToGuest.set(frameName, guest);
@@ -149,7 +148,8 @@ const setupGuest = function (embedder, frameName, guest, options) {
};
// Create a new guest created by |embedder| with |options|.
const createGuest = function (embedder, url, referrer, frameName, options, postData) {
const createGuest = function (embedder: Electron.webContents, url: string, referrer: string | Electron.Referrer,
frameName: string, options: Record<string, any>, postData?: Electron.UploadRawData[]) {
let guest = frameToGuest.get(frameName);
if (frameName && (guest != null)) {
guest.loadURL(url);
@@ -168,7 +168,7 @@ const createGuest = function (embedder, url, referrer, frameName, options, postD
//
// Navigating to the url when creating the window from an existing
// webContents is not necessary (it will navigate there anyway).
const loadOptions = {
const loadOptions: Electron.LoadURLOptions = {
httpReferrer: referrer
};
if (postData != null) {
@@ -178,10 +178,10 @@ const createGuest = function (embedder, url, referrer, frameName, options, postD
guest.loadURL(url, loadOptions);
}
return setupGuest(embedder, frameName, guest, options);
return setupGuest(embedder, frameName, guest);
};
const getGuestWindow = function (guestContents) {
const getGuestWindow = function (guestContents: Electron.WebContents) {
let guestWindow = BrowserWindow.fromWebContents(guestContents);
if (guestWindow == null) {
const hostContents = guestContents.hostWebContents;
@@ -195,31 +195,31 @@ const getGuestWindow = function (guestContents) {
return guestWindow;
};
const isChildWindow = function (sender, target) {
const isChildWindow = function (sender: Electron.WebContents, target: Electron.WebContents) {
return target.getLastWebPreferences().openerId === sender.id;
};
const isRelatedWindow = function (sender, target) {
const isRelatedWindow = function (sender: Electron.WebContents, target: Electron.WebContents) {
return isChildWindow(sender, target) || isChildWindow(target, sender);
};
const isScriptableWindow = function (sender, target) {
const isScriptableWindow = function (sender: Electron.WebContents, target: Electron.WebContents) {
return isRelatedWindow(sender, target) && isSameOrigin(sender.getURL(), target.getURL());
};
const isNodeIntegrationEnabled = function (sender) {
const isNodeIntegrationEnabled = function (sender: Electron.WebContents) {
return sender.getLastWebPreferences().nodeIntegration === true;
};
// Checks whether |sender| can access the |target|:
const canAccessWindow = function (sender, target) {
const canAccessWindow = function (sender: Electron.WebContents, target: Electron.WebContents) {
return isChildWindow(sender, target) ||
isScriptableWindow(sender, target) ||
isNodeIntegrationEnabled(sender);
};
// Routed window.open messages with raw options
ipcMainInternal.on('ELECTRON_GUEST_WINDOW_MANAGER_WINDOW_OPEN', (event, url, frameName, features) => {
ipcMainInternal.on('ELECTRON_GUEST_WINDOW_MANAGER_WINDOW_OPEN', (event, url: string, frameName: string, features: string) => {
// This should only be allowed for senders that have nativeWindowOpen: false
const lastWebPreferences = event.sender.getLastWebPreferences();
if (lastWebPreferences.nativeWindowOpen || lastWebPreferences.sandbox) {
@@ -233,14 +233,15 @@ ipcMainInternal.on('ELECTRON_GUEST_WINDOW_MANAGER_WINDOW_OPEN', (event, url, fra
const disposition = 'new-window';
const { options, webPreferences, additionalFeatures } = parseFeatures(features);
if (!options.title) options.title = frameName;
options.webPreferences = webPreferences;
(options as Electron.BrowserWindowConstructorOptions).webPreferences = webPreferences;
const referrer = { url: '', policy: 'default' };
internalWindowOpen(event, url, referrer, frameName, disposition, options, additionalFeatures, null);
const referrer: Electron.Referrer = { url: '', policy: 'default' };
internalWindowOpen(event, url, referrer, frameName, disposition, options, additionalFeatures);
});
// Routed window.open messages with fully parsed options
function internalWindowOpen (event, url, referrer, frameName, disposition, options, additionalFeatures, postData) {
export function internalWindowOpen (event: ElectronInternal.IpcMainInternalEvent, url: string, referrer: string | Electron.Referrer,
frameName: string, disposition: string, options: Record<string, any>, additionalFeatures: string[], postData?: Electron.UploadRawData[]) {
options = mergeBrowserWindowOptions(event.sender, options);
const postBody = postData ? {
data: postData,
@@ -248,15 +249,15 @@ function internalWindowOpen (event, url, referrer, frameName, disposition, optio
} : null;
event.sender.emit('new-window', event, url, frameName, disposition, options, additionalFeatures, referrer, postBody);
const { newGuest } = event;
const { newGuest } = event as unknown as { newGuest: Electron.BrowserWindow };
if ((event.sender.getType() === 'webview' && event.sender.getLastWebPreferences().disablePopups) || event.defaultPrevented) {
if (newGuest != null) {
if (options.webContents === newGuest.webContents) {
// the webContents is not changed, so set defaultPrevented to false to
// stop the callers of this event from destroying the webContents.
event.defaultPrevented = false;
(event as any).defaultPrevented = false;
}
event.returnValue = setupGuest(event.sender, frameName, newGuest, options);
event.returnValue = setupGuest(event.sender, frameName, newGuest);
} else {
event.returnValue = null;
}
@@ -265,8 +266,8 @@ function internalWindowOpen (event, url, referrer, frameName, disposition, optio
}
}
const makeSafeHandler = function (handler) {
return (event, guestId, ...args) => {
const makeSafeHandler = function<T> (handler: (event: Electron.IpcMainInvokeEvent, guestContents: Electron.webContents, ...args: any[]) => T) {
return (event: Electron.IpcMainInvokeEvent, guestId: number, ...args: any[]) => {
// Access webContents via electron to prevent circular require.
const guestContents = electron.webContents.fromId(guestId);
if (!guestContents) {
@@ -277,15 +278,15 @@ const makeSafeHandler = function (handler) {
};
};
const handleMessage = function (channel, handler) {
const handleMessage = function (channel: string, handler: (event: Electron.IpcMainInvokeEvent, guestContents: Electron.webContents, ...args: any[]) => any) {
ipcMainInternal.handle(channel, makeSafeHandler(handler));
};
const handleMessageSync = function (channel, handler) {
const handleMessageSync = function (channel: string, handler: (event: Electron.IpcMainInvokeEvent, guestContents: Electron.webContents, ...args: any[]) => any) {
ipcMainUtils.handleSync(channel, makeSafeHandler(handler));
};
const securityCheck = function (contents, guestContents, check) {
const securityCheck = function (contents: Electron.WebContents, guestContents: Electron.WebContents, check: (sender: Electron.WebContents, target: Electron.WebContents) => boolean) {
if (!check(contents, guestContents)) {
console.error(`Blocked ${contents.getURL()} from accessing guestId: ${guestContents.id}`);
throw new Error(`Access denied to guestId: ${guestContents.id}`);
@@ -298,7 +299,7 @@ const windowMethods = new Set([
'blur'
]);
handleMessage('ELECTRON_GUEST_WINDOW_MANAGER_WINDOW_METHOD', (event, guestContents, method, ...args) => {
handleMessage('ELECTRON_GUEST_WINDOW_MANAGER_WINDOW_METHOD', (event, guestContents, method: string, ...args: any[]) => {
securityCheck(event.sender, guestContents, canAccessWindow);
if (!windowMethods.has(method)) {
@@ -306,7 +307,7 @@ handleMessage('ELECTRON_GUEST_WINDOW_MANAGER_WINDOW_METHOD', (event, guestConten
throw new Error(`Invalid method: ${method}`);
}
return getGuestWindow(guestContents)[method](...args);
return (getGuestWindow(guestContents) as any)[method](...args);
});
handleMessage('ELECTRON_GUEST_WINDOW_MANAGER_WINDOW_POSTMESSAGE', (event, guestContents, message, targetOrigin, sourceOrigin) => {
@@ -331,7 +332,7 @@ const webContentsMethodsAsync = new Set([
'print'
]);
handleMessage('ELECTRON_GUEST_WINDOW_MANAGER_WEB_CONTENTS_METHOD', (event, guestContents, method, ...args) => {
handleMessage('ELECTRON_GUEST_WINDOW_MANAGER_WEB_CONTENTS_METHOD', (event, guestContents, method: string, ...args: any[]) => {
securityCheck(event.sender, guestContents, canAccessWindow);
if (!webContentsMethodsAsync.has(method)) {
@@ -339,14 +340,14 @@ handleMessage('ELECTRON_GUEST_WINDOW_MANAGER_WEB_CONTENTS_METHOD', (event, guest
throw new Error(`Invalid method: ${method}`);
}
return guestContents[method](...args);
return (guestContents as any)[method](...args);
});
const webContentsMethodsSync = new Set([
'getURL'
]);
handleMessageSync('ELECTRON_GUEST_WINDOW_MANAGER_WEB_CONTENTS_METHOD', (event, guestContents, method, ...args) => {
handleMessageSync('ELECTRON_GUEST_WINDOW_MANAGER_WEB_CONTENTS_METHOD', (event, guestContents, method: string, ...args: any[]) => {
securityCheck(event.sender, guestContents, canAccessWindow);
if (!webContentsMethodsSync.has(method)) {
@@ -354,7 +355,5 @@ handleMessageSync('ELECTRON_GUEST_WINDOW_MANAGER_WEB_CONTENTS_METHOD', (event, g
throw new Error(`Invalid method: ${method}`);
}
return guestContents[method](...args);
return (guestContents as any)[method](...args);
});
exports.internalWindowOpen = internalWindowOpen;

View File

@@ -1,9 +1,7 @@
import { Buffer } from 'buffer';
import { EventEmitter } from 'events';
import * as fs from 'fs';
import { Socket } from 'net';
import * as path from 'path';
import * as util from 'util';
const Module = require('module');
// We modified the original process.argv to let node.js load the init.js,
@@ -18,28 +16,6 @@ require('@electron/internal/common/init');
process._linkedBinding('electron_browser_event_emitter').setEventEmitterPrototype(EventEmitter.prototype);
if (process.platform === 'win32') {
// Redirect node's console to use our own implementations, since node can not
// handle console output when running as GUI program.
const consoleLog = (...args: any[]) => {
// @ts-ignore this typing is incorrect; 'format' is an optional parameter
// See https://nodejs.org/api/util.html#util_util_format_format_args
return process.log(util.format(...args) + '\n');
};
const streamWrite: Socket['write'] = function (chunk: Buffer | string, encoding?: any, callback?: Function) {
if (Buffer.isBuffer(chunk)) {
chunk = chunk.toString(encoding);
}
process.log(chunk);
if (callback) {
callback();
}
return true;
};
console.log = console.error = console.warn = consoleLog;
process.stdout.write = process.stderr.write = streamWrite;
}
// Don't quit on fatal error.
process.on('uncaughtException', function (error) {
// Do nothing if the user has a custom uncaught exception handler.
@@ -62,7 +38,7 @@ process.on('uncaughtException', function (error) {
// Emit 'exit' event on quit.
const { app } = require('electron');
app.on('quit', function (event, exitCode) {
app.on('quit', (_event, exitCode) => {
process.emit('exit', exitCode);
});

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