Compare commits

...

232 Commits

Author SHA1 Message Date
Electron Bot
8103ded33e Bump v9.0.0-nightly.20200124 2020-01-24 07:33:00 -08:00
bitdisaster
467d7457be docs: details to run unit tests on Windows (#21840)
* document how to get unit tests running

* chore: fix styles

* chore: add lang fence

Co-authored-by: Cheng Zhao <zcbenz@github.com>
2020-01-24 10:51:09 +09:00
Cheng Zhao
74acd17771 test: make window.history.pushState test more robust (#21875) 2020-01-23 10:51:41 -08:00
Tony
5781850706 feat: custom positioning for traffic light buttons (#21781)
* feat: custom positioning for traffic light buttons

* remove NSLog and unnecessary call-site in IsVisible()

* no longer need to check if entering fullscreen

* change API to take a point object

Co-authored-by: tonyfwoo <55114329+tonyfwoo@users.noreply.github.com>
2020-01-23 10:13:08 -08:00
Samuel Attard
dd95a6f034 build: move external binaries to S3 (#21829) 2020-01-23 10:00:35 -08:00
John Kleinschmidt
c92edc8fc4 test: specify target arch on mksnapshot (#21871) 2020-01-23 09:54:27 -08:00
John Kleinschmidt
dc2fcff01c ci: use goma for windows and linux builds (#21868)
* ci: use goma for windows and linux builds
2020-01-23 09:47:38 -08:00
Electron Bot
7c0a9f29ca Bump v9.0.0-nightly.20200123 2020-01-23 07:32:49 -08:00
Ross Rosen
1d58072f65 docs: added info on bookmark return values for securityScopedBookmarks (#17584) 2020-01-23 10:17:39 +09:00
Shelley Vohr
b90537a629 feat: add tray.closeContextMenu() (#21807) 2020-01-22 15:25:17 -08:00
Electron Bot
87af95be3e Revert "Bump v9.0.0-nightly.20200122"
This reverts commit 21b9b30b99.
2020-01-22 08:13:55 -08:00
Electron Bot
21b9b30b99 Bump v9.0.0-nightly.20200122 2020-01-22 07:31:45 -08:00
Shelley Vohr
a5d5e76b10 fix: some websites using WebComponents V0 not loading (#21858) 2020-01-22 22:03:17 +09:00
Shelley Vohr
11804dfe2f fix: Windows checkboxChecked edge case (#21852) 2020-01-22 16:38:39 +09:00
Cheng Zhao
fbc2f8344f fix: crash when doing redirect navigation with webRequest listener (#21838)
* fix: pass navigation_ui_data to proxying factory

* fix: clone response instead of move in redirect
2020-01-22 10:31:10 +09:00
Cheng Zhao
36fac7bfec fix: call SetCanActivate in setFocusable (#21846) 2020-01-22 10:13:48 +09:00
Jeremy Apthorp
100a85f93a fix: [extensions] load extensions on the IO thread (#21811) 2020-01-21 09:43:18 -08:00
Jeremy Apthorp
acb5b75057 chore: [extensions] support old APIs when enable_electron_extensions = true (#21812) 2020-01-21 09:42:55 -08:00
Electron Bot
dc97fe0640 chore: bump chromium to b243c83a66a7fded00f3408107778 (master) (#21827)
Co-authored-by: Robo <hop2deep@gmail.com>
2020-01-21 09:39:37 -08:00
Electron Bot
34baa02c28 Bump v9.0.0-nightly.20200121 2020-01-21 07:31:48 -08:00
Jeremy Apthorp
d802fe0fdd fix: [extensions] some chrome.extension APIs (#21804) 2020-01-21 09:44:09 +09:00
Samuel Attard
ebe8bddc31 fix: ignore (un)lock events for sessions that aren't the current session (#21805) 2020-01-20 15:48:12 +09:00
Shelley Vohr
38947f43de docs: menu item labels are not dynamic (#21823) 2020-01-20 15:44:22 +09:00
Electron Bot
64a2490efe Bump v9.0.0-nightly.20200119 2020-01-19 07:31:09 -08:00
Electron Bot
48b9c7df84 Bump v9.0.0-nightly.20200118 2020-01-18 07:31:19 -08:00
Martin
9636acb907 docs: update setAspectRatio documentation (#19945) 2020-01-17 20:35:27 +00:00
Cheng Zhao
42d8933d66 fix: crash when restoring minimized hidden window (#21813) 2020-01-17 11:29:01 -08:00
Electron Bot
bf6e4b1247 chore: bump chromium to 279aeeec3c9fe2237bc31f776f269 (master) (#21521)
* chore: bump chromium in DEPS to 46d2d82e84d73806da623c5333dae4dd218172df

* chore: bump chromium in DEPS to cbafe74731a5d1e59844ca59e0fc28f4a5f80a33

* chore: bump chromium in DEPS to d5dcd6b5cc76f4e1732083d775cdd7b533f0abe9

* Update patches

* update for lint

* Fix compilation errors

* chore: bump chromium in DEPS to 1c19360fdaaf65d4ed006736c7f9804104095990

* Replace removed constant

* chore: bump chromium in DEPS to 3b6639f5da26c1772c5d4f3ba634aca65df75fec

* chore: bump chromium in DEPS to cc6b1b930d4b5eca06701820dac54fa0f41e8999

* chore: bump chromium in DEPS to 7d1445641ad1032c67f731ba6ff7798f29349ade

* chore: bump chromium in DEPS to 6f7e5e79cefe982ad84a88927565a88db2e592be

* chore: bump chromium in DEPS to bfb25dafff19cb41bf9781331d19ef0be819d1e4

* chore: bump chromium in DEPS to 1a8196b39f0e0cdc4935fd122fff5625d5fab06e

* chore: bump chromium in DEPS to 9a03d8d2bb38ad8c0cbb9550ca81b2f94ff60c15

* chore: bump chromium in DEPS to 4c67f3505dab2d5457adb418cd3270a4f3236fd0

* chore: bump chromium in DEPS to 652394e7626fc1ae895a53fb34c64070494e648e

* chore: bump chromium in DEPS to 07653652c58cc019af7f833bd63eb0c2eceaab5e

* chore: bump chromium in DEPS to 451a1c5fec1fb073a5bae12a033bb342c72c905f

* chore: bump chromium in DEPS to 86cdba00e233899a232868b412b333d08db63478

* chore: bump chromium in DEPS to 7c322faad1aee8abef2330d74aabf09ecf8c11af

* Update patches

* chore: bump chromium in DEPS to d0044fae7efc29eb201cfdd5fdbed77d48aba212

* Replace IsProcessingUserGesture with HasTransientUserActivation

4baa9a6e85

* Fix 10.15 sdk build

0eaa6db358

* Remove CancelPrerender

5eb3329719

* Remove no longer used WebFloatPoint

43ab96ce6b

* Use base::span<const uint8_t> for devtools messages in content/public

21e19401af

* Update renamed header files

* TODO: update with upstream changes

This code needs to be updated to handle the changes made in:
19be6547a9

* chore: bump chromium in DEPS to 82e5a2c6bd33c2e53634a09fbcbc9fcac1e7ff93

* chore: bump chromium in DEPS to 91f877cadd2995201c276e952b3bf2c60b226c64

* chore: bump chromium in DEPS to 43fcd2ab2677a06d38246b42761dc5b40cf87177

* chore: bump chromium in DEPS to e30957dcb710c0977a7ff95b8d3cf65843df12ca

* chore: bump chromium in DEPS to 6a8335a56db12aae2fd06296f82579d804d92217

* chore: bump chromium in DEPS to a4a436cbc28ace88d71752f8f479e59559e54e46

* chore: bump chromium in DEPS to 982bbd0e4b2e1d57d515f384f6483ffc0d7073ad

* chore: bump chromium in DEPS to 92bb7a99f84ffcdf41d4edca57e90b1f0c7c6c8b

* update patches

* add checkout_google_benchmark gclient var

* FIXME: workaround grit bug

* chore: bump chromium in DEPS to d3623fc53615739e6b59340a5d349e4b397cb7c5

* update patches

* Remove color arg from DidChangeThemeColor().

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

* update CreateFileURLLoader with new suffix

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

* add node patch for removal of task API in v8

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

* add disable_secure_dns param for WillCreateURLLoaderFactory

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

* switch to mojo-ified PrintMsg_PrintPreview

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

* chore: bump chromium in DEPS to e7a6d173632660b6aeb9806e9132c34a315331c2

* update missing chrome/browser/ssl:proto dependency after chrome removal

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

* chore: add libvulkan.so to the linux manifest

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

* revert DidChangeThemeColor ternary change due to templates

* match Chrome's mojo-ified implementation in geolocation_permission_context.cc

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

* add vulkan-1.dll to zips

2d6f74c6d4

* add bug link to fixme_grit_conflicts.patch

* Introduce device.mojom.DeviceService

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

* PDF Compositor rename to Print Compositor

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

* chore: bump chromium_version 00362ea584735b4acf4c5a0e1912d7987f8645ab

* chore: update patches

* Use a virtual base class to provide GetWidget().

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

* [base] Remove usage of base::CurrentThread

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

* chore: gn format

* Revert "ci: Use Visual Studio Build Tools instead of VS Studio (#21771)"

This reverts commit 9c1310dadc.

* fix: trigger resize when iframe requests fullscreen

* fix: Locking scheme registry is not necessary

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

* chore: bump chromium f707f1d6d428f84cf14b64bc2ca74372e25c6ce7

* chore: update patches

* ui/base/clipboard: Remove redundant ANSI format functions

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

* [base] Prepare //chrome for Value::GetList() switch

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

Co-authored-by: John Kleinschmidt <jkleinsc@github.com>
Co-authored-by: loc <andy@slack-corp.com>
Co-authored-by: Jeremy Apthorp <nornagon@nornagon.net>
Co-authored-by: Robo <hop2deep@gmail.com>
2020-01-17 10:41:52 -08:00
Shelley Vohr
5c6f9a6947 feat: add mouse-down & mouse-up to Tray (#21795) 2020-01-17 16:28:34 +00:00
Electron Bot
5feafaceee Bump v9.0.0-nightly.20200117 2020-01-17 07:31:47 -08:00
Max
ae49b8be42 fix: npm download failed when define 'npm_config_platform=mas' (#21801) 2020-01-17 14:44:21 +09:00
Electron Bot
09ad1807af Bump v9.0.0-nightly.20200116 2020-01-16 07:31:36 -08:00
Shelley Vohr
1e99907acc fix: printToPDF failing to generate PDF (#21783) 2020-01-15 21:05:36 -08:00
Jeremy Apthorp
b9eb68c0b4 feat: [extensions] implement a couple of tabs APIs (#21779) 2020-01-15 15:11:51 -08:00
Electron Bot
8278a64e00 Bump v9.0.0-nightly.20200115 2020-01-15 07:32:48 -08:00
Samuel Attard
b31c02ef31 test: fix some failing and disabled node specs (#19518)
* test: fix some failing and disabled node specs

These tests were failing due to mismatched stacktraces as a result of
our Module._load hook.  This fixes those by adding a flag to optionally
not hook those calls and instead do the asar override eagily.

* ELECTRON_EAGER_ASAR_HOOK => ELECTRON_EAGER_ASAR_HOOK_FOR_TESTING

* test: parallel/test-zlib-unused-weak consistently fails

Co-authored-by: Cheng Zhao <zcbenz@github.com>
2020-01-15 16:07:03 +09:00
Cheng Zhao
49262b604d test: disable some flaky node tests (#21752) 2020-01-15 16:06:33 +09:00
Shelley Vohr
3019a2650d docs: ignore_locks not break_repo_locks (#21775) 2020-01-14 20:50:37 -08:00
Jeremy Apthorp
55368e4d97 feat: just enough //extensions to load a simple devtools extension (#19515) 2020-01-14 16:20:30 -08:00
John Kleinschmidt
9c1310dadc ci: Use Visual Studio Build Tools instead of VS Studio (#21771) 2020-01-14 17:10:50 -05:00
John Kleinschmidt
408d3d2a14 build: fix release asset names (#21772) 2020-01-14 17:10:08 -05:00
Cheng Zhao
ceacadb4f4 fix: pass full response headers in net module (#21552) 2020-01-14 09:36:08 -08:00
Felix Rieseberg
2d0bf81bd4 docs: Little fix in Goma docs (#21762)
* docs: Little fix in Goma docs

* docs: Remove space
2020-01-14 11:04:08 -05:00
Electron Bot
2d8839980c Bump v9.0.0-nightly.20200114 2020-01-14 07:32:51 -08:00
Shelley Vohr
83c19faf61 fix: pass startPage url correctly to extensions (#21711)
* fix: pass startPage url correctly to extensions

* check for devtools_page first
2020-01-14 15:47:56 +09:00
Samuel Attard
80a037db86 chore: update goma documentation (#21761) 2020-01-13 15:49:29 -08:00
Jeremy Apthorp
fa42b5980e feat: flesh out the api for //extensions (#21587) 2020-01-13 14:56:28 -08:00
Jeremy Apthorp
8bc0c92137 feat: [extensions] background pages (#21591) 2020-01-13 14:55:58 -08:00
Andrea Brancaleoni
cf497ea478 build: upload windows toolchain profile (#21327)
This commit uploads the output of the windows toolchain profiler.
The windows toolchain profiler is aimed at allowing the compilation
of electron release artifacts using the same windows toolchain on user
builder. This combined with the ability of electron of outputting
deterministic build should allow in future to check electron build
artifacts against CI artifacts.

See: 97959b5e5c include windows toolchain profiler (contd #20949)
2020-01-13 15:40:13 -05:00
Cheng Zhao
32af863e34 fix: double-autorelease of NSImage (#21757) 2020-01-13 11:37:11 -08:00
Jeremy Apthorp
d68f17b32c fix: stream protocols not completing (#21733) 2020-01-13 10:28:21 -08:00
Electron Bot
7723c2c16d Bump v9.0.0-nightly.20200113 2020-01-13 07:31:46 -08:00
Cheng Zhao
758863b84d fix: disable private macOS APIs in MAS build except for CAContext/CALayerHost (#21573)
* fix: add patch to disable remote accessibility APIs

* fix: add patch to disable private window frame APIs
2020-01-13 09:04:38 -05:00
Nate Wienert
425d2a2e1b add border radius to frameless window (#20360) 2020-01-13 15:43:00 +09:00
Konstantinos Ntoutsos-Oikonomou
20c910f98e docs: New fiddle example 'Create a new window' (#20480)
* add: New fiddle for Manage Windows section example

* Delete package.json

Not needed

* Address issue with .gitignore file, load new window, removing unwanted css class

* Delete package.json

* Pushing change regarding the use of shell.OpenExternal API with an event listener for the href tag on the link
2020-01-13 15:35:56 +09:00
Yaser
b31084493e docs: Added Window Management Fiddle example (#20535) 2020-01-13 15:34:13 +09:00
Jeremy Apthorp
2e1531ad90 feat: warn when remote is used without enableRemoteModule: true (#21546)
* feat: warn when remote is used without enableRemoteModule: true

* fix security warning
2020-01-13 15:23:03 +09:00
daveilers
2f394d46c7 docs: Update online-offline-events.md to reflect nodeIntegration required (#21707)
* Update online-offline-events.md

NodeIntegration is required for online/offline and the default changed, so the example should reflect the need for that config

* chore: fix lint warning

Co-authored-by: Cheng Zhao <zcbenz@github.com>
2020-01-13 14:56:39 +09:00
Shelley Vohr
2e7f9bffeb docs: update source code dir structure (#21659) 2020-01-12 21:08:00 -08:00
Jorn
aef9ab1bb7 Es6ify api docs (#21686)
* docs: es6ify docs -> var -> const / let

* docs: apply arrow functions throughout all of the docs
2020-01-13 10:29:46 +09:00
Daniel Playfair Cal
29b7d80eb5 fix(scripts): account for sys.platform being "linux" as well "linux2" (#21741) 2020-01-13 09:58:25 +09:00
loc
a0a932826c fix: prefer occluded rather than unloading layout info (#21585) 2020-01-13 09:56:49 +09:00
Shelley Vohr
19ef7a0fc9 fix: don't fallback to OpenFolderViaShell (#21668) 2020-01-13 09:49:51 +09:00
Milan Burda
c0bde4baa4 docs: responseHeaders should be Record<string, string[]> (#21730) 2020-01-12 09:20:13 -08:00
Electron Bot
702d18b2e3 Bump v9.0.0-nightly.20200111 2020-01-11 07:31:07 -08:00
loc
301bd8aec0 fix: avoid contextBridge double free on garbage collection (#21592)
* fix: reset next/prev pointers for life-monitored nodes

* fix: don't double-delete nodes in a linked list
2020-01-10 15:59:50 -08:00
Shelley Vohr
2858471151 feat: remove visibleOnFullscreen option (#21706) 2020-01-10 09:11:38 -08:00
Electron Bot
48ae7552f6 Bump v9.0.0-nightly.20200110 2020-01-10 07:32:59 -08:00
CezaryKulakowski
f461dc7002 fix: don't unnecessarily copy draggable regions (#21704) 2020-01-09 12:13:28 -08:00
Jeremy Apthorp
768a6ace1b test: move some fixtures from spec/ to spec-main/ (#21403) 2020-01-09 11:50:56 -08:00
Cheng Zhao
8a92b65fd3 test: retry for a few flaky tests (#21658) 2020-01-09 11:50:30 -08:00
Electron Bot
cfae97a64c chore: bump node to v12.14.1 (master) (#21703)
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2020-01-09 10:42:53 -08:00
Shelley Vohr
f5e202a898 fix: Notification crash in before-quit (#21709) 2020-01-09 09:42:20 -08:00
Kilian Valkhof
bd923838c1 docs: initial document for comparing web embeds (#20478)
Co-authored-by: Felix Rieseberg <felix@felixrieseberg.com>
Co-authored-by: Mark Lee <malept@users.noreply.github.com>
2020-01-09 09:29:22 -08:00
Shelley Vohr
bb054716c9 feat: allow http-parser NODE_OPTION in packaged apps (#21694) 2020-01-09 08:09:14 -08:00
Electron Bot
75e39be916 Bump v9.0.0-nightly.20200109 2020-01-09 07:31:24 -08:00
Electron Bot
349da6af7f Bump v9.0.0-nightly.20200108 2020-01-08 07:31:48 -08:00
Samuel Attard
e18acb4380 build: document electron goma usage and add the external binaries (#21622) 2020-01-07 10:35:52 -08:00
Shogun Sea
0a850fbc5d docs: Update react devtool version in document (#21601)
* docs: update react devtool version in document

* bump react devtool version ref to 4.3.0
2020-01-07 09:14:49 -05:00
Milan Burda
31c93fec67 fix: load window-setup in sandboxed renderer (#21416) 2020-01-06 22:23:03 +01:00
Shelley Vohr
d56f67b7af refactor: throw error for getLastCrashReport if crashReporter not started (#21643) 2020-01-06 11:00:27 -05:00
Electron Bot
7d2c97b671 Bump v9.0.0-nightly.20200106 2020-01-06 07:33:51 -08:00
Electron Bot
fb1131d531 Bump v9.0.0-nightly.20200105 2020-01-05 07:31:32 -08:00
Electron Bot
1abd24aa28 Bump v9.0.0-nightly.20200104 2020-01-04 07:33:32 -08:00
Kilian Valkhof
8dc4a20069 docs: fix typos in security.md (#21665) 2020-01-03 11:11:01 -05:00
Angel_Kitty
70029aa069 chore: update license year (#21657) 2020-01-03 11:10:23 -05:00
Electron Bot
b2071d2966 Bump v9.0.0-nightly.20200103 2020-01-03 07:31:59 -08:00
Electron Bot
35a7f76205 Bump v9.0.0-nightly.20200102 2020-01-02 07:31:08 -08:00
Electron Bot
55d8c4d937 Bump v9.0.0-nightly.20200101 2020-01-01 07:31:32 -08:00
Electron Bot
7b4a5a9f3a Bump v9.0.0-nightly.20191231 2019-12-31 07:32:05 -08:00
Shelley Vohr
fbb10beb40 fix: highlight defaulted button correctly (#21642) 2019-12-31 05:48:43 -08:00
Lutz Roeder
ed6a3877a4 fix: SimpleURLLoaderWrapper redirects (#21630) 2019-12-31 10:47:08 +11:00
Shelley Vohr
181eecd03e docs: fix shell.openPath documentation (#21641) 2019-12-30 11:40:30 -08:00
David Sanders
85382d8f1d fix: improve error handling in npm install (#21589)
* fix: improve error handling in npm install

* chore: simplify logic
2019-12-30 09:48:54 -08:00
Electron Bot
b41fb2e554 Bump v9.0.0-nightly.20191230 2019-12-30 07:32:58 -08:00
Electron Bot
659c4548eb Bump v9.0.0-nightly.20191229 2019-12-29 07:31:35 -08:00
Electron Bot
2497afcf94 Bump v9.0.0-nightly.20191228 2019-12-28 07:31:28 -08:00
Electron Bot
bf266b4479 Bump v9.0.0-nightly.20191226 2019-12-26 07:32:16 -08:00
Electron Bot
4324e4ce1d Bump v9.0.0-nightly.20191225 2019-12-25 07:31:32 -08:00
Electron Bot
a158c80377 Bump v9.0.0-nightly.20191224 2019-12-24 07:31:28 -08:00
Electron Bot
69f37356c1 Bump v9.0.0-nightly.20191223 2019-12-23 07:31:10 -08:00
Electron Bot
023c9a67fd Bump v9.0.0-nightly.20191222 2019-12-22 07:32:10 -08:00
Electron Bot
020cbf3595 Bump v9.0.0-nightly.20191221 2019-12-21 07:31:35 -08:00
Electron Bot
7161b2f57c Bump v9.0.0-nightly.20191220 2019-12-20 07:34:03 -08:00
Electron Bot
e02879d809 chore: bump node in DEPS to v12.14.0 (#21579) 2019-12-19 19:25:57 -08:00
Shelley Vohr
087cb1d592 refactor: update node main instance management (#21562) 2019-12-19 13:29:09 -08:00
Electron Bot
58b816431d Bump v9.0.0-nightly.20191219 2019-12-19 07:31:49 -08:00
Jeremy Apthorp
682b5d7d01 fix: set enable_negotiate_port to false in allowNTLMCredentialsForDomains (#21571)
* fix: set enable_negotiate_port to false in allowNTLMCredentialsForDomains

* read commandline switch
2019-12-19 05:53:49 -08:00
Shelley Vohr
5e244aa505 chore: make release branch pattern more robust (#21568) 2019-12-18 14:57:46 -08:00
John Kleinschmidt
b6214fdddf build: free up macos disk space on Mac publish (#21569) 2019-12-18 14:54:52 -08:00
Electron Bot
8ffc58bdba chore: bump node to v12.13.1 (master) (#21198)
* chore: bump node in DEPS to v12.13.1

* chore: remove redundant patches

* disable node tests

disable prepareStackTrack test since Node.js won't handle our case, and disable new es-module tests since it's still flagged and requires flags to run properly

* fix missing files

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

* fix: don't error if can't find advapi32.dll

* fixup! chore: bump node in DEPS to v12.13.1

* Disable native tests for now
2019-12-18 09:49:09 -08:00
Electron Bot
96a88f02fb Bump v9.0.0-nightly.20191218 2019-12-18 07:32:07 -08:00
Jeremy Apthorp
7152173d26 ci: retry uploading pdb files on appveyor (#21561) 2019-12-18 06:30:18 -08:00
Jeremy Apthorp
3effa8bc46 feat: remove deprecated base::Value-based serialization (#21560)
* feat: remove deprecated base::Value-based serialization

* add note to breaking-changes
2019-12-18 15:25:15 +09:00
Jeremy Apthorp
1cac62f0a2 feat: remove deprecated base::Value-based serialization (#21560)
* feat: remove deprecated base::Value-based serialization

* add note to breaking-changes
2019-12-18 15:24:50 +09:00
liulun
cc8bf12351 docs: replace systemPreferences.isDarkMode() with nativeTheme.shouldUseDarkColors (#21480) 2019-12-17 15:13:35 -08:00
Shelley Vohr
f0d52eaf0c build: allow getOutDir cli argument (#21545) 2019-12-17 14:00:42 -08:00
Jeremy Apthorp
54b4756a29 refactor: try just using regular [Sync] for MessageSync (#20797) 2019-12-17 11:35:28 -08:00
Electron Bot
6cc9f0c34e Bump v9.0.0-nightly.20191217 2019-12-17 07:31:56 -08:00
Shelley Vohr
dba8a0caa8 feat: enable explicit IAP restoration (#21461) 2019-12-17 07:07:11 -08:00
Jeremy Apthorp
53957d47d6 test: clean up some stale code in renderer spec runner (#21384)
* test: clean up some stale code in renderer spec runner

* remove jquery from spec

* remove extraneous close tag

* Revert "remove jquery from spec"

This reverts commit 7b885c8ca8.

* re-clean-up html

* don't highlight tags

* update session docs; clear cache on boot

* clear user-data-dir before running tests
2019-12-17 11:15:12 +09:00
Javan Makhmali
b57d218466 docs: update webContents.printToPDF() example for promisified API (#21541) 2019-12-16 16:14:13 -08:00
Mark Lee
9c442e0a7e docs: update installation docs to reflect latest @electron/get changes (#21491)
* doc: update Chinese Electron mirror URL

* doc: replace remaining references of electron-download with @electron/get

* doc: update cache dir example based on recent @electron/get cache changes
2019-12-16 08:16:55 -08:00
Electron Bot
5f2b6f71b5 Bump v9.0.0-nightly.20191216 2019-12-16 07:32:21 -08:00
Joël Charles
0bcfae752e feat: allow pages to override window.history.length (#17742)
* fix: allow pages to override window.history.length

* Update lib/renderer/window-setup.ts

Co-Authored-By: magne4000 <joel.charles91@gmail.com>

* fix: lint error
2019-12-16 11:14:27 +09:00
Milan Burda
6a03d3cc66 refactor: export internalWindowOpen from guest-window-manager (#21498) 2019-12-16 10:30:25 +09:00
Electron Bot
a7f5aafaca Bump v9.0.0-nightly.20191215 2019-12-15 07:31:37 -08:00
John Kleinschmidt
48688f9124 ci: use cmd to call gclient (#21523) 2019-12-14 14:25:33 -05:00
Electron Bot
fb20bd74e6 Revert "Bump v9.0.0-nightly.20191214"
This reverts commit f09bef3ba2.
2019-12-14 08:09:49 -08:00
Electron Bot
f09bef3ba2 Bump v9.0.0-nightly.20191214 2019-12-14 07:31:54 -08:00
Electron Bot
0f2f9a580a chore: bump chromium to 94cc24d3bb17a7406ba6c6cc6dc29 (master) (#21485) 2019-12-13 12:13:12 -08:00
loc
19cd8f3a02 fix: avoid contextBridge crash when RenderFrame address is reused (#21501)
* fix: avoid contextBridge crash when RenderFrame address is reused

Co-Authored-By: Jeremy Apthorp <nornagon@nornagon.net>

* make routing_id_ const
2019-12-13 13:13:04 -05:00
Jeremy Apthorp
c535e00187 feat: enable pointer compression and 31bit smis (#21468) 2019-12-13 10:12:24 -08:00
Milan Burda
341df4a8c2 fix: enforce parent-child relationship in custom postMessage() handler (#21496) 2019-12-13 10:10:56 -08:00
Jeremy Apthorp
a90b5f8421 chore: fix patch linter (#21495) 2019-12-13 09:18:45 -08:00
Felix Rieseberg
7932e28aa2 docs: Explain notarization, improve code-signing docs (#21373)
* docs: Explain notarization

* Update docs/tutorial/code-signing.md

Co-Authored-By: Zeke Sikelianos <zeke@github.com>
2019-12-13 11:16:20 -05:00
Victor Bennich
cf833a7650 feat: add win.getBackgroundColor() for macOS (#21448)
thanks @vbennich - great work on this 🌟
2019-12-13 11:08:30 -05:00
Electron Bot
c1210f8ad3 Revert "Bump v9.0.0-nightly.20191213"
This reverts commit e6c23e1a5e.
2019-12-13 08:01:32 -08:00
Electron Bot
e6c23e1a5e Bump v9.0.0-nightly.20191213 2019-12-13 07:34:50 -08:00
Cheng Zhao
f9a1dc10fe fix: quit after Chromium is fully started (#21488)
* fix: quit when chromium is fully started

* test: remove hacks on app.quit

* chore: RunUntilIdle is unnecessary
2019-12-13 18:57:02 +09:00
Electron Bot
b9a250a623 Bump v9.0.0-nightly.20191212 2019-12-12 07:32:26 -08:00
Robo
63e600f655 fix: sourcemaps not loading with network service (#21473)
Backports https://chromium-review.googlesource.com/c/chromium/src/+/1525270
Backports https://chromium-review.googlesource.com/c/chromium/src/+/1852212
2019-12-11 23:58:17 -08:00
Robo
aa4b36a03d fix: avoid Electron.dsym files in the main app bundle (#21447)
* ci: CHECK_DIST_MANIFEST in release builds

* fix: skip Electron.dSYM on macOS app zip
2019-12-11 12:42:57 -05:00
Electron Bot
287592b5f6 Bump v9.0.0-nightly.20191211 2019-12-11 07:31:56 -08:00
Cheng Zhao
d5192853f9 fix: name and expirationDate should be optional when setting cookie (#21454)
* fix: correctly set cookie date

* fix: name is not required for setting cookie

* test: clear cookie after each cookie test

* test: should test session property

* chore: style fixes
2019-12-11 16:44:49 +09:00
Shelley Vohr
cbe1e3a1d0 fix: MediaKey globalShortcuts not working on macOS (#21442) 2019-12-11 15:48:55 +09:00
loc
5cecc230fb fix: restore POST forms that open a new window with target=_blank (#21469)
* fix: restore parts of original ResourceRequestBody V8 conversion

Restore some of the original conversion logic in order to fix target=_blank post form submissions.

* test: add test for POST form submission
2019-12-11 15:46:25 +09:00
Electron Bot
49b47ee4ed chore: bump chromium to f755b70e34659441e72c1a928a406 (master) (#21000) 2019-12-10 16:22:35 -08:00
J. Ryan Stinnett
a5c9bd53e0 fix: restore accessibility window title on macOS (#21462)
Electron's `AtomNSWindow` implements `accessibilityAttributeValue` to
provide various accessibility info to the OS, including window titles.

Chromium 75 changed to Apple's newer accessibility API for window titles
in the super class that `AtomNSWindow` inherits from. macOS still
supports both the old and new style APIs, but it will prefer the new
style if it is implemented.  This means the Electron window title is
being ignored because the newer API at the Chromium level has taken
precedence.

By implementing the newer accessibility API in `AtomNSWindow`, this
restores correct accessibility window titles in macOS Electron apps.

This is a regression has been present since Electron 6.0.0 (the first
release including the Chromium change above).
2019-12-10 15:03:00 -08:00
Electron Bot
9e866f8315 Bump v9.0.0-nightly.20191210 2019-12-10 07:32:16 -08:00
Cheng Zhao
a6d142a112 fix: window menu should handle keys correctly (#21434)
* fix: overriding AccessiblePaneView's methods

* chore: add CL link
2019-12-10 16:15:48 +09:00
Samuel Attard
ec0edb757a chore: workflows and pipeline state were split in the circle API (#21441) 2019-12-09 11:26:43 -08:00
Cheng Zhao
3cb0ed306b fix: hiding window menu should work on startup (#21436)
* fix: menu visibility should not be overwritten on startup

* fix: removing menu for window without global menubar

* test: setMenu tests are not for mac
2019-12-09 11:17:36 -08:00
Jeremy Apthorp
7f6b308bf1 test: move remote specs to main process (#21387) 2019-12-09 10:27:30 -08:00
Electron Bot
409ef49d3a Bump v9.0.0-nightly.20191209 2019-12-09 07:32:27 -08:00
Electron Bot
a5e84d0a2a Bump v9.0.0-nightly.20191208 2019-12-08 07:32:26 -08:00
Electron Bot
e3f36d3e0b Bump v9.0.0-nightly.20191207 2019-12-07 07:31:36 -08:00
Jeremy Apthorp
1f3561227d feat: add tracing info to WebContents IPC methods (#21404) 2019-12-06 13:15:23 -08:00
Jeremy Apthorp
092e00f7f0 fix: fix ClientRequest.getUploadProgress (#21388) 2019-12-06 13:14:44 -08:00
Jeremy Apthorp
dc9beda182 feat: remove deprecated setLayoutZoomLevelLimits (#21383) 2019-12-06 13:14:25 -08:00
Shelley Vohr
4ac575416f docs: fix return type of getPrinters (#21411) 2019-12-06 12:36:35 -08:00
Samuel Attard
5bc8809d64 fix: do not use messages after move (#21419) 2019-12-06 12:35:57 -08:00
loc
8a06ef11cf fix: ensure persistence store still exists when GC runs (#21402)
Fix a bad access crash that happens when a render frame is deleted (window closed) and garbage collection runs afterward.
2019-12-06 11:15:08 -08:00
Electron Bot
4037b12511 Bump v9.0.0-nightly.20191206 2019-12-06 07:31:51 -08:00
Tierney Cyren
6df7bd63e4 docs: improve Windows build variable documentation (#20548)
* docs: improve Windows build variable documentation

Documents an additional and possibly unclear variable, `DRIVE:`, in the example global variables for building with Windows

* docs: update formatting in build-instructions-windows.md to align with styleguide
2019-12-06 08:53:50 +09:00
John Kleinschmidt
63058b8a2d ci: fix crash on arm testing (#21407) 2019-12-05 14:44:02 -08:00
Shelley Vohr
9e189eac71 fix: pass noLink correctly on Windows (#21386) 2019-12-05 13:38:57 -08:00
Charles Kerr
93802a7e6f fix: remove minor "trailing whitespace" warnings (#21398) 2019-12-05 11:04:34 -08:00
Birunthan Mohanathas
5223d1d774 fix: Fix compositor recycling when creating new BrowserView (#21372)
In #20829, we fixed compositor recycling when switching between
BrowserViews, but it turns out that there is one additional case that we
need to handle. When we create a completely new BrowserView instance, it
starts of as visible (even when it hasn't been added to the window),
which means that it will need its own compositor instead of using the
recycled compositor.

To fix this, lets make BrowserViews hidden by default until they're
added to the window. See also #19988. This is a potentially breaking
change given that the initial value of `document.visibilityState` will
now be `hidden`, but given the experimental status of BrowserViews, I
think this is a fine change to make. The old behavior can be restored
with `webPreferences: { show: true }`.

Notes: Fix compositor recycling when creating new BrowserView
2019-12-05 09:37:42 -08:00
Electron Bot
fff484d4ea Bump v9.0.0-nightly.20191205 2019-12-05 07:33:07 -08:00
Cheng Zhao
0a741670a9 chore: remove native_mate (Part 14) (#21365)
* chore: remove uses of mate::Dictionary and mate::Handle

* chore: move CreateConstructor to gin_helper

* chore: remove native_mate

* chore: remove unneeded gin patch
2019-12-05 18:46:34 +09:00
Electron Bot
113b47d871 Bump v9.0.0-nightly.20191204 2019-12-04 07:32:41 -08:00
Yaser
143407ea1b docs: Adds Native-UI tray Fiddle example (#20526) 2019-12-04 15:38:53 +09:00
Yaser
1b61fe780e docs: adds Native-UI Open external links and the file manager Fiddle example (#20524) 2019-12-04 15:38:19 +09:00
Amor
5733507040 docs: update installation.md (#21331) 2019-12-04 15:11:09 +09:00
Milan Burda
01ab72d8c0 chore: remove unused shell/common/crash_reporter/win/crash_service.cc (#21349) 2019-12-04 15:09:58 +09:00
Electron Bot
c1845121e0 Bump v9.0.0-nightly.20191203 2019-12-03 07:32:38 -08:00
Jeremy Apthorp
9526c5584e fix: deprecate setLayoutZoomLevelLimits (#21296) 2019-12-02 13:27:03 -08:00
Shelley Vohr
c7cbc2e6b1 fix: backgroundThrottling rwh assignment (#21037)
* fix: backgroundThrottling rwh assignment

* fix: disable DOM timer throttling

* chore: fix typo
2019-12-02 10:29:03 -08:00
Alex Kondratyuk
f2f52c23b5 docs: rename ELECTRON_CACHE env variable to electron_config_cache (#21313) 2019-12-02 10:12:51 -08:00
Samuel Attard
ee58d60612 fix: ensure no node globals passively leak when nodeIntegration is disabled (#21342) 2019-12-02 10:09:47 -08:00
Electron Bot
66035a2448 Bump v9.0.0-nightly.20191202 2019-12-02 07:33:23 -08:00
liulun
3d2fa09db3 Two 'close' in this line (#21345) 2019-12-02 18:30:56 +09:00
Samuel Attard
0a60f455a9 build: add hashes to the external binary downloader (#21328) 2019-12-01 15:23:54 -08:00
Samuel Attard
b26a6793ba chore: delete the security issue template (#21344)
GitHub now automatically adds our security policy to the issue page in a Much Better ™️  way, this removes a duplicate
2019-12-01 15:23:31 -08:00
Electron Bot
469fc0ea36 Bump v9.0.0-nightly.20191201 2019-12-01 07:33:09 -08:00
Milan Burda
03824ef53f build: fix building with enable_builtin_spellchecker = false (#21334) 2019-11-30 14:17:46 -08:00
Electron Bot
74f698d7bc Bump v9.0.0-nightly.20191130 2019-11-30 07:31:23 -08:00
Electron Bot
ba77489cb6 Bump v9.0.0-nightly.20191129 2019-11-29 07:32:09 -08:00
Electron Bot
2129751966 Bump v9.0.0-nightly.20191128 2019-11-28 07:32:48 -08:00
Max
0618505722 build: disable strip_absolute_paths_from_debug_symbols on debug.gn (#20884) 2019-11-28 10:37:57 +09:00
Samuel Attard
01f5e9c5c4 build: make CI faster, magic contained within (#21086)
* build: cache the out directory for exact deps hash matches

* chore: generate a target based depshash discriminator

* fix: hash on gn args

* build: share logic on the mac builds

* build: ensure that the mksnapshot binary is built before stripping before zipping

* build: attach the workspace on macOS

* build: optimize the macOS checkout path for testing

* build: fix mksnapshot zip generation

* build: make the mac src cache restore work

* build: v2 out cache

* build: macOS cache restore is just stupidly slow

* build: strip more binaries

* build: attach the out cache to the workspace for macOS builds

* build: allow linux boxes to restore darwin out caches

* build: cat the deps hash target file

* build: ensure that the deps target hash matches on the linux box

* build: do not use host arch in target key

* build: force undefined in the target hash file

* build: only restore out cache when it isn't in the workspace

* build: fix the macOS cache workspace trick

* build: do not double restore

* build: remove the big stuff from the out dir

* build: workaround layer issue

* build: try it back on macOS again but with smaller thingy

* build: macOS needs the out cache now

* build: clean up for omptimal macOS path

* build: use old docker image

* build: idek at this point

* build: we need a deps hash

* build: yeah we need a checkout too

* chore: use testing env on save cache job

* chore: well that should fix the cache key thing

* chore: handle cross-OS path mismatch for src cache restore

* build: use a /portal directory to transfer the src cache appropriately

* build: use the correct docker image

* build: super perms for /portal

* build: increment out cache number

* build: ensure target hash is correct for args + disable pre-compiled headers on macOS

* build: wipe the cross-arch libffmpeg before building Electron
2019-11-27 16:29:53 -08:00
Jeremy Apthorp
f09cb114e4 test: retry beforeunload tests up to 3 times (#21293) 2019-11-27 09:42:54 -08:00
Electron Bot
06e349d074 Bump v9.0.0-nightly.20191127 2019-11-27 07:32:14 -08:00
Julio
96c4c48268 docs: app.dock could be undefined (#20609) 2019-11-27 22:23:13 +09:00
Shelley Vohr
5f365858c9 fix: correctly plumb checkboxChecked on win (#21248)
* fix: correctly plumb checkboxChecked on win

* address final style comment
2019-11-27 16:39:07 +09:00
Jeremy Apthorp
d25256dcf5 refactor: rewrite the net module to simplify state tracking (#21244) 2019-11-26 17:01:13 -08:00
Jeremy Apthorp
4149d76890 fix: restore --ignore-connections-limit functionality (#21286) 2019-11-26 13:27:33 -08:00
Samuel Attard
149aaeba94 feat: add session.addWordToSpellCheckerDictionary to allow custom words in the dictionary (#21266)
* feat: add session.addWordToSpellCheckerDictionary to allow custom words in the dictionary

* Update session.md
2019-11-26 13:16:43 -08:00
Electron Bot
8a9c7c484b Bump v9.0.0-nightly.20191126 2019-11-26 07:33:26 -08:00
OJ Kwon
ca61d2fae7 fix: allow reading body from non-2xx responses in net.request (#21055)
* fix(urlrequest): allow non-2xx repsponse results

- closes #21046

* test(net): add test cases to verify non-2xx body

* test(session): update spec to match clientrequest behavior

* test(net): update test cases to match clientrequest behavior

* spec: clean up async net spec
2019-11-25 14:34:25 -08:00
Jeremy Apthorp
2e25999c52 test: refactor net tests (#21265) 2019-11-25 12:56:18 -08:00
Samuel Attard
d84ba30541 fix: reloadIgnoringCache() should ignore the cache (#21263) 2019-11-25 11:12:58 -08:00
loc
f26b7931eb fix: add missing early return (#21264) 2019-11-25 11:03:54 -08:00
Electron Bot
27c764c66c Bump v9.0.0-nightly.20191125 2019-11-25 07:31:36 -08:00
Electron Bot
ab695fb2f7 Bump v9.0.0-nightly.20191124 2019-11-24 07:31:32 -08:00
Electron Bot
78ae5d410e Bump v9.0.0-nightly.20191123 2019-11-23 07:31:26 -08:00
Shelley Vohr
d20273f95b chore: improve nativeImage path converter error (#21243) 2019-11-22 19:16:43 -08:00
Samuel Attard
34452ee69e feat: expose executeJavaScriptInIsolatedWorld on webContents (#21190)
* feat: expose executeJavaScriptInIsolatedWorld on webContents

* Apply suggestions from code review

Co-Authored-By: loc <andy@slack-corp.com>
2019-11-22 15:33:55 -08:00
Jacob
a7c2f79a94 fix: prevent silent failure when DOM storage quota exceeded (#20899)
* test: update DOM storage quota limits test

* fix: update dom_storage_limits.patch (fixes #13465)

The previous version of this patch did not include
changes required to circumvent the quota enforcement
performed by StorageAreaImpl. Consequently when
the quota was exceeded, things still "appeared to
work" at first but then would later fail silently.
That is, the cache would be updated but the backing
store would not.

This could be fixed by disabling the code below
(from `content/browser/dom_storage/storage_area_impl.cc`)
```
  // Only check quota if the size is increasing, this allows
  // shrinking changes to pre-existing maps that are over budget.
  if (new_item_size > old_item_size && new_storage_used > max_size_) {
    if (map_state_ == MapState::LOADED_KEYS_ONLY) {
      receivers_.ReportBadMessage(
          "The quota in browser cannot exceed when there is only one "
          "renderer.");
    } else {
      std::move(callback).Run(false);
    }
    return;
  }
```

However, since this seems to have some unintended side-effects
(see updated notes in dom_storage_limits.patch) it seems
more prudent to simply increase the quota to a larger
yet still reasonable size rather than attempt to circumvent
the storage quota altogether.
2019-11-22 11:35:54 -08:00
Electron Bot
745363959a Bump v9.0.0-nightly.20191122 2019-11-22 07:31:58 -08:00
Jeremy Apthorp
033d309874 fix: record cpu_profiler data for main process (#21187)
* fix: record cpu_profiler data for main process

* kick ci
2019-11-21 18:05:41 -08:00
Shelley Vohr
135a64955c ci: handle network drive not being available (#21247)
Fixes 'The system cannot find the path specified' error when trying to save source to shared network drive.
2019-11-21 14:52:29 -08:00
Samuel Attard
0cadf2846b docs: remove string literal type from window events (#21235) 2019-11-21 11:12:03 -08:00
Bruce Auyeung
07b94ff578 docs: clarify uniqueness of WebContents.id, BrowserWindow.id (#21101) 2019-11-21 11:11:44 -08:00
Electron Bot
1da9959f57 Bump v9.0.0-nightly.20191121 2019-11-21 07:31:25 -08:00
Milan Burda
3f2cb91a35 refactor: declare KeyWeakMap<K, V> returned by createIDWeakMap() / createDoubleIDWeakMap() (#21171) 2019-11-21 13:32:31 +01:00
Julien Isorce
92ff39c168 ci: generate debug symbols on Linux (#18676) 2019-11-20 17:21:44 -08:00
Samuel Attard
41f1569c46 build: update release build endpoint from /jobs to /job (#21232) 2019-11-20 11:14:48 -08:00
Robo
0111f6216c fix: focus with OOPIF embedded inside <webview> (#21219)
Backports https://chromium-review.googlesource.com/c/chromium/src/+/1922650
2019-11-20 09:06:09 -08:00
John Kleinschmidt
4bc85f777f build: delete unneeded files when running a release (#21216)
* build: delete unneeded files when running a release

Needed to free up disk space on MacOS.

* Delete all the .git directories

* Update comment

* Run gn gen after deleting .git dirs
2019-11-20 10:42:38 -05:00
Electron Bot
af3bee742f Revert "Bump v9.0.0-nightly.20191120"
This reverts commit 99cafae1ec.
2019-11-20 07:37:12 -08:00
Electron Bot
99cafae1ec Bump v9.0.0-nightly.20191120 2019-11-20 07:31:46 -08:00
Cheng Zhao
50f2d2b5ab fix: menu should not be garbage-collected when popuping (#21169)
* fix: retain menu when popuping

* test: menu should not be garbage-collected when popuping
2019-11-20 20:17:39 +09:00
Samuel Attard
ea23f18e94 docs: document the channel param for event.reply (#21185) 2019-11-19 13:17:59 -08:00
Milan Burda
145dd33da1 spec: skip flaky <webview>.capturePage() test on Windows (#21175) 2019-11-19 12:57:35 -05:00
Electron Bot
6ca7eb79bc Bump v9.0.0-nightly.20191119 2019-11-19 07:32:04 -08:00
John Kleinschmidt
58abc757fd build: use symbol_level 1 for 32bit linux releases (#21193)
* build: use symbol_level 1 for 32bit linux releases

* Add comment
2019-11-19 06:36:16 -08:00
Samuel Attard
d34ba76eb6 build: use python3 to download external binaries (#21184)
* build: use python3 to download external binaries

* Update config.py
2019-11-19 06:08:20 -08:00
Robo
73467f00e3 fix: allow chromium to handle WM_NCCALCSIZE for frameless windows (#21164) 2019-11-19 06:07:10 -08:00
Samuel Attard
c8ed22def3 docs: fix isMactemplateImage type definition (#21166) 2019-11-18 10:57:22 -08:00
Jeremy Apthorp
4045852e6f fix: stream protocols sometimes flake out (#21113) 2019-11-18 10:47:29 -08:00
606 changed files with 10598 additions and 9638 deletions

View File

@@ -53,7 +53,7 @@ parameters:
# Build machines configs.
docker-image: &docker-image
docker:
- image: electronjs/build:697b894f36d127155e020f4e8ad4b2e5f6a09613
- image: electronjs/build:3bba0fdee0d5650e751c2561f1806f9138dfe56a
machine-linux-medium: &machine-linux-medium
<<: *docker-image
@@ -61,7 +61,7 @@ machine-linux-medium: &machine-linux-medium
machine-linux-2xlarge: &machine-linux-2xlarge
<<: *docker-image
resource_class: 2xlarge
resource_class: 2xlarge+
machine-mac: &machine-mac
macos:
@@ -81,6 +81,7 @@ env-release-build: &env-release-build
GN_CONFIG: //electron/build/args/release.gn
STRIP_BINARIES: true
GENERATE_SYMBOLS: true
CHECK_DIST_MANIFEST: '1'
env-headless-testing: &env-headless-testing
DISPLAY: ':99.0'
@@ -151,6 +152,14 @@ env-ninja-status: &env-ninja-status
env-disable-run-as-node: &env-disable-run-as-node
GN_BUILDFLAG_ARGS: 'enable_run_as_node = false'
env-32bit-release: &env-32bit-release
# Set symbol level to 1 for 32 bit releases because of https://crbug.com/648948
GN_BUILDFLAG_ARGS: 'symbol_level = 1'
env-macos-build: &env-macos-build
# Disable pre-compiled headers to reduce out size, only useful for rebuilds
GN_BUILDFLAG_ARGS: 'enable_precompiled_headers = false'
# Individual (shared) steps.
step-maybe-notify-slack-failure: &step-maybe-notify-slack-failure
run:
@@ -210,6 +219,15 @@ step-setup-env-for-build: &step-setup-env-for-build
command: |
# To find `gn` executable.
echo 'export CHROMIUM_BUILDTOOLS_PATH="'"$PWD"'/src/buildtools"' >> $BASH_ENV
# Setup Goma if applicable
if [ ! -z "$RAW_GOMA_AUTH" ] && [ "`uname`" == "Linux" ]; then
export USE_SCCACHE="false"
echo 'export USE_SCCACHE=false' >> $BASH_ENV
echo 'export USE_GOMA=true' >> $BASH_ENV
echo 'export NUMBER_OF_NINJA_PROCESSES=300' >> $BASH_ENV
echo $RAW_GOMA_AUTH > ~/.goma_oauth2_config
src/electron/external_binaries/goma/goma_ctl.py ensure_start
fi
if [ "$USE_SCCACHE" == "true" ]; then
# https://github.com/mozilla/sccache
@@ -252,10 +270,11 @@ step-get-more-space-on-mac: &step-get-more-space-on-mac
step-delete-git-directories: &step-delete-git-directories
run:
name: Delete src/.git directory on MacOS to free space
name: Delete all .git directories under src on MacOS to free space
command: |
if [ "`uname`" == "Darwin" ]; then
sudo rm -rf src/.git
cd src
( find . -type d -name ".git" ) | xargs rm -rf
fi
# On macOS the yarn install command during gclient sync was run on a linux
@@ -310,7 +329,11 @@ step-gn-gen-default: &step-gn-gen-default
name: Default GN gen
command: |
cd src
gn gen out/Default --args='import("'$GN_CONFIG'") cc_wrapper="'"$SCCACHE_PATH"'"'" $GN_EXTRA_ARGS $GN_BUILDFLAG_ARGS"
if [ "$USE_GOMA" == "true" ]; then
gn gen out/Default --args="import(\"$GN_CONFIG\") import(\"//electron/build/args/goma.gn\") $GN_EXTRA_ARGS $GN_BUILDFLAG_ARGS"
else
gn gen out/Default --args="import(\"$GN_CONFIG\") cc_wrapper=\"$SCCACHE_PATH\" $GN_EXTRA_ARGS $GN_BUILDFLAG_ARGS"
fi
step-gn-check: &step-gn-check
run:
@@ -329,6 +352,12 @@ step-electron-build: &step-electron-build
name: Electron build
no_output_timeout: 30m
command: |
# On arm platforms we generate a cross-arch ffmpeg that ninja does not seem
# to realize is not correct / should be rebuilt. We delete it here so it is
# rebuilt
if [ "$TRIGGER_ARM_TEST" == "true" ]; then
rm -f src/out/Default/libffmpeg.so
fi
cd src
ninja -C out/Default electron -j $NUMBER_OF_NINJA_PROCESSES
@@ -344,9 +373,18 @@ step-maybe-electron-dist-strip: &step-maybe-electron-dist-strip
run:
name: Strip electron binaries
command: |
if [ "$STRIP_BINARIES" == "true" ] && [ "`uname`" != "Darwin" ]; then
if [ "$STRIP_BINARIES" == "true" ] && [ "`uname`" == "Linux" ]; then
if [ x"$TARGET_ARCH" == x ]; then
target_cpu=x64
elif [ "$TARGET_ARCH" == "ia32" ]; then
target_cpu=x86
else
target_cpu="$TARGET_ARCH"
fi
cd src
electron/script/strip-binaries.py --target-cpu="$TARGET_ARCH"
electron/script/copy-debug-symbols.py --target-cpu="$target_cpu" --out-dir=out/Default/debug --compress
electron/script/strip-binaries.py --target-cpu="$target_cpu"
electron/script/add-debug-link.py --target-cpu="$target_cpu" --debug-dir=out/Default/debug
fi
step-electron-dist-build: &step-electron-dist-build
@@ -420,6 +458,9 @@ step-electron-publish: &step-electron-publish
run:
name: Publish Electron Dist
command: |
if [ "`uname`" == "Darwin" ]; then
rm -rf src/out/Default/obj
fi
cd src/electron
if [ "$UPLOAD_TO_S3" == "1" ]; then
echo 'Uploading Electron release distribution to S3'
@@ -471,7 +512,11 @@ step-ffmpeg-gn-gen: &step-ffmpeg-gn-gen
name: ffmpeg GN gen
command: |
cd src
gn gen out/ffmpeg --args='import("//electron/build/args/ffmpeg.gn") cc_wrapper="'"$SCCACHE_PATH"'"'" $GN_EXTRA_ARGS"
if [ "$USE_GOMA" == "true" ]; then
gn gen out/ffmpeg --args="import(\"//electron/build/args/ffmpeg.gn\") import(\"//electron/build/args/goma.gn\") $GN_EXTRA_ARGS"
else
gn gen out/ffmpeg --args="import(\"//electron/build/args/ffmpeg.gn\") cc_wrapper=\"$SCCACHE_PATH\" $GN_EXTRA_ARGS"
fi
step-ffmpeg-build: &step-ffmpeg-build
run:
@@ -509,17 +554,21 @@ step-setup-linux-for-headless-testing: &step-setup-linux-for-headless-testing
step-show-sccache-stats: &step-show-sccache-stats
run:
name: Check sccache stats after build
name: Check sccache/goma stats after build
command: |
if [ "$SCCACHE_PATH" != "" ]; then
$SCCACHE_PATH -s
fi
if [ "$USE_GOMA" == "true" ]; then
src/electron/external_binaries/goma/goma_ctl.py stat
fi
step-mksnapshot-build: &step-mksnapshot-build
run:
name: mksnapshot build
command: |
cd src
ninja -C out/Default electron:electron_mksnapshot -j $NUMBER_OF_NINJA_PROCESSES
if [ "`uname`" != "Darwin" ]; then
if [ "$TARGET_ARCH" == "arm" ]; then
electron/script/strip-binaries.py --file $PWD/out/Default/clang_x86_v8_arm/mksnapshot
@@ -527,6 +576,7 @@ step-mksnapshot-build: &step-mksnapshot-build
electron/script/strip-binaries.py --file $PWD/out/Default/clang_x64_v8_arm64/mksnapshot
else
electron/script/strip-binaries.py --file $PWD/out/Default/mksnapshot
electron/script/strip-binaries.py --file $PWD/out/Default/v8_context_snapshot_generator
fi
fi
if [ "$SKIP_DIST_ZIP" != "1" ]; then
@@ -644,7 +694,7 @@ step-ninja-report: &step-ninja-report
step-generate-deps-hash: &step-generate-deps-hash
run:
name: Generate DEPS Hash
command: node src/electron/script/generate-deps-hash.js
command: node src/electron/script/generate-deps-hash.js && cat src/electron/.depshash-target
step-touch-sync-done: &step-touch-sync-done
run:
@@ -656,10 +706,8 @@ step-touch-sync-done: &step-touch-sync-done
# If a cache is matched EXACTLY then the .circle-sync-done file contains "done"
step-maybe-restore-src-cache: &step-maybe-restore-src-cache
restore_cache:
paths:
- ./src
keys:
- v5-src-cache-{{ arch }}-{{ checksum "src/electron/.depshash" }}
- v7-src-cache-{{ checksum "src/electron/.depshash" }}
name: Restoring src cache
# Restore exact or closest git cache based on the hash of DEPS and .circle-sync-done
@@ -670,10 +718,18 @@ step-maybe-restore-git-cache: &step-maybe-restore-git-cache
paths:
- ~/.gclient-cache
keys:
- v2-gclient-cache-{{ arch }}-{{ checksum "src/electron/.circle-sync-done" }}-{{ checksum "src/electron/DEPS" }}
- v2-gclient-cache-{{ arch }}-{{ checksum "src/electron/.circle-sync-done" }}
- v2-gclient-cache-{{ checksum "src/electron/.circle-sync-done" }}-{{ checksum "src/electron/DEPS" }}
- v2-gclient-cache-{{ checksum "src/electron/.circle-sync-done" }}
name: Conditionally restoring git cache
step-restore-out-cache: &step-restore-out-cache
restore_cache:
paths:
- ./src/out/Default
keys:
- v7-out-cache-{{ checksum "src/electron/.depshash" }}-{{ checksum "src/electron/.depshash-target" }}
name: Restoring out cache
step-set-git-cache-path: &step-set-git-cache-path
run:
name: Set GIT_CACHE_PATH to make gclient to use the cache
@@ -688,9 +744,16 @@ step-save-git-cache: &step-save-git-cache
save_cache:
paths:
- ~/.gclient-cache
key: v2-gclient-cache-{{ arch }}-{{ checksum "src/electron/.circle-sync-done" }}-{{ checksum "src/electron/DEPS" }}
key: v2-gclient-cache-{{ checksum "src/electron/.circle-sync-done" }}-{{ checksum "src/electron/DEPS" }}
name: Persisting git cache
step-save-out-cache: &step-save-out-cache
save_cache:
paths:
- ./src/out/Default
key: v7-out-cache-{{ checksum "src/electron/.depshash" }}-{{ checksum "src/electron/.depshash-target" }}
name: Persisting out cache
step-run-electron-only-hooks: &step-run-electron-only-hooks
run:
name: Run Electron Only Hooks
@@ -699,7 +762,7 @@ step-run-electron-only-hooks: &step-run-electron-only-hooks
step-generate-deps-hash-cleanly: &step-generate-deps-hash-cleanly
run:
name: Generate DEPS Hash
command: (cd src/electron && git checkout .) && node src/electron/script/generate-deps-hash.js
command: (cd src/electron && git checkout .) && node src/electron/script/generate-deps-hash.js && cat src/electron/.depshash-target
# Mark the sync as done for future cache saving
step-mark-sync-done: &step-mark-sync-done
@@ -722,8 +785,8 @@ step-minimize-workspace-size-from-checkout: &step-minimize-workspace-size-from-c
step-save-src-cache: &step-save-src-cache
save_cache:
paths:
- ./src
key: v5-src-cache-{{ arch }}-{{ checksum "src/electron/.depshash" }}
- /portal
key: v7-src-cache-{{ checksum "/portal/src/electron/.depshash" }}
name: Persisting src cache
# Check for doc only change
@@ -816,40 +879,6 @@ steps-lint: &steps-lint
node script/yarn install --frozen-lockfile
node script/yarn lint
steps-checkout-fast: &steps-checkout-fast
steps:
- *step-checkout-electron
- *step-check-for-doc-only-change
- *step-persist-doc-only-change
- *step-maybe-early-exit-doc-only-change
- *step-depot-tools-get
- *step-depot-tools-add-to-path
- *step-restore-brew-cache
- *step-get-more-space-on-mac
- *step-install-gnutar-on-mac
- *step-generate-deps-hash
- *step-touch-sync-done
- *step-maybe-restore-src-cache
- *step-maybe-restore-git-cache
- *step-set-git-cache-path
# This sync call only runs if .circle-sync-done is an EMPTY file
- *step-gclient-sync
# These next few steps reset Electron to the correct commit regardless of which cache was restored
- run:
name: Wipe Electron
command: rm -rf src/electron
- *step-checkout-electron
- *step-run-electron-only-hooks
- *step-generate-deps-hash-cleanly
- *step-mark-sync-done
- *step-minimize-workspace-size-from-checkout
- persist_to_workspace:
root: .
paths:
- depot_tools
- src
steps-checkout-and-save-cache: &steps-checkout-and-save-cache
steps:
- *step-checkout-electron
@@ -864,7 +893,7 @@ steps-checkout-and-save-cache: &steps-checkout-and-save-cache
- *step-generate-deps-hash
- *step-touch-sync-done
- *step-maybe-restore-src-cache
- maybe-restore-portaled-src-cache
- *step-maybe-restore-git-cache
- *step-set-git-cache-path
# This sync call only runs if .circle-sync-done is an EMPTY file
@@ -879,6 +908,13 @@ steps-checkout-and-save-cache: &steps-checkout-and-save-cache
- *step-generate-deps-hash-cleanly
- *step-mark-sync-done
- *step-minimize-workspace-size-from-checkout
- *step-delete-git-directories
- run:
name: Move src folder to the cross-OS portal
command: |
sudo mkdir -p /portal
sudo chown -R $(id -u):$(id -g) /portal
mv ./src /portal
- *step-save-src-cache
- *step-save-brew-cache
@@ -903,8 +939,8 @@ steps-electron-build: &steps-electron-build
- *step-get-more-space-on-mac
- *step-install-npm-deps-on-mac
- *step-fix-sync-on-mac
- *step-gn-gen-default
- *step-delete-git-directories
- *step-gn-gen-default
# Electron app
- *step-electron-build
@@ -950,89 +986,6 @@ steps-electron-build: &steps-electron-build
- *step-maybe-notify-slack-failure
steps-electron-build-with-inline-checkout-for-tests: &steps-electron-build-with-inline-checkout-for-tests
steps:
# Checkout - Copied ffrom steps-checkout
- *step-checkout-electron
- *step-check-for-doc-only-change
- *step-persist-doc-only-change
- *step-maybe-early-exit-doc-only-change
- *step-depot-tools-get
- *step-depot-tools-add-to-path
- *step-restore-brew-cache
- *step-get-more-space-on-mac
- *step-install-gnutar-on-mac
- *step-generate-deps-hash
- *step-touch-sync-done
- *step-maybe-restore-src-cache
- *step-maybe-restore-git-cache
- *step-set-git-cache-path
# This sync call only runs if .circle-sync-done is an EMPTY file
- *step-gclient-sync
# These next few steps reset Electron to the correct commit regardless of which cache was restored
- run:
name: Wipe Electron
command: rm -rf src/electron
- *step-checkout-electron
- *step-run-electron-only-hooks
- *step-generate-deps-hash-cleanly
- *step-mark-sync-done
- *step-minimize-workspace-size-from-checkout
- *step-depot-tools-add-to-path
- *step-setup-env-for-build
- *step-restore-brew-cache
- *step-get-more-space-on-mac
- *step-install-npm-deps-on-mac
- *step-fix-sync-on-mac
- *step-gn-gen-default
- *step-delete-git-directories
# Electron app
- *step-electron-build
- *step-ninja-summary
- *step-ninja-report
- *step-maybe-electron-dist-strip
- *step-electron-dist-build
- *step-electron-dist-store
# Native test targets
- *step-native-unittests-build
- *step-native-unittests-store
# Node.js headers
- *step-nodejs-headers-build
- *step-nodejs-headers-store
- *step-show-sccache-stats
# mksnapshot
- *step-mksnapshot-build
- *step-mksnapshot-store
- *step-maybe-cross-arch-snapshot
- *step-maybe-cross-arch-snapshot-store
# ffmpeg
- *step-ffmpeg-gn-gen
- *step-ffmpeg-build
- *step-ffmpeg-store
# hunspell
- *step-hunspell-build
- *step-hunspell-store
# Save all data needed for a further tests run.
- *step-persist-data-for-tests
- *step-maybe-generate-breakpad-symbols
- *step-maybe-zip-symbols
- *step-symbols-store
# Trigger tests on arm hardware if needed
- *step-maybe-trigger-arm-test
- *step-maybe-notify-slack-failure
steps-electron-ts-compile-for-doc-change: &steps-electron-ts-compile-for-doc-change
steps:
# Checkout - Copied ffrom steps-checkout
@@ -1046,7 +999,7 @@ steps-electron-ts-compile-for-doc-change: &steps-electron-ts-compile-for-doc-cha
- *step-install-gnutar-on-mac
- *step-generate-deps-hash
- *step-touch-sync-done
- *step-maybe-restore-src-cache
- maybe-restore-portaled-src-cache
- *step-maybe-restore-git-cache
- *step-set-git-cache-path
# This sync call only runs if .circle-sync-done is an EMPTY file
@@ -1081,8 +1034,9 @@ steps-electron-build-for-publish: &steps-electron-build-for-publish
- *step-get-more-space-on-mac
- *step-gclient-sync
- *step-setup-env-for-build
- *step-gn-gen-default
- *step-delete-git-directories
- *step-minimize-workspace-size-from-checkout
- *step-gn-gen-default
# Electron app
- *step-electron-build
@@ -1271,6 +1225,202 @@ steps-test-node: &steps-test-node
chromium-upgrade-branches: &chromium-upgrade-branches
/chromium\-upgrade\/[0-9]+/
# Command Aliases
commands:
maybe-restore-portaled-src-cache:
steps:
- run:
name: Prepare for cross-OS sync restore
command: |
sudo mkdir -p /portal
sudo chown -R $(id -u):$(id -g) /portal
- *step-maybe-restore-src-cache
- run:
name: Fix the src cache restore point on macOS
command: |
if [ -d "/portal/src" ]; then
echo Relocating Cache
rm -rf src
mv /portal/src ./
fi
checkout-from-cache:
steps:
- *step-checkout-electron
- *step-maybe-early-exit-doc-only-change
- *step-depot-tools-get
- *step-depot-tools-add-to-path
- *step-generate-deps-hash
- maybe-restore-portaled-src-cache
- run:
name: Ensure src checkout worked
command: |
if [ ! -d "src/third_party/blink" ]; then
echo src cache was not restored for some reason, idk what happened here...
exit 1
fi
- run:
name: Wipe Electron
command: rm -rf src/electron
- *step-checkout-electron
- *step-run-electron-only-hooks
- *step-generate-deps-hash-cleanly
electron-build:
parameters:
attach:
type: boolean
default: false
persist:
type: boolean
default: true
persist-checkout:
type: boolean
default: false
checkout:
type: boolean
default: true
checkout-and-assume-cache:
type: boolean
default: false
build:
type: boolean
default: true
use-out-cache:
type: boolean
default: true
steps:
- when:
condition: << parameters.attach >>
steps:
- attach_workspace:
at: .
- *step-restore-brew-cache
- *step-install-gnutar-on-mac
- when:
condition: << parameters.checkout-and-assume-cache >>
steps:
- checkout-from-cache
- when:
condition: << parameters.checkout >>
steps:
# Checkout - Copied ffrom steps-checkout
- *step-checkout-electron
- *step-check-for-doc-only-change
- *step-persist-doc-only-change
- *step-maybe-early-exit-doc-only-change
- *step-depot-tools-get
- *step-depot-tools-add-to-path
- *step-get-more-space-on-mac
- *step-generate-deps-hash
- *step-touch-sync-done
- maybe-restore-portaled-src-cache
- *step-maybe-restore-git-cache
- *step-set-git-cache-path
# This sync call only runs if .circle-sync-done is an EMPTY file
- *step-gclient-sync
# These next few steps reset Electron to the correct commit regardless of which cache was restored
- run:
name: Wipe Electron
command: rm -rf src/electron
- *step-checkout-electron
- *step-run-electron-only-hooks
- *step-generate-deps-hash-cleanly
- *step-mark-sync-done
- *step-minimize-workspace-size-from-checkout
- when:
condition: << parameters.persist-checkout >>
steps:
- persist_to_workspace:
root: .
paths:
- depot_tools
- src
- when:
condition: << parameters.build >>
steps:
- *step-depot-tools-add-to-path
- *step-setup-env-for-build
- *step-get-more-space-on-mac
- *step-fix-sync-on-mac
- *step-delete-git-directories
- *step-gn-gen-default
# Electron app
- when:
condition: << parameters.use-out-cache >>
steps:
- *step-restore-out-cache
- *step-gn-gen-default
- *step-electron-build
- *step-ninja-summary
- *step-ninja-report
- *step-maybe-electron-dist-strip
- *step-electron-dist-build
- *step-electron-dist-store
# Native test targets
- *step-native-unittests-build
- *step-native-unittests-store
# Node.js headers
- *step-nodejs-headers-build
- *step-nodejs-headers-store
- *step-show-sccache-stats
# mksnapshot
- *step-mksnapshot-build
- *step-mksnapshot-store
- *step-maybe-cross-arch-snapshot
- *step-maybe-cross-arch-snapshot-store
# ffmpeg
- *step-ffmpeg-gn-gen
- *step-ffmpeg-build
- *step-ffmpeg-store
# hunspell
- *step-hunspell-build
- *step-hunspell-store
# Save all data needed for a further tests run.
- when:
condition: << parameters.persist >>
steps:
- *step-persist-data-for-tests
- when:
condition: << parameters.build >>
steps:
- *step-maybe-generate-breakpad-symbols
- *step-maybe-zip-symbols
- *step-symbols-store
- when:
condition: << parameters.build >>
steps:
- run:
name: Remove the big things on macOS, this seems to be better on average
command: |
if [ "`uname`" == "Darwin" ]; then
mkdir -p src/out/Default
cd src/out/Default
find . -type f -size +50M -delete
mkdir -p gen/electron
cd gen/electron
# These files do not seem to like being in a cache, let us remove them
find . -type f -name '*_pkg_info' -delete
fi
- when:
condition: << parameters.use-out-cache >>
steps:
- *step-save-out-cache
# Trigger tests on arm hardware if needed
- *step-maybe-trigger-arm-test
- *step-maybe-notify-slack-failure
# List of all jobs.
jobs:
# Layer 0: Lint. Standalone.
@@ -1293,7 +1443,12 @@ jobs:
environment:
<<: *env-linux-2xlarge
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_arm=True --custom-var=checkout_arm64=True'
<<: *steps-checkout-fast
steps:
- electron-build:
persist: false
build: false
checkout: true
persist-checkout: true
linux-checkout-and-save-cache:
<<: *machine-linux-2xlarge
@@ -1307,26 +1462,45 @@ jobs:
environment:
<<: *env-linux-2xlarge
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_pyyaml=True'
<<: *steps-checkout-fast
steps:
- electron-build:
persist: false
build: false
checkout: true
persist-checkout: true
linux-checkout-for-native-tests-with-no-patches:
<<: *machine-linux-2xlarge
environment:
<<: *env-linux-2xlarge
GCLIENT_EXTRA_ARGS: '--custom-var=apply_patches=False --custom-var=checkout_pyyaml=True'
<<: *steps-checkout-fast
steps:
- electron-build:
persist: false
build: false
checkout: true
persist-checkout: true
mac-checkout-fast:
<<: *machine-linux-2xlarge
environment:
<<: *env-linux-2xlarge
<<: *env-testing-build
<<: *env-macos-build
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_mac=True --custom-var=host_os=mac'
<<: *steps-checkout-fast
steps:
- electron-build:
persist: false
build: false
checkout: true
persist-checkout: true
mac-checkout-and-save-cache:
<<: *machine-linux-2xlarge
environment:
<<: *env-linux-2xlarge
<<: *env-testing-build
<<: *env-macos-build
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_mac=True --custom-var=host_os=mac'
<<: *steps-checkout-and-save-cache
@@ -1339,7 +1513,11 @@ jobs:
<<: *env-enable-sccache
<<: *env-ninja-status
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_arm=True --custom-var=checkout_arm64=True'
<<: *steps-electron-build-with-inline-checkout-for-tests
steps:
- electron-build:
persist: true
checkout: true
use-out-cache: false
linux-x64-testing-no-run-as-node:
<<: *machine-linux-2xlarge
@@ -1350,7 +1528,11 @@ jobs:
<<: *env-ninja-status
<<: *env-disable-run-as-node
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_arm=True --custom-var=checkout_arm64=True'
<<: *steps-electron-build-with-inline-checkout-for-tests
steps:
- electron-build:
persist: false
checkout: true
use-out-cache: false
linux-x64-testing-gn-check:
<<: *machine-linux-medium
@@ -1397,7 +1579,11 @@ jobs:
<<: *env-enable-sccache
<<: *env-ninja-status
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_arm=True --custom-var=checkout_arm64=True'
<<: *steps-electron-build-with-inline-checkout-for-tests
steps:
- electron-build:
persist: true
checkout: true
use-out-cache: false
linux-ia32-chromedriver:
<<: *machine-linux-medium
@@ -1428,6 +1614,7 @@ jobs:
<<: *env-ia32
<<: *env-release-build
<<: *env-enable-sccache
<<: *env-32bit-release
UPLOAD_TO_S3: << pipeline.parameters.upload-to-s3 >>
<<: *steps-electron-build-for-publish
@@ -1441,7 +1628,11 @@ jobs:
<<: *env-ninja-status
TRIGGER_ARM_TEST: true
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_arm=True --custom-var=checkout_arm64=True'
<<: *steps-electron-build-with-inline-checkout-for-tests
steps:
- electron-build:
persist: false
checkout: true
use-out-cache: false
linux-arm-chromedriver:
<<: *machine-linux-medium
@@ -1471,6 +1662,7 @@ jobs:
<<: *env-arm
<<: *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'
UPLOAD_TO_S3: << pipeline.parameters.upload-to-s3 >>
<<: *steps-electron-build-for-publish
@@ -1485,7 +1677,11 @@ jobs:
<<: *env-ninja-status
TRIGGER_ARM_TEST: true
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_arm=True --custom-var=checkout_arm64=True'
<<: *steps-electron-build-with-inline-checkout-for-tests
steps:
- electron-build:
persist: false
checkout: true
use-out-cache: false
linux-arm64-testing-gn-check:
<<: *machine-linux-medium
@@ -1534,7 +1730,14 @@ jobs:
<<: *env-testing-build
<<: *env-enable-sccache
<<: *env-ninja-status
<<: *steps-electron-build
<<: *env-macos-build
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_mac=True --custom-var=host_os=mac'
steps:
- electron-build:
persist: true
checkout: false
checkout-and-assume-cache: true
attach: false
osx-testing-gn-check:
<<: *machine-mac
@@ -1579,7 +1782,14 @@ jobs:
<<: *env-testing-build
<<: *env-enable-sccache
<<: *env-ninja-status
<<: *steps-electron-build
<<: *env-macos-build
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_mac=True --custom-var=host_os=mac'
steps:
- electron-build:
persist: true
checkout: false
checkout-and-assume-cache: true
attach: false
mas-testing-gn-check:
<<: *machine-mac
@@ -1970,7 +2180,7 @@ workflows:
- osx-testing:
requires:
- mac-checkout-fast
- mac-checkout-and-save-cache
- osx-testing-gn-check:
requires:
@@ -1982,7 +2192,7 @@ workflows:
- mas-testing:
requires:
- mac-checkout-fast
- mac-checkout-and-save-cache
- mas-testing-gn-check:
requires:

View File

@@ -1,10 +0,0 @@
---
name: Security report
about: Do not create an issue for security reports, send an email to security@electronjs.org
---
### Notice
**DO NOT** create an issue for security reports.
Send an email to: **security@electronjs.org**.

1
.gitignore vendored
View File

@@ -65,3 +65,4 @@ ts-gen
# Used to accelerate CI builds
.depshash
.depshash-target

311
BUILD.gn
View File

@@ -79,15 +79,11 @@ npm_action("build_electron_definitions") {
args = [ rebase_path("$target_gen_dir/tsc/typings/electron.d.ts") ]
inputs = auto_filenames.api_docs + [ "yarn.lock" ]
outputs = [
"$target_gen_dir/tsc/typings/electron.d.ts",
]
outputs = [ "$target_gen_dir/tsc/typings/electron.d.ts" ]
}
webpack_build("electron_browser_bundle") {
deps = [
":build_electron_definitions",
]
deps = [ ":build_electron_definitions" ]
inputs = auto_filenames.browser_bundle_deps
@@ -96,9 +92,7 @@ webpack_build("electron_browser_bundle") {
}
webpack_build("electron_renderer_bundle") {
deps = [
":build_electron_definitions",
]
deps = [ ":build_electron_definitions" ]
inputs = auto_filenames.renderer_bundle_deps
@@ -107,9 +101,7 @@ webpack_build("electron_renderer_bundle") {
}
webpack_build("electron_worker_bundle") {
deps = [
":build_electron_definitions",
]
deps = [ ":build_electron_definitions" ]
inputs = auto_filenames.worker_bundle_deps
@@ -118,9 +110,7 @@ webpack_build("electron_worker_bundle") {
}
webpack_build("electron_sandboxed_renderer_bundle") {
deps = [
":build_electron_definitions",
]
deps = [ ":build_electron_definitions" ]
inputs = auto_filenames.sandbox_bundle_deps
@@ -129,9 +119,7 @@ webpack_build("electron_sandboxed_renderer_bundle") {
}
webpack_build("electron_isolated_renderer_bundle") {
deps = [
":build_electron_definitions",
]
deps = [ ":build_electron_definitions" ]
inputs = auto_filenames.isolated_bundle_deps
@@ -140,9 +128,7 @@ webpack_build("electron_isolated_renderer_bundle") {
}
webpack_build("electron_content_script_bundle") {
deps = [
":build_electron_definitions",
]
deps = [ ":build_electron_definitions" ]
inputs = auto_filenames.content_script_bundle_deps
@@ -155,9 +141,7 @@ copy("atom_js2c_copy") {
"lib/common/asar.js",
"lib/common/asar_init.js",
]
outputs = [
"$target_gen_dir/js2c/{{source_file_part}}",
]
outputs = [ "$target_gen_dir/js2c/{{source_file_part}}" ]
}
action("atom_js2c") {
@@ -173,11 +157,11 @@ action("atom_js2c") {
webpack_sources = [
"$target_gen_dir/js2c/browser_init.js",
"$target_gen_dir/js2c/renderer_init.js",
"$target_gen_dir/js2c/worker_init.js",
"$target_gen_dir/js2c/content_script_bundle.js",
"$target_gen_dir/js2c/isolated_bundle.js",
"$target_gen_dir/js2c/renderer_init.js",
"$target_gen_dir/js2c/sandbox_bundle.js",
"$target_gen_dir/js2c/worker_init.js",
]
sources = webpack_sources + [
@@ -186,9 +170,7 @@ action("atom_js2c") {
]
inputs = sources + [ "//third_party/electron_node/tools/js2c.py" ]
outputs = [
"$root_gen_dir/atom_natives.cc",
]
outputs = [ "$root_gen_dir/atom_natives.cc" ]
script = "tools/js2c.py"
args = [ rebase_path("//third_party/electron_node") ] +
@@ -199,9 +181,7 @@ action("atom_js2c") {
target_gen_default_app_js = "$target_gen_dir/js/default_app"
typescript_build("default_app_js") {
deps = [
":build_electron_definitions",
]
deps = [ ":build_electron_definitions" ]
type_root = rebase_path("$target_gen_dir/tsc/electron/typings")
sources = filenames.default_app_ts_sources
@@ -213,16 +193,12 @@ typescript_build("default_app_js") {
copy("default_app_static") {
sources = filenames.default_app_static_sources
outputs = [
"$target_gen_default_app_js/{{source}}",
]
outputs = [ "$target_gen_default_app_js/{{source}}" ]
}
copy("default_app_octicon_deps") {
sources = filenames.default_app_octicon_sources
outputs = [
"$target_gen_default_app_js/electron/default_app/octicon/{{source_file_part}}",
]
outputs = [ "$target_gen_default_app_js/electron/default_app/octicon/{{source_file_part}}" ]
}
asar("default_app_asar") {
@@ -236,9 +212,7 @@ asar("default_app_asar") {
sources = get_target_outputs(":default_app_js") +
get_target_outputs(":default_app_static") +
get_target_outputs(":default_app_octicon_deps")
outputs = [
"$root_out_dir/resources/default_app.asar",
]
outputs = [ "$root_out_dir/resources/default_app.asar" ]
}
grit("resources") {
@@ -256,20 +230,14 @@ grit("resources") {
"target_gen_dir=" + rebase_path(target_gen_dir, root_build_dir),
]
deps = [
":copy_shell_devtools_discovery_page",
]
deps = [ ":copy_shell_devtools_discovery_page" ]
output_dir = "$target_gen_dir"
}
copy("copy_shell_devtools_discovery_page") {
sources = [
"//content/shell/resources/shell_devtools_discovery_page.html",
]
outputs = [
"$target_gen_dir/shell_devtools_discovery_page.html",
]
sources = [ "//content/shell/resources/shell_devtools_discovery_page.html" ]
outputs = [ "$target_gen_dir/shell_devtools_discovery_page.html" ]
}
if (is_linux) {
@@ -315,9 +283,7 @@ source_set("manifests") {
npm_action("electron_version_args") {
script = "generate-version-json"
outputs = [
"$target_gen_dir/electron_version.args",
]
outputs = [ "$target_gen_dir/electron_version.args" ]
args = rebase_path(outputs)
@@ -328,9 +294,7 @@ npm_action("electron_version_args") {
}
templated_file("electron_version_header") {
deps = [
":electron_version_args",
]
deps = [ ":electron_version_args" ]
template = "build/templates/electron_version.tmpl"
output = "$target_gen_dir/electron_version.h"
@@ -354,7 +318,7 @@ source_set("electron_lib") {
":resources",
"buildflags",
"chromium_src:chrome",
"native_mate",
"chromium_src:chrome_spellchecker",
"shell/common/api:mojo",
"//base:base_static",
"//base/allocator:buildflags",
@@ -383,12 +347,10 @@ source_set("electron_lib") {
"//media/mojo/mojom",
"//net:extras",
"//net:net_resources",
"//net:net_with_v8",
"//ppapi/host",
"//ppapi/proxy",
"//ppapi/shared_impl",
"//printing/buildflags",
"//services/audio/public/mojom:constants",
"//services/device/public/cpp/geolocation",
"//services/device/public/mojom",
"//services/proxy_resolver:lib",
@@ -400,7 +362,7 @@ source_set("electron_lib") {
"//third_party/electron_node:node_lib",
"//third_party/leveldatabase",
"//third_party/libyuv",
"//third_party/webrtc_overrides:init_webrtc",
"//third_party/webrtc_overrides:webrtc_component",
"//third_party/widevine/cdm:headers",
"//ui/base/idle",
"//ui/events:dom_keycode_converter",
@@ -482,10 +444,6 @@ source_set("electron_lib") {
]
}
if (enable_builtin_spellchecker) {
deps += [ "chromium_src:chrome_spellchecker" ]
}
if (is_mac) {
deps += [
"//components/remote_cocoa/app_shim",
@@ -668,9 +626,11 @@ source_set("electron_lib") {
"shell/renderer/printing/print_render_frame_helper_delegate.cc",
"shell/renderer/printing/print_render_frame_helper_delegate.h",
]
deps += [ "//components/printing/common:mojo_interfaces" ]
}
public_deps += [ "shell/common/extensions/api:extensions_features" ]
deps += [ "shell/common/extensions/api:extensions_features" ]
deps += [ "shell/common/extensions/api" ]
deps += [
"//components/pref_registry",
"//components/user_prefs",
@@ -718,15 +678,11 @@ if (is_mac) {
electron_version = read_file("ELECTRON_VERSION", "trim string")
mac_xib_bundle_data("electron_xibs") {
sources = [
"shell/common/resources/mac/MainMenu.xib",
]
sources = [ "shell/common/resources/mac/MainMenu.xib" ]
}
bundle_data("electron_framework_resources") {
public_deps = [
":packed_resources",
]
public_deps = [ ":packed_resources" ]
sources = []
if (icu_use_data_file) {
sources += [ "$root_out_dir/icudtl.dat" ]
@@ -741,9 +697,7 @@ if (is_mac) {
sources += [ "$root_out_dir/snapshot_blob.bin" ]
}
}
outputs = [
"{{bundle_resources_dir}}/{{source_file_part}}",
]
outputs = [ "{{bundle_resources_dir}}/{{source_file_part}}" ]
}
if (!is_component_build) {
@@ -754,9 +708,7 @@ if (is_mac) {
sources += [ "$root_out_dir/libffmpeg.dylib" ]
public_deps += [ "//third_party/ffmpeg:ffmpeg" ]
}
outputs = [
"{{bundle_contents_dir}}/Libraries/{{source_file_part}}",
]
outputs = [ "{{bundle_contents_dir}}/Libraries/{{source_file_part}}" ]
}
} else {
group("electron_framework_libraries") {
@@ -769,12 +721,8 @@ if (is_mac) {
"$root_out_dir/egl_intermediates/libEGL.dylib",
"$root_out_dir/egl_intermediates/libGLESv2.dylib",
]
outputs = [
"{{bundle_contents_dir}}/Libraries/{{source_file_part}}",
]
public_deps = [
"//ui/gl:angle_library_copy",
]
outputs = [ "{{bundle_contents_dir}}/Libraries/{{source_file_part}}" ]
public_deps = [ "//ui/gl:angle_library_copy" ]
}
# Add the SwiftShader .dylibs in the Libraries directory of the Framework.
@@ -783,42 +731,28 @@ if (is_mac) {
"$root_out_dir/egl_intermediates/libswiftshader_libEGL.dylib",
"$root_out_dir/egl_intermediates/libswiftshader_libGLESv2.dylib",
]
outputs = [
"{{bundle_contents_dir}}/Libraries/{{source_file_part}}",
]
public_deps = [
"//ui/gl:swiftshader_library_copy",
]
outputs = [ "{{bundle_contents_dir}}/Libraries/{{source_file_part}}" ]
public_deps = [ "//ui/gl:swiftshader_library_copy" ]
}
}
group("electron_angle_library") {
if (use_egl) {
deps = [
":electron_angle_binaries",
]
deps = [ ":electron_angle_binaries" ]
}
}
group("electron_swiftshader_library") {
if (use_egl) {
deps = [
":electron_swiftshader_binaries",
]
deps = [ ":electron_swiftshader_binaries" ]
}
}
bundle_data("electron_crashpad_helper") {
sources = [
"$root_out_dir/crashpad_handler",
]
sources = [ "$root_out_dir/crashpad_handler" ]
outputs = [
"{{bundle_resources_dir}}/{{source_file_part}}",
]
outputs = [ "{{bundle_resources_dir}}/{{source_file_part}}" ]
public_deps = [
"//third_party/crashpad/crashpad/handler:crashpad_handler",
]
public_deps = [ "//third_party/crashpad/crashpad/handler:crashpad_handler" ]
}
mac_framework_bundle("electron_framework") {
@@ -876,9 +810,7 @@ if (is_mac) {
assert(defined(invoker.helper_name_suffix))
output_name = electron_helper_name + invoker.helper_name_suffix
deps = [
":electron_framework+link",
]
deps = [ ":electron_framework+link" ]
if (!is_mas_build) {
deps += [ "//sandbox/mac:seatbelt" ]
}
@@ -912,9 +844,7 @@ if (is_mac) {
}
bundle_data("electron_app_framework_bundle_data") {
sources = [
"$root_out_dir/$electron_framework_name.framework",
]
sources = [ "$root_out_dir/$electron_framework_name.framework" ]
if (!is_mas_build) {
sources += [
"external_binaries/Mantle.framework",
@@ -922,12 +852,8 @@ if (is_mac) {
"external_binaries/Squirrel.framework",
]
}
outputs = [
"{{bundle_contents_dir}}/Frameworks/{{source_file_part}}",
]
public_deps = [
":electron_framework+link",
]
outputs = [ "{{bundle_contents_dir}}/Frameworks/{{source_file_part}}" ]
public_deps = [ ":electron_framework+link" ]
foreach(helper_params, content_mac_helpers) {
sources +=
@@ -947,15 +873,10 @@ if (is_mac) {
}
bundle_data("electron_login_helper_app") {
public_deps = [
":electron_login_helper",
]
sources = [
"$root_out_dir/$electron_login_helper_name.app",
]
outputs = [
"{{bundle_contents_dir}}/Library/LoginItems/{{source_file_part}}",
]
public_deps = [ ":electron_login_helper" ]
sources = [ "$root_out_dir/$electron_login_helper_name.app" ]
outputs =
[ "{{bundle_contents_dir}}/Library/LoginItems/{{source_file_part}}" ]
}
action("electron_app_lproj_dirs") {
@@ -970,15 +891,9 @@ if (is_mac) {
foreach(locale, locales_as_mac_outputs) {
bundle_data("electron_app_strings_${locale}_bundle_data") {
sources = [
"$target_gen_dir/app_infoplist_strings/$locale.lproj",
]
outputs = [
"{{bundle_resources_dir}}/$locale.lproj",
]
public_deps = [
":electron_app_lproj_dirs",
]
sources = [ "$target_gen_dir/app_infoplist_strings/$locale.lproj" ]
outputs = [ "{{bundle_resources_dir}}/$locale.lproj" ]
public_deps = [ ":electron_app_lproj_dirs" ]
}
}
group("electron_app_strings_bundle_data") {
@@ -997,9 +912,7 @@ if (is_mac) {
"$root_out_dir/resources/default_app.asar",
"shell/browser/resources/mac/electron.icns",
]
outputs = [
"{{bundle_resources_dir}}/{{source_file_part}}",
]
outputs = [ "{{bundle_resources_dir}}/{{source_file_part}}" ]
}
mac_app_bundle("electron_app") {
@@ -1030,9 +943,7 @@ if (is_mac) {
binary = "$root_out_dir/$electron_framework_name.framework/Versions/$electron_framework_version/$electron_framework_name"
symbol_dir = "$root_out_dir/breakpad_symbols"
dsym_file = "$root_out_dir/$electron_framework_name.dSYM/Contents/Resources/DWARF/$electron_framework_name"
deps = [
":electron_framework",
]
deps = [ ":electron_framework" ]
}
foreach(helper_params, content_mac_helpers) {
@@ -1043,9 +954,7 @@ if (is_mac) {
binary = "$root_out_dir/$electron_helper_name${_helper_suffix}.app/Contents/MacOS/$electron_helper_name${_helper_suffix}"
symbol_dir = "$root_out_dir/breakpad_symbols"
dsym_file = "$root_out_dir/$electron_helper_name${_helper_suffix}.dSYM/Contents/Resources/DWARF/$electron_helper_name${_helper_suffix}"
deps = [
":electron_helper_app_${_helper_target}",
]
deps = [ ":electron_helper_app_${_helper_target}" ]
}
}
@@ -1053,18 +962,15 @@ if (is_mac) {
binary = "$root_out_dir/$electron_product_name.app/Contents/MacOS/$electron_product_name"
symbol_dir = "$root_out_dir/breakpad_symbols"
dsym_file = "$root_out_dir/$electron_product_name.dSYM/Contents/Resources/DWARF/$electron_product_name"
deps = [
":electron_app",
]
deps = [ ":electron_app" ]
}
extract_symbols("swiftshader_egl_syms") {
binary = "$root_out_dir/libswiftshader_libEGL.dylib"
symbol_dir = "$root_out_dir/breakpad_symbols"
dsym_file = "$root_out_dir/libswiftshader_libEGL.dylib.dSYM/Contents/Resources/DWARF/libswiftshader_libEGL.dylib"
deps = [
"//third_party/swiftshader/src/OpenGL/libEGL:swiftshader_libEGL",
]
deps =
[ "//third_party/swiftshader/src/OpenGL/libEGL:swiftshader_libEGL" ]
}
extract_symbols("swiftshader_gles_syms") {
@@ -1080,9 +986,7 @@ if (is_mac) {
binary = "$root_out_dir/crashpad_handler"
symbol_dir = "$root_out_dir/breakpad_symbols"
dsym_file = "$root_out_dir/crashpad_handler.dSYM/Contents/Resources/DWARF/crashpad_handler"
deps = [
"//third_party/crashpad/crashpad/handler:crashpad_handler",
]
deps = [ "//third_party/crashpad/crashpad/handler:crashpad_handler" ]
}
group("electron_symbols") {
@@ -1143,9 +1047,7 @@ if (is_mac) {
data += [ "$root_out_dir/resources/default_app.asar" ]
}
public_deps = [
"//tools/v8_context_snapshot:v8_context_snapshot",
]
public_deps = [ "//tools/v8_context_snapshot:v8_context_snapshot" ]
if (is_win) {
sources += [
@@ -1202,17 +1104,14 @@ if (is_mac) {
extract_symbols("electron_app_symbols") {
binary = "$root_out_dir/$electron_project_name$_target_executable_suffix"
symbol_dir = "$root_out_dir/breakpad_symbols"
deps = [
":electron_app",
]
deps = [ ":electron_app" ]
}
extract_symbols("swiftshader_egl_symbols") {
binary = "$root_out_dir/swiftshader/libEGL$_target_shared_library_suffix"
symbol_dir = "$root_out_dir/breakpad_symbols"
deps = [
"//third_party/swiftshader/src/OpenGL/libEGL:swiftshader_libEGL",
]
deps =
[ "//third_party/swiftshader/src/OpenGL/libEGL:swiftshader_libEGL" ]
}
extract_symbols("swiftshader_gles_symbols") {
@@ -1284,9 +1183,7 @@ template("dist_zip") {
action(target_name) {
script = "//electron/build/zip.py"
deps = [
":$_runtime_deps_target",
]
deps = [ ":$_runtime_deps_target" ]
forward_variables_from(invoker,
[
"outputs",
@@ -1305,106 +1202,80 @@ template("dist_zip") {
}
copy("electron_license") {
sources = [
"LICENSE",
]
outputs = [
"$root_build_dir/{{source_file_part}}",
]
sources = [ "LICENSE" ]
outputs = [ "$root_build_dir/{{source_file_part}}" ]
}
copy("chromium_licenses") {
deps = [
"//components/resources:about_credits",
]
sources = [
"$root_gen_dir/components/resources/about_credits.html",
]
outputs = [
"$root_build_dir/LICENSES.chromium.html",
]
deps = [ "//components/resources:about_credits" ]
sources = [ "$root_gen_dir/components/resources/about_credits.html" ]
outputs = [ "$root_build_dir/LICENSES.chromium.html" ]
}
group("licenses") {
data_deps = [
":electron_license",
":chromium_licenses",
":electron_license",
]
}
copy("electron_version") {
sources = [
"ELECTRON_VERSION",
]
outputs = [
"$root_build_dir/version",
]
sources = [ "ELECTRON_VERSION" ]
outputs = [ "$root_build_dir/version" ]
}
dist_zip("electron_dist_zip") {
data_deps = [
":electron_app",
":licenses",
":electron_version",
":licenses",
]
if (is_linux) {
data_deps += [ "//sandbox/linux:chrome_sandbox" ]
}
outputs = [
"$root_build_dir/dist.zip",
]
outputs = [ "$root_build_dir/dist.zip" ]
}
dist_zip("electron_ffmpeg_zip") {
data_deps = [
"//third_party/ffmpeg",
]
outputs = [
"$root_build_dir/ffmpeg.zip",
]
data_deps = [ "//third_party/ffmpeg" ]
outputs = [ "$root_build_dir/ffmpeg.zip" ]
}
dist_zip("electron_chromedriver_zip") {
testonly = true
data_deps = [
"//chrome/test/chromedriver",
":licenses",
"//chrome/test/chromedriver",
]
outputs = [
"$root_build_dir/chromedriver.zip",
]
outputs = [ "$root_build_dir/chromedriver.zip" ]
}
mksnapshot_deps = [
":licenses",
"//tools/v8_context_snapshot:v8_context_snapshot_generator",
"//v8:mksnapshot($v8_snapshot_toolchain)",
]
group("electron_mksnapshot") {
public_deps = mksnapshot_deps
}
dist_zip("electron_mksnapshot_zip") {
data_deps = [
"//v8:mksnapshot($v8_snapshot_toolchain)",
"//tools/v8_context_snapshot:v8_context_snapshot_generator",
":licenses",
]
outputs = [
"$root_build_dir/mksnapshot.zip",
]
data_deps = mksnapshot_deps
outputs = [ "$root_build_dir/mksnapshot.zip" ]
}
copy("hunspell_dictionaries") {
sources = hunspell_dictionaries + hunspell_licenses
outputs = [
"$target_gen_dir/electron_hunspell/{{source_file_part}}",
]
outputs = [ "$target_gen_dir/electron_hunspell/{{source_file_part}}" ]
}
dist_zip("hunspell_dictionaries_zip") {
data_deps = [
":hunspell_dictionaries",
]
data_deps = [ ":hunspell_dictionaries" ]
flatten = true
outputs = [
"$root_build_dir/hunspell_dictionaries.zip",
]
outputs = [ "$root_build_dir/hunspell_dictionaries.zip" ]
}
group("electron") {
public_deps = [
":electron_app",
]
public_deps = [ ":electron_app" ]
}

11
DEPS
View File

@@ -6,14 +6,15 @@ gclient_gn_args = [
'checkout_libaom',
'checkout_nacl',
'checkout_oculus_sdk',
'checkout_openxr'
'checkout_openxr',
'checkout_google_benchmark'
]
vars = {
'chromium_version':
'dc9525d251bf30828899e4cd7161f6dc6507023f',
'8fe78d4711fb243c83a66a7fded00f3408107778',
'node_version':
'v12.13.0',
'v12.14.1',
'nan_version':
'2ee313aaca52e2b478965ac50eb5082520380d1b',
@@ -69,6 +70,8 @@ vars = {
False,
'checkout_android_native_support':
False,
'checkout_google_benchmark':
False,
}
deps = {
@@ -114,7 +117,7 @@ hooks = [
'pattern': 'src/electron/script/update-external-binaries.py',
'condition': 'download_external_binaries',
'action': [
'python',
'python3',
'src/electron/script/update-external-binaries.py',
],
},

View File

@@ -1 +1 @@
9.0.0-nightly.20191118
9.0.0-nightly.20200124

View File

@@ -1,4 +1,4 @@
Copyright (c) 2013-2019 GitHub Inc.
Copyright (c) 2013-2020 GitHub Inc.
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the

View File

@@ -78,7 +78,7 @@ build_script:
"https://github.com/electron/electron"
- ps: >-
if ($env:GN_CONFIG -eq 'release') {
gclient sync --with_branch_heads --with_tags --reset
$env:RUN_GCLIENT_SYNC="true"
} else {
cd src\electron
node script\generate-deps-hash.js
@@ -92,23 +92,37 @@ build_script:
python src/electron/script/update-external-binaries.py
} else {
# file does not exist, gclient sync, then zip
gclient sync --with_branch_heads --with_tags --reset
$env:RUN_GCLIENT_SYNC="true"
if ($env:TARGET_ARCH -ne 'ia32') {
# archive current source for future use
# only run on x64/woa to avoid contention saving
7z a $zipfile src -xr!android_webview -xr!electron -xr'!*\.git' -xr!third_party\WebKit\LayoutTests! -xr!third_party\blink\web_tests -xr!third_party\blink\perf_tests -slp -t7z -mmt=30
# only save on x64/woa to avoid contention saving
$env:SAVE_GCLIENT_SRC="true"
}
}
}
- if "%RUN_GCLIENT_SYNC%"=="true" ( gclient sync --with_branch_heads --with_tags --ignore_locks)
- ps: >-
if ($env:SAVE_GCLIENT_SRC -eq 'true') {
# archive current source for future use
# only run on x64/woa to avoid contention saving
if ($(7z a $zipfile src -xr!android_webview -xr!electron -xr'!*\.git' -xr!third_party\WebKit\LayoutTests! -xr!third_party\blink\web_tests -xr!third_party\blink\perf_tests -slp -t7z -mmt=30;$LASTEXITCODE -ne 0)) {
Write-warning "Could not save source to shared drive; continuing anyway"
}
}
- ps: >-
if (Test-Path 'env:RAW_GOMA_AUTH') {
$env:GOMA_OAUTH2_CONFIG_FILE = "$pwd\.goma_oauth2_config"
$env:RAW_GOMA_AUTH | Set-Content $env:GOMA_OAUTH2_CONFIG_FILE
.\src\electron\script\start-goma.ps1 -gomaDir "$pwd\src\electron\external_binaries\goma"
}
- cd src
- ps: $env:BUILD_CONFIG_PATH="//electron/build/args/%GN_CONFIG%.gn"
- gn gen out/Default "--args=import(\"%BUILD_CONFIG_PATH%\") %GN_EXTRA_ARGS% cc_wrapper=\"%SCCACHE_PATH%\""
- set BUILD_CONFIG_PATH=//electron/build/args/%GN_CONFIG%.gn
- if DEFINED RAW_GOMA_AUTH (gn gen out/Default "--args=import(\"%BUILD_CONFIG_PATH%\") import(\"//electron/build/args/goma.gn\") %GN_EXTRA_ARGS% ") else (gn gen out/Default "--args=import(\"%BUILD_CONFIG_PATH%\") %GN_EXTRA_ARGS% cc_wrapper=\"%SCCACHE_PATH%\"")
- gn check out/Default //electron:electron_lib
- gn check out/Default //electron:electron_app
- gn check out/Default //electron:manifests
- gn check out/Default //electron/shell/common/api:mojo
- ninja -C out/Default electron:electron_app
- if "%GN_CONFIG%"=="testing" ( python C:\Users\electron\depot_tools\post_build_ninja_summary.py -C out\Default )
- if DEFINED RAW_GOMA_AUTH (ninja -j 300 -C out/Default electron:electron_app) else (ninja -C out/Default electron:electron_app)
- if "%GN_CONFIG%"=="testing" ( python C:\Users\electron\depot_tools\post_build_ninja_summary.py -C out\Default )
- gn gen out/ffmpeg "--args=import(\"//electron/build/args/ffmpeg.gn\") %GN_EXTRA_ARGS%"
- ninja -C out/ffmpeg electron:electron_ffmpeg_zip
- ninja -C out/Default electron:electron_dist_zip
@@ -117,7 +131,7 @@ build_script:
- ninja -C out/Default electron:hunspell_dictionaries_zip
- ninja -C out/Default electron:electron_chromedriver_zip
- ninja -C out/Default third_party/electron_node:headers
- cmd /C %SCCACHE_PATH% --show-stats
- if DEFINED RAW_GOMA_AUTH (python electron\external_binaries\goma\goma_ctl.py stat)
- python electron/build/profile_toolchain.py --output-json=out/Default/windows_toolchain_profile.json
- appveyor PushArtifact out/Default/windows_toolchain_profile.json
- appveyor PushArtifact out/Default/dist.zip
@@ -138,12 +152,12 @@ build_script:
- ps: >-
if ($env:GN_CONFIG -eq 'release') {
python electron\script\zip-symbols.py
appveyor PushArtifact out/Default/symbols.zip
appveyor-retry appveyor PushArtifact out/Default/symbols.zip
} else {
# It's useful to have pdb files when debugging testing builds that are
# built on CI.
7z a pdb.zip out\Default\*.pdb
appveyor PushArtifact pdb.zip
appveyor-retry appveyor PushArtifact pdb.zip
}
- python electron/script/zip_manifests/check-zip-manifest.py out/Default/dist.zip electron/script/zip_manifests/dist_zip.win.%TARGET_ARCH%.manifest
test_script:

View File

@@ -17,6 +17,7 @@ ffmpeg_branding = "Chrome"
enable_basic_printing = true
angle_enable_vulkan_validation_layers = false
dawn_enable_vulkan_validation_layers = false
is_cfi = false

2
build/args/goma.gn Normal file
View File

@@ -0,0 +1,2 @@
goma_dir = rebase_path("//electron/external_binaries/goma")
use_goma = true

View File

@@ -34,9 +34,7 @@ template("extract_symbols") {
dump_syms_binary,
]
stamp_file = "${target_gen_dir}/${target_name}.stamp"
outputs = [
stamp_file,
]
outputs = [ stamp_file ]
args = [
"./" + rebase_path(dump_syms_binary, root_build_dir),
rebase_path(invoker.binary, root_build_dir),

View File

@@ -10,9 +10,7 @@ template("npm_action") {
]
script = "//electron/build/npm-run.py"
outputs = [
"$target_gen_dir/npm_pre_stamps/" + target_name + ".stamp",
]
outputs = [ "$target_gen_dir/npm_pre_stamps/" + target_name + ".stamp" ]
args = [
"--silent",

View File

@@ -81,9 +81,7 @@ template("mac_xib_bundle_data") {
"visibility",
])
public_deps = [
":$_compile_target_name",
]
public_deps = [ ":$_compile_target_name" ]
sources = get_target_outputs(":$_compile_target_name")
_output_path = "{{bundle_resources_dir}}"
@@ -91,8 +89,6 @@ template("mac_xib_bundle_data") {
_output_path = invoker.output_path
}
outputs = [
"$_output_path/{{source_file_part}}",
]
outputs = [ "$_output_path/{{source_file_part}}" ]
}
}

View File

@@ -15,12 +15,8 @@ template("templated_file") {
"inputs",
"outputs",
])
inputs = [
invoker.template,
]
outputs = [
invoker.output,
]
inputs = [ invoker.template ]
outputs = [ invoker.output ]
script = "//electron/build/generate-template.py"
args = [
rebase_path(invoker.template),

View File

@@ -27,8 +27,6 @@ template("webpack_build") {
rebase_path(invoker.out_file),
]
outputs = [
invoker.out_file,
]
outputs = [ invoker.out_file ]
}
}

View File

@@ -16,6 +16,10 @@ PATHS_TO_SKIP = [
'./libVkICD_mock_', #Skipping because these are outputs that we don't need
'./VkICD_mock_', #Skipping because these are outputs that we don't need
# Skipping because its an output of create_bundle from //build/config/mac/rules.gni
# that we don't need
'Electron.dSYM',
# //chrome/browser:resources depends on this via
# //chrome/browser/resources/ssl/ssl_error_assistant, but we don't need to
# ship it.
@@ -52,14 +56,13 @@ def main(argv):
with open(runtime_deps) as f:
for dep in f.readlines():
dep = dep.strip()
dist_files.add(dep)
if not skip_path(dep, dist_zip, target_cpu):
dist_files.add(dep)
if sys.platform == 'darwin' and not should_flatten:
execute(['zip', '-r', '-y', dist_zip] + list(dist_files))
else:
with zipfile.ZipFile(dist_zip, 'w', zipfile.ZIP_DEFLATED, allowZip64=True) as z:
for dep in dist_files:
if skip_path(dep, dist_zip, target_cpu):
continue
if os.path.isdir(dep):
for root, dirs, files in os.walk(dep):
for file in files:

View File

@@ -21,6 +21,7 @@ buildflag_header("buildflags") {
"ENABLE_ELECTRON_EXTENSIONS=$enable_electron_extensions",
"ENABLE_BUILTIN_SPELLCHECKER=$enable_builtin_spellchecker",
"ENABLE_PICTURE_IN_PICTURE=$enable_picture_in_picture",
"ENABLE_MEDIA_KEY_OVERRIDES=$enable_media_key_overrides",
"OVERRIDE_LOCATION_PROVIDER=$enable_fake_location_provider",
]
}

View File

@@ -22,6 +22,8 @@ declare_args() {
enable_picture_in_picture = true
enable_media_key_overrides = true
# Provide a fake location provider for mocking
# the geolocation responses. Disable it if you
# need to test with chromium's location provider.

View File

@@ -68,6 +68,7 @@ static_library("chrome") {
]
deps = [
"//chrome/browser:resource_prefetch_predictor_proto",
"//chrome/browser/ssl:proto",
"//components/feature_engagement:buildflags",
]
@@ -184,9 +185,9 @@ static_library("chrome") {
"//chrome/services/printing:lib",
"//components/printing/browser",
"//components/printing/renderer",
"//components/services/pdf_compositor",
"//components/services/pdf_compositor/public/cpp",
"//components/services/pdf_compositor/public/mojom",
"//components/services/print_compositor",
"//components/services/print_compositor/public/cpp",
"//components/services/print_compositor/public/mojom",
]
deps += [
@@ -229,6 +230,15 @@ static_library("chrome") {
"//components/vector_icons:vector_icons",
]
}
if (enable_electron_extensions) {
sources += [
"//chrome/renderer/extensions/extension_hooks_delegate.cc",
"//chrome/renderer/extensions/extension_hooks_delegate.h",
"//chrome/renderer/extensions/tabs_hooks_delegate.cc",
"//chrome/renderer/extensions/tabs_hooks_delegate.h",
]
}
}
source_set("plugins") {
@@ -308,45 +318,51 @@ source_set("plugins") {
# You may have to add new files here during the upgrade if //chrome/browser/spellchecker
# gets more files
source_set("chrome_spellchecker") {
sources = [
"//chrome/browser/spellchecker/spell_check_host_chrome_impl.cc",
"//chrome/browser/spellchecker/spell_check_host_chrome_impl.h",
"//chrome/browser/spellchecker/spellcheck_custom_dictionary.cc",
"//chrome/browser/spellchecker/spellcheck_custom_dictionary.h",
"//chrome/browser/spellchecker/spellcheck_factory.cc",
"//chrome/browser/spellchecker/spellcheck_factory.h",
"//chrome/browser/spellchecker/spellcheck_hunspell_dictionary.cc",
"//chrome/browser/spellchecker/spellcheck_hunspell_dictionary.h",
"//chrome/browser/spellchecker/spellcheck_language_blacklist_policy_handler.cc",
"//chrome/browser/spellchecker/spellcheck_language_blacklist_policy_handler.h",
"//chrome/browser/spellchecker/spellcheck_language_policy_handler.cc",
"//chrome/browser/spellchecker/spellcheck_language_policy_handler.h",
"//chrome/browser/spellchecker/spellcheck_service.cc",
"//chrome/browser/spellchecker/spellcheck_service.h",
"//chrome/common/pref_names.h",
]
sources = []
deps = []
libs = []
if (has_spellcheck_panel) {
if (enable_builtin_spellchecker) {
sources += [
"//chrome/browser/spellchecker/spell_check_panel_host_impl.cc",
"//chrome/browser/spellchecker/spell_check_panel_host_impl.h",
"//chrome/browser/spellchecker/spell_check_host_chrome_impl.cc",
"//chrome/browser/spellchecker/spell_check_host_chrome_impl.h",
"//chrome/browser/spellchecker/spellcheck_custom_dictionary.cc",
"//chrome/browser/spellchecker/spellcheck_custom_dictionary.h",
"//chrome/browser/spellchecker/spellcheck_factory.cc",
"//chrome/browser/spellchecker/spellcheck_factory.h",
"//chrome/browser/spellchecker/spellcheck_hunspell_dictionary.cc",
"//chrome/browser/spellchecker/spellcheck_hunspell_dictionary.h",
"//chrome/browser/spellchecker/spellcheck_language_blacklist_policy_handler.cc",
"//chrome/browser/spellchecker/spellcheck_language_blacklist_policy_handler.h",
"//chrome/browser/spellchecker/spellcheck_language_policy_handler.cc",
"//chrome/browser/spellchecker/spellcheck_language_policy_handler.h",
"//chrome/browser/spellchecker/spellcheck_service.cc",
"//chrome/browser/spellchecker/spellcheck_service.h",
"//chrome/common/pref_names.h",
]
if (has_spellcheck_panel) {
sources += [
"//chrome/browser/spellchecker/spell_check_panel_host_impl.cc",
"//chrome/browser/spellchecker/spell_check_panel_host_impl.h",
]
}
if (use_browser_spellchecker) {
sources += [
"//chrome/browser/spellchecker/spelling_request.cc",
"//chrome/browser/spellchecker/spelling_request.h",
]
}
deps += [
"//base:base_static",
"//components/language/core/browser",
"//components/spellcheck:buildflags",
"//components/sync",
]
}
if (use_browser_spellchecker) {
sources += [
"//chrome/browser/spellchecker/spelling_request.cc",
"//chrome/browser/spellchecker/spelling_request.h",
]
}
deps = [
"//base:base_static",
"//components/language/core/browser",
"//components/spellcheck:buildflags",
"//components/sync",
]
public_deps = [
"//components/spellcheck/browser",
"//components/spellcheck/common",

View File

@@ -1,33 +0,0 @@
## Docs Translations
This directory once contained unstructured translations of Electron's
documentation, but has been deprecated in favor of a new translation process
using [Crowdin], a GitHub-friendly platform for collaborative translation.
For more details, visit the [electron/i18n] repo.
## Contributing
If you're interested in helping translate Electron's docs, visit
[Crowdin] and log in with your GitHub account. And thanks!
## Offline Docs
If you miss having access to Electron's raw markdown files in your preferred
language, don't fret! You can still get raw docs, they're just in a
different place now. See [electron/i18n/tree/master/content]
To more easily view and browse offline docs in your language, clone the repo and use [vmd],
an Electron-based GitHub-styled markdown viewer:
```sh
npm i -g vmd
git clone https://github.com/electron/i18n
vmd electron-i18n/content/zh-CN
```
[crowdin.com/project/electron]: https://crowdin.com/project/electron
[Crowdin]: https://crowdin.com/project/electron
[electron/i18n]: https://github.com/electron/i18n#readme
[electron/i18n/tree/master/content]: https://github.com/electron/i18n/tree/master/content
[vmd]: http://ghub.io/vmd

View File

@@ -53,6 +53,7 @@ an issue:
* [Native File Drag & Drop](tutorial/native-file-drag-drop.md)
* [Offscreen Rendering](tutorial/offscreen-rendering.md)
* [Supporting macOS Dark Mode](tutorial/mojave-dark-mode-guide.md)
* [Web embeds in Electron](tutorial/web-embeds.md)
* [Accessibility](tutorial/accessibility.md)
* [Spectron](tutorial/accessibility.md#spectron)
* [Devtron](tutorial/accessibility.md#devtron)

View File

@@ -1303,7 +1303,7 @@ command line arguments that Chromium uses.
### `app.dock` _macOS_ _Readonly_
A [`Dock`](./dock.md) object that allows you to perform actions on your app icon in the user's
A [`Dock`](./dock.md) `| undefined` object that allows you to perform actions on your app icon in the user's
dock on macOS.
### `app.isPackaged` _Readonly_

View File

@@ -20,6 +20,30 @@ const { remote } = require('electron')
remote.webContents.fromId(webview.getWebContentsId())
```
### `webFrame.setLayoutZoomLevelLimits()`
Chromium has removed support for changing the layout zoom level limits, and it
is beyond Electron's capacity to maintain it. The function was deprecated in
Electron 8.x, and has been removed in Electron 9.x. The layout zoom level limits
are now fixed at a minimum of 0.25 and a maximum of 5.0, as defined
[here](https://chromium.googlesource.com/chromium/src/+/938b37a6d2886bf8335fc7db792f1eb46c65b2ae/third_party/blink/common/page/page_zoom.cc#11).
### Sending non-JS objects over IPC now throws an exception
In Electron 8.0, IPC was changed to use the Structured Clone Algorithm,
bringing significant performance improvements. To help ease the transition, the
old IPC serialization algorithm was kept and used for some objects that aren't
serializable with Structured Clone. In particular, DOM objects (e.g. `Element`,
`Location` and `DOMMatrix`), Node.js objects backed by C++ classes (e.g.
`process.env`, some members of `Stream`), and Electron objects backed by C++
classes (e.g. `WebContents`, `BrowserWindow` and `WebFrame`) are not
serializable with Structured Clone. Whenever the old algorithm was invoked, a
deprecation warning was printed.
In Electron 9.0, the old serialization algorithm has been removed, and sending
such non-serializable objects will now throw an "object could not be cloned"
error.
## Planned Breaking API Changes (8.0)
### Values sent over IPC are now serialized with Structured Clone Algorithm
@@ -92,7 +116,7 @@ However, it is recommended to avoid using the `remote` module altogether.
// main
const { ipcMain, webContents } = require('electron')
const getGuestForWebContents = function (webContentsId, contents) {
const getGuestForWebContents = (webContentsId, contents) => {
const guest = webContents.fromId(webContentsId)
if (!guest) {
throw new Error(`Invalid webContentsId: ${webContentsId}`)
@@ -114,6 +138,14 @@ const { ipcRenderer } = require('electron')
ipcRenderer.invoke('openDevTools', webview.getWebContentsId())
```
### `webFrame.setLayoutZoomLevelLimits()`
Chromium has removed support for changing the layout zoom level limits, and it
is beyond Electron's capacity to maintain it. The function will emit a warning
in Electron 8.x, and cease to exist in Electron 9.x. The layout zoom level
limits are now fixed at a minimum of 0.25 and a maximum of 5.0, as defined
[here](https://chromium.googlesource.com/chromium/src/+/938b37a6d2886bf8335fc7db792f1eb46c65b2ae/third_party/blink/common/page/page_zoom.cc#11).
## Planned Breaking API Changes (7.0)
### Node Headers URL

View File

@@ -229,6 +229,7 @@ It creates a new `BrowserWindow` with native properties as set by the `options`.
unless hovered over in the top left of the window. These custom buttons prevent
issues with mouse events that occur with the standard window toolbar buttons.
**Note:** This option is currently experimental.
* `trafficLightPosition` [Point](structures/point.md) (optional) - Set a custom position for the traffic light buttons. Can only be used with `titleBarStyle` set to `hidden`
* `fullscreenWindowTitle` Boolean (optional) - Shows the title in the
title bar in full screen mode on macOS for all `titleBarStyle` options.
Default is `false`.
@@ -517,7 +518,7 @@ Emitted when the window is restored from a minimized state.
Returns:
* `event` Event
* `newBounds` [`Rectangle`](structures/rectangle.md) - Size the window is being resized to.
* `newBounds` [Rectangle](structures/rectangle.md) - Size the window is being resized to.
Emitted before the window is resized. Calling `event.preventDefault()` will prevent the window from being resized.
@@ -532,7 +533,7 @@ Emitted after the window has been resized.
Returns:
* `event` Event
* `newBounds` [`Rectangle`](structures/rectangle.md) - Location the window is being moved to.
* `newBounds` [Rectangle](structures/rectangle.md) - Location the window is being moved to.
Emitted before the window is moved. On Windows, calling `event.preventDefault()` will prevent the window from being moved.
@@ -772,7 +773,7 @@ events.
#### `win.id` _Readonly_
A `Integer` property representing the unique ID of the window.
A `Integer` property representing the unique ID of the window. Each ID is unique among all `BrowserWindow` instances of the entire Electron application.
#### `win.autoHideMenuBar`
@@ -963,13 +964,10 @@ Perhaps there are 15 pixels of controls on the left edge, 25 pixels of controls
on the right edge and 50 pixels of controls below the player. In order to
maintain a 16:9 aspect ratio (standard aspect ratio for HD @1920x1080) within
the player itself we would call this function with arguments of 16/9 and
[ 40, 50 ]. The second argument doesn't care where the extra width and height
{ width: 40, height: 50 }. The second argument doesn't care where the extra width and height
are within the content view--only that they exist. Sum any extra width and
height areas you have within the overall content view.
Calling this function with a value of `0` will remove any previously set aspect
ratios.
#### `win.setBackgroundColor(backgroundColor)`
* `backgroundColor` String - Window's background color as a hexadecimal value,
@@ -1019,6 +1017,11 @@ console.log(win.getBounds())
Returns [`Rectangle`](structures/rectangle.md) - The `bounds` of the window as `Object`.
#### `win.getBackgroundColor()`
Returns `String` - Gets the background color of the window. See [Setting
`backgroundColor`](#setting-backgroundcolor).
#### `win.setContentBounds(bounds[, animate])`
* `bounds` [Rectangle](structures/rectangle.md)
@@ -1622,12 +1625,9 @@ can still bring up the menu bar by pressing the single `Alt` key.
Returns `Boolean` - Whether the menu bar is visible.
#### `win.setVisibleOnAllWorkspaces(visible[, options])`
#### `win.setVisibleOnAllWorkspaces(visible)`
* `visible` Boolean
* `options` Object (optional)
* `visibleOnFullScreen` Boolean (optional) _macOS_ - Sets whether
the window should be visible above fullscreen windows
Sets whether the window should be visible on all workspaces.

View File

@@ -32,8 +32,8 @@ the hostname and the port number 'hostname:port'.
* `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
deferred until [`request.followRedirect`](#requestfollowredirect) is invoked. Listen for the [`redirect`](#event-redirect) event in
this mode to get more details about the redirect request.
cancelled unless [`request.followRedirect`](#requestfollowredirect) is invoked
synchronously during the [`redirect`](#event-redirect) event.
`options` properties such as `protocol`, `host`, `hostname`, `port` and `path`
strictly follow the Node.js model as described in the
@@ -136,8 +136,11 @@ Returns:
* `redirectUrl` String
* `responseHeaders` Record<String, String[]>
Emitted when there is redirection and the mode is `manual`. Calling
[`request.followRedirect`](#requestfollowredirect) will continue with the redirection.
Emitted when the server returns a redirect response (e.g. 301 Moved
Permanently). Calling [`request.followRedirect`](#requestfollowredirect) will
continue with the redirection. If this event is handled,
[`request.followRedirect`](#requestfollowredirect) must be called
**synchronously**, otherwise the request will be cancelled.
### Instance Properties
@@ -214,7 +217,8 @@ response object,it will emit the `aborted` event.
#### `request.followRedirect()`
Continues any deferred redirection request when the redirection mode is `manual`.
Continues any pending redirection. Can only be called during a `'redirect'`
event.
#### `request.getUploadProgress()`

View File

@@ -38,6 +38,9 @@ Get a set of category groups. The category groups can change as new code paths
are reached. See also the [list of built-in tracing
categories](https://chromium.googlesource.com/chromium/src/+/master/base/trace_event/builtin_categories.h).
> **NOTE:** Electron adds a non-default tracing category called `"electron"`.
> This category can be used to capture Electron-specific tracing events.
### `contentTracing.startRecording(options)`
* `options` ([TraceConfig](structures/trace-config.md) | [TraceCategoriesAndOptions](structures/trace-categories-and-options.md))

View File

@@ -120,7 +120,7 @@ Returns `Promise<Object>` - Resolve with an object containing the following:
* `canceled` Boolean - whether or not the dialog was canceled.
* `filePaths` String[] - An array of file paths chosen by the user. If the dialog is cancelled this will be an empty array.
* `bookmarks` String[] (optional) _macOS_ _mas_ - An array matching the `filePaths` array of base64 encoded strings which contains security scoped bookmark data. `securityScopedBookmarks` must be enabled for this to be populated.
* `bookmarks` String[] (optional) _macOS_ _mas_ - An array matching the `filePaths` array of base64 encoded strings which contains security scoped bookmark data. `securityScopedBookmarks` must be enabled for this to be populated. (For return values, see [table here](#bookmarks-array).)
The `browserWindow` argument allows the dialog to attach itself to a parent window, making it modal.
@@ -215,7 +215,7 @@ The `filters` specifies an array of file types that can be displayed, see
Returns `Promise<Object>` - Resolve with an object containing the following:
* `canceled` Boolean - whether or not the dialog was canceled.
* `filePath` String (optional) - If the dialog is canceled, this will be `undefined`.
* `bookmark` String (optional) _macOS_ _mas_ - Base64 encoded string which contains the security scoped bookmark data for the saved file. `securityScopedBookmarks` must be enabled for this to be present.
* `bookmark` String (optional) _macOS_ _mas_ - Base64 encoded string which contains the security scoped bookmark data for the saved file. `securityScopedBookmarks` must be enabled for this to be present. (For return values, see [table here](#bookmarks-array).)
The `browserWindow` argument allows the dialog to attach itself to a parent window, making it modal.
@@ -350,6 +350,17 @@ On Windows the options are more limited, due to the Win32 APIs used:
* The `browserWindow` argument is ignored since it is not possible to make
this confirmation dialog modal.
## Bookmarks array
`showOpenDialog`, `showOpenDialogSync`, `showSaveDialog`, and `showSaveDialogSync` will return a `bookmarks` array.
| Build Type | securityScopedBookmarks boolean | Return Type | Return Value |
|------------|---------------------------------|:-----------:|--------------------------------|
| macOS mas | True | Success | `['LONGBOOKMARKSTRING']` |
| macOS mas | True | Error | `['']` (array of empty string) |
| macOS mas | False | NA | `[]` (empty array) |
| non mas | any | NA | `[]` (empty array) |
## Sheets
On macOS, dialogs are presented as sheets attached to a window if you provide

View File

@@ -48,6 +48,7 @@ Unsupported options are:
```sh
--max-http-header-size
--http-parser
```
### `GOOGLE_API_KEY`

View File

@@ -40,11 +40,17 @@ Retrieves the product descriptions.
### `inAppPurchase.canMakePayments()`
Returns `Boolean`, whether a user can make a payment.
Returns `Boolean` - whether a user can make a payment.
### `inAppPurchase.restoreCompletedTransactions()`
Restores finished transactions. This method can be called either to install purchases on additional devices, or to restore purchases for an application that the user deleted and reinstalled.
[The payment queue](https://developer.apple.com/documentation/storekit/skpaymentqueue?language=objc) delivers a new transaction for each previously completed transaction that can be restored. Each transaction includes a copy of the original transaction.
### `inAppPurchase.getReceiptURL()`
Returns `String`, the path to the receipt.
Returns `String` - the path to the receipt.
### `inAppPurchase.finishAllTransactions()`

View File

@@ -14,7 +14,7 @@ See [`Menu`](menu.md) for examples.
* `menuItem` MenuItem
* `browserWindow` [BrowserWindow](browser-window.md)
* `event` [KeyboardEvent](structures/keyboard-event.md)
* `role` String (optional) - Can be `undo`, `redo`, `cut`, `copy`, `paste`, `pasteAndMatchStyle`, `delete`, `selectAll`, `reload`, `forceReload`, `toggleDevTools`, `resetZoom`, `zoomIn`, `zoomOut`, `togglefullscreen`, `window`, `minimize`, `close`, `help`, `about`, `services`, `hide`, `hideOthers`, `unhide`, `quit`, `startSpeaking`, `stopSpeaking`, `close`, `minimize`, `zoom`, `front`, `appMenu`, `fileMenu`, `editMenu`, `viewMenu`, `recentDocuments`, `toggleTabBar`, `selectNextTab`, `selectPreviousTab`, `mergeAllWindows`, `clearRecentDocuments`, `moveTabToNewWindow` or `windowMenu` - Define the action of the menu item, when specified the
* `role` String (optional) - Can be `undo`, `redo`, `cut`, `copy`, `paste`, `pasteAndMatchStyle`, `delete`, `selectAll`, `reload`, `forceReload`, `toggleDevTools`, `resetZoom`, `zoomIn`, `zoomOut`, `togglefullscreen`, `window`, `minimize`, `close`, `help`, `about`, `services`, `hide`, `hideOthers`, `unhide`, `quit`, `startSpeaking`, `stopSpeaking`, `minimize`, `zoom`, `front`, `appMenu`, `fileMenu`, `editMenu`, `viewMenu`, `recentDocuments`, `toggleTabBar`, `selectNextTab`, `selectPreviousTab`, `mergeAllWindows`, `clearRecentDocuments`, `moveTabToNewWindow` or `windowMenu` - Define the action of the menu item, when specified the
`click` property will be ignored. See [roles](#roles).
* `type` String (optional) - Can be `normal`, `separator`, `submenu`, `checkbox` or
`radio`.
@@ -130,8 +130,7 @@ dynamically changed.
#### `menuItem.label`
A `String` indicating the item's visible label, this property can be
dynamically changed.
A `String` indicating the item's visible label.
#### `menuItem.click`
@@ -165,7 +164,7 @@ item's icon, if set.
#### `menuItem.sublabel`
A `String` indicating the item's sublabel, this property can be dynamically changed.
A `String` indicating the item's sublabel.
#### `menuItem.toolTip` _macOS_
@@ -197,7 +196,9 @@ You can add a `click` function for additional behavior.
#### `menuItem.registerAccelerator`
A `Boolean` indicating if the accelerator should be registered with the
system or just displayed, this property can be dynamically changed.
system or just displayed.
This property can be dynamically changed.
#### `menuItem.commandId`

View File

@@ -329,9 +329,9 @@ can be called on empty images.
[buffer]: https://nodejs.org/api/buffer.html#buffer_class_buffer
## Properties
### Instance Properties
### `nativeImage.isMacTemplateImage` _macOS_
#### `nativeImage.isMacTemplateImage` _macOS_
A `Boolean` property that determines whether the image is considered a [template image](https://developer.apple.com/documentation/appkit/nsimage/1520017-template).

View File

@@ -126,9 +126,10 @@ Clears the sessions HTTP cache.
`scheme://host:port`.
* `storages` String[] (optional) - The types of storages to clear, can contain:
`appcache`, `cookies`, `filesystem`, `indexdb`, `localstorage`,
`shadercache`, `websql`, `serviceworkers`, `cachestorage`.
`shadercache`, `websql`, `serviceworkers`, `cachestorage`. If not
specified, clear all storage types.
* `quotas` String[] (optional) - The types of quotas to clear, can contain:
`temporary`, `persistent`, `syncable`.
`temporary`, `persistent`, `syncable`. If not specified, clear all quotas.
Returns `Promise<void>` - resolves when the storage data has been cleared.
@@ -464,12 +465,16 @@ The built in spellchecker does not automatically detect what language a user is
spell checker to correctly check their words you must call this API with an array of language codes. You can
get the list of supported language codes with the `ses.availableSpellCheckerLanguages` property.
**Note:** On macOS the OS spellchecker is used and will detect your language automatically. This API is a no-op on macOS.
#### `ses.getSpellCheckerLanguages()`
Returns `String[]` - An array of language codes the spellchecker is enabled for. If this list is empty the spellchecker
will fallback to using `en-US`. By default on launch if this setting is an empty list Electron will try to populate this
setting with the current OS locale. This setting is persisted across restarts.
**Note:** On macOS the OS spellchecker is used and has it's own list of languages. This API is a no-op on macOS.
#### `ses.setSpellCheckerDictionaryDownloadURL(url)`
* `url` String - A base URL for Electron to download hunspell dictionaries from.
@@ -479,6 +484,16 @@ behavior you can use this API to point the dictionary downloader at your own hos
dictionaries. We publish a `hunspell_dictionaries.zip` file with each release which contains the files you need
to host here.
**Note:** On macOS the OS spellchecker is used and therefore we do not download any dictionary files. This API is a no-op on macOS.
#### `ses.addWordToSpellCheckerDictionary(word)`
* `word` String - The word you want to add to the dictionary
Returns `Boolean` - Whether the word was successfully written to the custom dictionary.
**Note:** On macOS and Windows 10 this word will be written to the OS custom dictionary as well
### Instance Properties
The following properties are available on instances of `Session`:
@@ -504,12 +519,12 @@ A [`Protocol`](protocol.md) object for this session.
const { app, session } = require('electron')
const path = require('path')
app.on('ready', function () {
app.on('ready', () => {
const protocol = session.fromPartition('some-partition').protocol
protocol.registerFileProtocol('atom', function (request, callback) {
var url = request.url.substr(7)
protocol.registerFileProtocol('atom', (request, callback) => {
let url = request.url.substr(7)
callback({ path: path.normalize(`${__dirname}/${url}`) })
}, function (error) {
}, (error) => {
if (error) console.error('Failed to register protocol')
})
})
@@ -522,7 +537,7 @@ A [`NetLog`](net-log.md) object for this session.
```javascript
const { app, session } = require('electron')
app.on('ready', async function () {
app.on('ready', async () => {
const netLog = session.fromPartition('some-partition').netLog
netLog.startLogging('/path/to/net-log')
// After some network events

View File

@@ -28,10 +28,7 @@ Show the given file in a file manager. If possible, select the file.
* `path` String
Returns `Promise<Object>` - Resolve with an object containing the following:
* `success` Boolean - whether or not the path was successfully opened in the desktop's default manner.
* `errorMessage` String (optional) - The error message corresponding to the failure if a failure occurred, otherwise empty string.
Returns `Promise<String>` - Resolves with an string containing the error message corresponding to the failure if a failure occurred, otherwise "".
Open the given file in the desktop's default manner.

View File

@@ -4,4 +4,5 @@
* `returnValue` any - Set this to the value to be returned in a synchronous message
* `sender` WebContents - Returns the `webContents` that sent the message
* `reply` Function - A function that will send an IPC message to the renderer frame that sent the original message that you are currently handling. You should use this method to "reply" to the sent message in order to guarantee the reply will go to the correct process and frame.
* `channel` String
* `...args` any[]

View File

@@ -143,6 +143,26 @@ Emitted when a drag operation exits the tray icon.
Emitted when a drag operation ends on the tray or ends at another location.
#### Event: 'mouse-up' _macOS_
Returns:
* `event` [KeyboardEvent](structures/keyboard-event.md)
* `position` [Point](structures/point.md) - The position of the event.
Emitted when the mouse is released from clicking the tray icon.
Note: This will not be emitted if you have set a context menu for your Tray using `tray.setContextMenu`, as a result of macOS-level constraints.
#### Event: 'mouse-down' _macOS_
Returns:
* `event` [KeyboardEvent](structures/keyboard-event.md)
* `position` [Point](structures/point.md) - The position of the event.
Emitted when the mouse clicks the tray icon.
#### Event: 'mouse-enter' _macOS_
Returns:
@@ -257,6 +277,10 @@ be shown instead of the tray icon's context menu.
The `position` is only available on Windows, and it is (0, 0) by default.
#### `tray.closeContextMenu()` _macOS_ _Windows_
Closes an open context menu, as set by `tray.setContextMenu()`.
#### `tray.setContextMenu(menu)`
* `menu` Menu | null

View File

@@ -987,7 +987,7 @@ Injects CSS into the current web page and returns a unique key for the inserted
stylesheet.
```js
contents.on('did-finish-load', function () {
contents.on('did-finish-load', () => {
contents.insertCSS('html, body { background-color: #f00; }')
})
```
@@ -1002,7 +1002,7 @@ Removes the inserted CSS from the current web page. The stylesheet is identified
by its key, which is returned from `contents.insertCSS(css)`.
```js
contents.on('did-finish-load', async function () {
contents.on('did-finish-load', async () => {
const key = await contents.insertCSS('html, body { background-color: #f00; }')
contents.removeInsertedCSS(key)
})
@@ -1031,6 +1031,17 @@ contents.executeJavaScript('fetch("https://jsonplaceholder.typicode.com/users/1"
})
```
#### `contents.executeJavaScriptInIsolatedWorld(worldId, scripts[, userGesture])`
* `worldId` Integer - The ID of the world to run the javascript in, `0` is the default world, `999` is the world used by Electron's `contextIsolation` feature. You can provide any integer here.
* `scripts` [WebSource[]](structures/web-source.md)
* `userGesture` Boolean (optional) - Default is `false`.
Returns `Promise<any>` - A promise that resolves with the result of the executed code
or is rejected if the result of the code is a rejected promise.
Works like `executeJavaScript` but evaluates `scripts` in an isolated context.
#### `contents.setIgnoreMenuShortcuts(ignore)` _Experimental_
* `ignore` Boolean
@@ -1102,15 +1113,6 @@ Sets the maximum and minimum pinch-to-zoom level.
> contents.setVisualZoomLevelLimits(1, 3)
> ```
#### `contents.setLayoutZoomLevelLimits(minimumLevel, maximumLevel)`
* `minimumLevel` Number
* `maximumLevel` Number
Returns `Promise<void>`
Sets the maximum and minimum layout-based (i.e. non-visual) zoom level.
#### `contents.undo()`
Executes the editing command `undo` in web page.
@@ -1227,7 +1229,7 @@ Captures a snapshot of the page within `rect`. Omitting `rect` will capture the
Get the system printer list.
Returns [`PrinterInfo[]`](structures/printer-info.md).
Returns [`PrinterInfo[]`](structures/printer-info.md)
#### `contents.print([options], [callback])`
@@ -1316,12 +1318,13 @@ win.loadURL('http://github.com')
win.webContents.on('did-finish-load', () => {
// Use default printing options
win.webContents.printToPDF({}, (error, data) => {
if (error) throw error
win.webContents.printToPDF({}).then(data => {
fs.writeFile('/tmp/print.pdf', data, (error) => {
if (error) throw error
console.log('Write PDF successfully.')
})
}).catch(error => {
console.log(error)
})
})
```
@@ -1771,7 +1774,7 @@ Only applicable if *offscreen rendering* is enabled.
#### `contents.id` _Readonly_
A `Integer` representing the unique ID of this WebContents.
A `Integer` representing the unique ID of this WebContents. Each ID is unique among all `WebContents` instances of the entire Electron application.
#### `contents.session` _Readonly_

View File

@@ -56,13 +56,6 @@ Sets the maximum and minimum pinch-to-zoom level.
> webFrame.setVisualZoomLevelLimits(1, 3)
> ```
### `webFrame.setLayoutZoomLevelLimits(minimumLevel, maximumLevel)`
* `minimumLevel` Number
* `maximumLevel` Number
Sets the maximum and minimum layout-based (i.e. non-visual) zoom level.
### `webFrame.setSpellCheckProvider(language, provider)`
* `language` String

View File

@@ -146,7 +146,7 @@ response are visible by the time this listener is fired.
* `timestamp` Double
* `statusLine` String
* `statusCode` Integer
* `responseHeaders` Record<string, string> (optional)
* `responseHeaders` Record<string, string[]> (optional)
* `callback` Function
* `headersReceivedResponse` Object
* `cancel` Boolean (optional)
@@ -175,7 +175,7 @@ The `callback` has to be called with a `response` object.
* `resourceType` String
* `referrer` String
* `timestamp` Double
* `responseHeaders` Record<string, string> (optional)
* `responseHeaders` Record<string, string[]> (optional)
* `fromCache` Boolean - Indicates whether the response was fetched from disk
cache.
* `statusCode` Integer
@@ -205,7 +205,7 @@ and response headers are available.
* `ip` String (optional) - The server IP address that the request was
actually sent to.
* `fromCache` Boolean
* `responseHeaders` Record<string, string> (optional)
* `responseHeaders` Record<string, string[]> (optional)
The `listener` will be called with `listener(details)` when a server initiated
redirect is about to occur.
@@ -224,7 +224,7 @@ redirect is about to occur.
* `resourceType` String
* `referrer` String
* `timestamp` Double
* `responseHeaders` Record<string, string> (optional)
* `responseHeaders` Record<string, string[]> (optional)
* `fromCache` Boolean
* `statusCode` Integer
* `statusLine` String

View File

@@ -635,15 +635,6 @@ Returns `Promise<void>`
Sets the maximum and minimum pinch-to-zoom level.
### `<webview>.setLayoutZoomLevelLimits(minimumLevel, maximumLevel)`
* `minimumLevel` Number
* `maximumLevel` Number
Returns `Promise<void>`
Sets the maximum and minimum layout-based (i.e. non-visual) zoom level.
### `<webview>.showDefinitionForSelection()` _macOS_
Shows pop-up dictionary that searches the selected word on the page.

View File

@@ -265,8 +265,7 @@ New-ItemProperty -Path "HKLM:\System\CurrentControlSet\Services\Lanmanworkstatio
### Stale locks in the git cache
If `gclient sync` is interrupted while using the git cache, it will leave
the cache locked. To remove the lock, pass the `--break_repo_locks` argument to
`gclient sync`.
the cache locked. To remove the lock, pass the `--ignore_locks` argument to `gclient sync`.
### I'm being asked for a username/password for chromium-internal.googlesource.com
If you see a prompt for `Username for 'https://chrome-internal.googlesource.com':` when running `gclient sync` on Windows, it's probably because the `DEPOT_TOOLS_WIN_TOOLCHAIN` environment variable is not set to 0. Open `Control Panel``System and Security``System``Advanced system settings` and add a system variable

View File

@@ -11,9 +11,8 @@ Follow the guidelines below for building Electron on Windows.
components are required.
* If your Visual Studio is installed in a directory other than the default, you'll need to
set a few environment variables to point the toolchains to your installation path.
* `vs2019_install = DRIVE:\path\to\Microsoft Visual Studio\2019\Community`
(replace `2019` and `Community` with your installed versions)
* `WINDOWSSDKDIR = DRIVE:\path\to\Windows Kits\10`
* `vs2019_install = DRIVE:\path\to\Microsoft Visual Studio\2019\Community`, replacing `2019` and `Community` with your installed versions and replacing `DRIVE:` with the drive that Visual Studio is on. Often, this will be `C:`.
* `WINDOWSSDKDIR = DRIVE:\path\to\Windows Kits\10`, replacing `DRIVE:` with the drive that Windows Kits is on. Often, this will be `C:`.
* [Python 2.7.10 or higher](http://www.python.org/download/releases/2.7/)
* Contrary to the `depot_tools` setup instructions linked below, you will need
to use your locally installed Python with at least version 2.7.10 (with

View File

@@ -57,7 +57,7 @@ you're currently working on using Mocha's
`.only` to any `describe` or `it` function call:
```js
describe.only('some feature', function () {
describe.only('some feature', () => {
// ... only tests in this block will be run
})
```

63
docs/development/goma.md Normal file
View File

@@ -0,0 +1,63 @@
# Goma
> Goma is a distributed compiler service for open-source projects such as
> Chromium and Android.
Electron has a deployment of a custom Goma Backend that we make available to
all Electron Maintainers. See the [Access](#access) section below for details
on authentication.
## Enabling Goma
Currently Electron Goma supports Windows, Linux, and macOS. If you are
on a supported platform you can enable goma by importing the `goma.gn` config
file when using `gn`.
```bash
gn gen out/Testing --args="import(\"//electron/build/args/testing.gn\") import(\"//electron/build/args/goma.gn\")"
```
You must ensure that you do not have `cc_wrapper` configured, this means you
can't use `sccache` or similar technology.
Before you can use goma to build Electron you need to authenticate against
the Goma service. You only need to do this once per-machine.
```bash
cd electron/external_binaries/goma
./goma_auth.py login
```
Once authenticated you need to make sure the goma daemon is running on your
machine.
```bash
cd electron/external_binaries/goma
./goma_ctl.py ensure_start
```
## Building with Goma
When you are using Goma you can run `ninja` with a substantially higher `j`
value than would normally be supported by your machine.
Please do not set a value higher than **300** on Windows or Linux and
**80** on macOS, we monitor the goma system and users found to be abusing
it with unreasonable concurrency will be de-activated.
```bash
ninja -C out/Testing electron -j 200
```
## Monitoring Goma
If you access [http://localhost:8088](http://localhost:8088) on your local
machine you can monitor compile jobs as they flow through the goma system.
## Access
For security and cost reasons access to Electron Goma is currently restricted
to Electron Maintainers. If you want access please head to `#access-requests` in
Slack and ping `@goma-squad` to ask for access. Please be aware that being a
maintainer does not *automatically* grant access and access is determined on a
case by case basis.

View File

@@ -11,7 +11,48 @@ to understand the source code better.
```diff
Electron
├── atom/ - C++ source code.
├── build/ - Build configuration files needed to build with GN.
├── buildflags/ - Determines the set of features that can be conditionally built.
├── chromium_src/ - Source code copied from Chromium that isn't part of the content layer.
├── default_app/ - A default app run when Electron is started without
| providing a consumer app.
├── docs/ - Electron's documentation.
| ├── api/ - Documentation for Electron's externally-facing modules and APIs.
| ├── development/ - Documentation to aid in developing for and with Electron.
| ├── fiddles/ - A set of code snippets one can run in Electron Fiddle.
| ├── images/ - Images used in documentation.
| └── tutorial/ - Tutorial documents for various aspects of Electron.
├── lib/ - JavaScript/TypeScript source code.
| ├── browser/ - Main process initialization code.
| | ├── api/ - API implementation for main process modules.
| | └── remote/ - Code related to the remote module as it is
| | used in the main process.
| ├── common/ - Relating to logic needed by both main and renderer processes.
| | └── api/ - API implementation for modules that can be used in
| | both the main and renderer processes
| ├── isolated_renderer/ - Handles creation of isolated renderer processes when
| | contextIsolation is enabled.
| ├── renderer/ - Renderer process initialization code.
| | ├── api/ - API implementation for renderer process modules.
| | ├── extension/ - Code related to use of Chrome Extensions
| | | in Electron's renderer process.
| | ├── remote/ - Logic that handes use of the remote module in
| | | the main process.
| | └── web-view/ - Logic that handles the use of webviews in the
| | renderer process.
| ├── sandboxed_renderer/ - Logic that handles creation of sandboxed renderer
| | | processes.
| | └── api/ - API implementation for sandboxed renderer processes.
| └── worker/ - Logic that handles proper functionality of Node.js
| environments in Web Workers.
├── patches/ - Patches applied on top of Electron's core dependencies
| | in order to handle differences between our use cases and
| | default functionality.
| ├── boringssl/ - Patches applied to Google's fork of OpenSSL, BoringSSL.
| ├── chromium/ - Patches applied to Chromium.
| ├── node/ - Patches applied on top of Node.js.
| └── v8/ - Patches applied on top of Google's V8 engine.
├── shell/ - C++ source code.
| ├── app/ - System entry code.
| ├── browser/ - The frontend including the main window, UI, and all of the
| | | main process things. This talks to the renderer to manage web
@@ -31,51 +72,36 @@ Electron
| | message loop into Chromium's message loop.
| └── api/ - The implementation of common APIs, and foundations of
| Electron's built-in modules.
├── chromium_src/ - Source code copied from Chromium. See below.
├── default_app/ - The default page to show when Electron is started without
| providing an app.
├── docs/ - Documentations.
├── lib/ - JavaScript source code.
| ├── browser/ - Javascript main process initialization code.
| | └── api/ - Javascript API implementation.
| ├── common/ - JavaScript used by both the main and renderer processes
| | └── api/ - Javascript API implementation.
| └── renderer/ - Javascript renderer process initialization code.
| └── api/ - Javascript API implementation.
├── native_mate/ - A fork of Chromium's gin library that makes it easier to marshal
| types between C++ and JavaScript.
├── spec/ - Automatic tests.
├── spec/ - Components of Electron's test suite run in the renderer process.
├── spec-main/ - Components of Electron's test suite run in the main process.
└── BUILD.gn - Building rules of Electron.
```
## `/chromium_src`
The files in `/chromium_src` tend to be pieces of Chromium that aren't part of
the content layer. For example to implement Pepper API, we need some wiring
similar to what official Chrome does. We could have built the relevant
sources as a part of [libcc](../glossary.md#libchromiumcontent) but most
often we don't require all the features (some tend to be proprietary,
analytics stuff) so we took parts of the code. These could have easily
been patches in libcc, but at the time when these were written the goal of
libcc was to maintain very minimal patches and chromium_src changes tend to be
big ones. Also, note that these patches can never be upstreamed unlike other
libcc patches we maintain now.
## Structure of Other Directories
* **script** - Scripts used for development purpose like building, packaging,
testing, etc.
* **tools** - Helper scripts used by GN files, unlike `script`, scripts put
here should never be invoked by users directly.
* **vendor** - Source code of third party dependencies, we didn't use
`third_party` as name because it would confuse it with the same directory in
Chromium's source code tree.
* **node_modules** - Third party node modules used for building.
* **out** - Temporary output directory of `ninja`.
* **.circleci** - Config file for CI with CircleCI.
* **.github** - GitHub-specific config files including issues templates and CODEOWNERS.
* **dist** - Temporary directory created by `script/create-dist.py` script
when creating a distribution.
* **external_binaries** - Downloaded binaries of third-party frameworks which
do not support building with `gn`.
* **node_modules** - Third party node modules used for building.
* **npm** - Logic for installation of Electron via npm.
* **out** - Temporary output directory of `ninja`.
* **script** - Scripts used for development purpose like building, packaging,
testing, etc.
```diff
script/ - The set of all scripts Electron runs for a variety of purposes.
├── codesign/ - Fakes codesigning for Electron apps; used for testing.
├── lib/ - Miscellaneous python utility scripts.
└── release/ - Scripts run during Electron's release process.
├── notes/ - Generates release notes for new Electron versions.
└── uploaders/ - Uploads various release-related files during release.
```
* **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`.
## Keeping Git Submodules Up to Date

View File

@@ -11,6 +11,7 @@ as well as unit and integration tests. To learn more about Electron's
coding style, please see the [coding-style](coding-style.md) document.
## Linting
To ensure that your JavaScript is in compliance with the Electron coding
style, run `npm run lint-js`, which will run `standard` against both
Electron itself as well as the unit tests. If you are using an editor
@@ -44,11 +45,29 @@ would run `npm run test -- -g ipc`.
[standard-addons]: https://standardjs.com/#are-there-text-editor-plugins
### Testing on Windows 10 devices
#### Extra steps to run the unit test:
1. Visual Studio 2019 must be installed.
2. Node headers have to be compiled for your configuration.
```powershell
ninja -C out\Testing third_party\electron_node:headers
```
3. The electron.lib has to be copied as node.lib.
```powershell
cd out\Testing
mkdir gen\node_headers\Release
copy electron.lib gen\node_headers\Release\node.lib
```
#### Missing fonts
[Some Windows 10 devices](https://docs.microsoft.com/en-us/typography/fonts/windows_10_font_list) do not ship with the Meiryo font installed, which may cause a font fallback test to fail. To install Meiryo:
1. Push the Windows key and search for _Manage optional features_.
1. Click _Add a feature_.
1. Select _Japanese Supplemental Fonts_ and click _Install_.
2. Click _Add a feature_.
3. Select _Japanese Supplemental Fonts_ and click _Install_.
#### Pixel measurements
Some tests which rely on precise pixel measurements may not work correctly on
devices with Hi-DPI screen settings due to floating point precision errors.
@@ -56,4 +75,4 @@ To run these tests correctly, make sure the device is set to 100% scaling.
To configure display scaling:
1. Push the Windows key and search for _Display settings_.
1. Under _Scale and layout_, make sure that the device is set to 100%.
2. Under _Scale and layout_, make sure that the device is set to 100%.

View File

@@ -0,0 +1,104 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Open external links and the file manager</title>
</head>
<body>
<div>
<h1>
Open external links and the file manager
</h1>
<h3>
The <code>shell</code> module in Electron allows you to access certain
native elements like the file manager and default web browser.
</h3>
<p>This module works in both the main and renderer process.</p>
<p>
Open the
<a href="http://electron.atom.io/docs/api/shell">
full API documentation (opens in new window)
</a>
in your browser.
</p>
</div>
<div>
<div>
<h2>Open Path in File Manager</h2>
<div>
<div>
<button id="open-file-manager">
View Demo
</button>
</div>
<p>
This demonstrates using the <code>shell</code> module to open the
system file manager at a particular location.
</p>
<p>
Clicking the demo button will open your file manager at the root.
</p>
</div>
</div>
</div>
<div>
<div>
<h2>Open External Links</h2>
<div>
<div>
<button id="open-ex-links">View Demo</button>
</div>
<p>
If you do not want your app to open website links
<em>within</em> the app, you can use the <code>shell</code> module
to open them externally. When clicked, the links will open outside
of your app and in the user's default web browser.
</p>
<p>
When the demo button is clicked, the electron website will open in
your browser.
</p>
<p></p>
<div>
<h2>ProTip</h2>
<strong>Open all outbound links externally.</strong>
<p>
You may want to open all <code>http</code> and
<code>https</code> links outside of your app. To do this, query
the document and loop through each link and add a listener. This
app uses the code below which is located in
<code>assets/ex-links.js</code>.
</p>
<h5>Renderer Process</h5>
<pre>
<code>
const shell = require('electron').shell
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)
})
}
})
</code>
</pre>
</div>
</div>
</div>
</div>
<script>
// You can also require other files to run in this process
require("./renderer.js");
</script>
</body>
</html>

View File

@@ -0,0 +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.on('ready', createWindow)
// Quit when all windows are closed.
app.on('window-all-closed', function () {
// On OS X 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 OS X it's 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

@@ -0,0 +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('http://electron.atom.io')
})

View File

@@ -0,0 +1,126 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Tray</title>
</head>
<body>
<div>
<h1>Tray</h1>
<h3>
The <code>tray</code> module allows you to create an icon in the
operating system's notification area.
</h3>
<p>This icon can also have a context menu attached.</p>
<p>
Open the
<a href="http://electron.atom.io/docs/api/tray">
full API documentation (opens in new window)
</a>
in your browser.
</p>
</div>
<div>
<div>
<div>
<div>
<button id="put-in-tray">View Demo</button>
<span id="tray-countdown"></span>
</div>
<p>
The demo button sends a message to the main process using the
<code>ipc</code> module. In the main process the app is told to
place an icon, with a context menu, in the tray.
</p>
<p>
In this example the tray icon can be removed by clicking 'Remove' in
the context menu or selecting the demo button again.
</p>
<h5>Main Process</h5>
<pre>
<code>
const path = require('path')
const {ipcMain, app, Menu, Tray} = require('electron')
let appIcon = null
ipcMain.on('put-in-tray', (event) => {
const iconName = process.platform === 'win32' ? 'windows-icon.png' : 'iconTemplate.png'
const iconPath = path.join(__dirname, iconName)
appIcon = new Tray(iconPath)
const contextMenu = Menu.buildFromTemplate([{
label: 'Remove',
click: () => {
event.sender.send('tray-removed')
}
}])
appIcon.setToolTip('Electron Demo in the tray.')
appIcon.setContextMenu(contextMenu)
})
ipcMain.on('remove-tray', () => {
appIcon.destroy()
})
app.on('window-all-closed', () => {
if (appIcon) appIcon.destroy()
})
</code>
</pre>
<h5>Renderer Process</h5>
<pre>
<code>
const ipc = require('electron').ipcRenderer
const trayBtn = document.getElementById('put-in-tray')
let trayOn = false
trayBtn.addEventListener('click', function (event) {
if (trayOn) {
trayOn = false
document.getElementById('tray-countdown').innerHTML = ''
ipc.send('remove-tray')
} else {
trayOn = true
const message = 'Click demo again to remove.'
document.getElementById('tray-countdown').innerHTML = message
ipc.send('put-in-tray')
}
})
// Tray removed from context menu on icon
ipc.on('tray-removed', function () {
ipc.send('remove-tray')
trayOn = false
document.getElementById('tray-countdown').innerHTML = ''
})
</code>
</pre>
<div>
<h2>ProTip</h2>
<strong>Tray support in Linux.</strong>
<p>
On Linux distributions that only have app indicator support, users
will need to install <code>libappindicator1</code> to make the
tray icon work. See the
<a href="http://electron.atom.io/docs/api/tray">
full API documentation (opens in new window)
</a>
for more details about using Tray on Linux.
</p>
</div>
</div>
</div>
</div>
<script>
// You can also require other files to run in this process
require("./renderer.js");
</script>
</body>
</html>

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +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)
})
}
})

View File

@@ -0,0 +1,76 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Frameless window</title>
</head>
<body>
<div>
<h1>Create and Manage Windows</h1>
<h3>
The <code>BrowserWindow</code> module in Electron allows you to create a
new browser window or manage an existing one.
</h3>
<p>
Each browser window is a separate process, known as the renderer
process. This process, like the main process that controls the life
cycle of the app, has full access to the Node.js APIs.
</p>
<p>
Open the
<a href="http://electron.atom.io/docs/api/browser-window">
full API documentation (opens in new window)
</a>
in your browser.
</p>
</div>
<div>
<div>
<h2>Create a frameless window</h2>
<div>
<div>
<button id="frameless-window">View Demo</button>
</div>
<p>
A frameless window is a window that has no
<a href="https://developer.mozilla.org/en-US/docs/Glossary/Chrome">
"chrome"
</a>
, such as toolbars, title bars, status bars, borders, etc. You can
make a browser window frameless by setting <code>frame</code> to
<code>false</code> when creating the window.
</p>
<p>
Windows can have a transparent background, too. By setting the
<code>transparent</code> option to <code>true</code>, you can also
make your frameless window transparent:
</p>
<pre>
<code class="language-js">var win = new BrowserWindow({
transparent: true,
frame: false
})</code></pre>
<p>
For more details, see the
<a href="http://electron.atom.io/docs/api/frameless-window/">
Frameless Window
</a>
documentation.
</p>
</div>
</div>
</div>
<script>
// You can also require other files to run in this process
require("./renderer.js");
</script>
</body>
</html>

View File

@@ -0,0 +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.on('ready', createWindow)
// Quit when all windows are closed.
app.on('window-all-closed', function () {
// On OS X 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 OS X it's 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

@@ -0,0 +1,25 @@
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)
})
}
})

View File

@@ -0,0 +1,64 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Manage window state</title>
</head>
<body>
<div>
<h1>Create and Manage Windows</h1>
<h3>
The <code>BrowserWindow</code> module in Electron allows you to create a
new browser window or manage an existing one.
</h3>
<p>
Each browser window is a separate process, known as the renderer
process. This process, like the main process that controls the life
cycle of the app, has full access to the Node.js APIs.
</p>
<p>
Open the
<a href="http://electron.atom.io/docs/api/browser-window">
full API documentation (opens in new window)
</a>
in your browser.
</p>
</div>
<div>
<div>
<h2>Manage window state</h2>
<div>
<div>
<button id="manage-window">View Demo</button>
<span id="manage-window-reply"></span>
</div>
<p>
In this demo we create a new window and listen for
<code>move</code> and <code>resize</code> events on it. Click the
demo button, change the new window and see the dimensions and
position update here, above.
</p>
<p>
There are a lot of methods for controlling the state of the window
such as the size, location, and focus status as well as events to
listen to for window changes. Visit the
<a href="http://electron.atom.io/docs/api/browser-window">
documentation (opens in new window)
</a>
for the full list.
</p>
</div>
</div>
</div>
<script>
// You can also require other files to run in this process
require("./renderer.js");
</script>
</body>
</html>

View File

@@ -0,0 +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.on('ready', createWindow)
// Quit when all windows are closed.
app.on('window-all-closed', function () {
// On OS X 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 OS X it's 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

@@ -0,0 +1,35 @@
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)
})
}
})

View File

@@ -0,0 +1,25 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
</head>
<body>
<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>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>
<strong>Use an invisible browser window to run background tasks.</strong>
<p>You can set a new browser window to not be shown (be invisible) in order to use that additional renderer process as a kind of new thread in which to run JavaScript in the background of your app. You do this by setting the <code>show</code> property to <code>false</code> when defining the new window.</p>
<pre><code><span>var</span> win = <span>new</span> BrowserWindow({
<span>width</span>: <span>400</span>, <span>height</span>: <span>225</span>, <span>show</span>: <span>false</span>
})</code></pre>
</div>
<script>
// You can also require other files to run in this process
require('./renderer.js')
</script>
</body>
</html>

View File

@@ -0,0 +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.on('ready', createWindow)
// Quit when all windows are closed.
app.on('window-all-closed', function () {
// On OS X 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 OS X it's 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

@@ -0,0 +1,19 @@
const { BrowserWindow } = require('electron').remote
const { shell } = require('electron').remote
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()
})
link.addEventListener('click', (e) => {
e.preventDefault()
shell.openExternal("http://electron.atom.io/docs/api/browser-window")
})

View File

@@ -0,0 +1,58 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Window events</title>
</head>
<body>
<div>
<h1>Create and Manage Windows</h1>
<h3>
The <code>BrowserWindow</code> module in Electron allows you to create a
new browser window or manage an existing one.
</h3>
<p>
Each browser window is a separate process, known as the renderer
process. This process, like the main process that controls the life
cycle of the app, has full access to the Node.js APIs.
</p>
<p>
Open the
<a href="http://electron.atom.io/docs/api/browser-window">
full API documentation (opens in new window)
</a>
in your browser.
</p>
</div>
<div>
<div>
<h2>Window events</h2>
<div>
<div>
<button id="listen-to-window">View Demo</button>
<button id="focus-on-modal-window">
Focus on Demo
</button>
</div>
<p>
In this demo, we create a new window and listen for
<code>blur</code> event on it. Click the demo button to create a new
modal window, and switch focus back to the parent window by clicking
on it. You can click the <i>Focus on Demo</i> button to switch focus
to the modal window again.
</p>
</div>
</div>
</div>
<script>
// You can also require other files to run in this process
require("./renderer.js");
</script>
</body>
</html>

View File

@@ -0,0 +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.on('ready', createWindow)
// Quit when all windows are closed.
app.on('window-all-closed', function () {
// On OS X 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 OS X it's 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

@@ -0,0 +1,48 @@
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)
})
}
})

BIN
docs/images/gatekeeper.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 190 KiB

View File

@@ -5,13 +5,13 @@ To write automated tests for your Electron app, you will need a way to "drive" y
To create a custom driver, we'll use Node.js' [child_process](https://nodejs.org/api/child_process.html) API. The test suite will spawn the Electron process, then establish a simple messaging protocol:
```js
var childProcess = require('child_process')
var electronPath = require('electron')
const childProcess = require('child_process')
const electronPath = require('electron')
// spawn the process
var env = { /* ... */ }
var stdio = ['inherit', 'inherit', 'inherit', 'ipc']
var appProcess = childProcess.spawn(electronPath, ['./app'], { stdio, env })
let env = { /* ... */ }
let stdio = ['inherit', 'inherit', 'inherit', 'ipc']
let appProcess = childProcess.spawn(electronPath, ['./app'], { stdio, env })
// listen for IPC messages from the app
appProcess.on('message', (msg) => {
@@ -50,7 +50,7 @@ class TestDriver {
// handle rpc responses
this.process.on('message', (message) => {
// pop the handler
var rpcCall = this.rpcCalls[message.msgId]
let rpcCall = this.rpcCalls[message.msgId]
if (!rpcCall) return
this.rpcCalls[message.msgId] = null
// reject/resolve
@@ -70,7 +70,7 @@ class TestDriver {
// to use: driver.rpc('method', 1, 2, 3).then(...)
async rpc (cmd, ...args) {
// send rpc request
var msgId = this.rpcCalls.length
let msgId = this.rpcCalls.length
this.process.send({ msgId, cmd, args })
return new Promise((resolve, reject) => this.rpcCalls.push({ resolve, reject }))
}
@@ -89,13 +89,13 @@ if (process.env.APP_TEST_DRIVER) {
}
async function onMessage ({ msgId, cmd, args }) {
var method = METHODS[cmd]
let method = METHODS[cmd]
if (!method) method = () => new Error('Invalid method: ' + cmd)
try {
var resolve = await method(...args)
let resolve = await method(...args)
process.send({ msgId, resolve })
} catch (err) {
var reject = {
let reject = {
message: err.message,
stack: err.stack,
name: err.name
@@ -116,10 +116,10 @@ const METHODS = {
Then, in your test suite, you can use your test-driver as follows:
```js
var test = require('ava')
var electronPath = require('electron')
const test = require('ava')
const electronPath = require('electron')
var app = new TestDriver({
let app = new TestDriver({
path: electronPath,
args: ['./app'],
env: {

View File

@@ -3,7 +3,7 @@
Code signing is a security technology that you use to certify that an app was
created by you.
On macOS the system can detect any change to the app, whether the change is
On macOS the system can detect any change to the app, whether the change is
introduced accidentally or by malicious code.
On Windows the system assigns a trust level to your code signing certificate which
@@ -11,15 +11,18 @@ if you don't have, or if your trust level is low will cause security dialogs to
appear when users start using your application. Trust level builds over time
so it's better to start code signing as early as possible.
While it is possible to distribute unsigned apps, it is not recommended.
For example, here's what macOS users see when attempting to start an unsigned app:
While it is possible to distribute unsigned apps, it is not recommended. Both
Windows and macOS will, by default, prevent either the download or the
execution of unsigned applications. Starting with macOS Catalina (version 10.15),
users have to go through multiple manual steps to open unsigned applications.
![unsigned app warning on macOS](https://user-images.githubusercontent.com/2289/39488937-bdc854ba-4d38-11e8-88f8-7b3c125baefc.png)
![macOS Catalina Gatekeeper warning: The app cannot be opened because the developer cannot be verified](../images/gatekeeper.png)
> App can't be opened because it is from an unidentified developer
As you can see, users get two options: Move the app straight to the trash or
cancel running it. You don't want your users to see that dialog.
If you are building an Electron app that you intend to package and distribute,
it should be code signed. The Mac and Windows app stores do not allow unsigned
it should be code-signed. The Mac and Windows app stores do not allow unsigned
apps.
# Signing macOS builds
@@ -39,7 +42,20 @@ pass the `--osx-sign=true` flag to sign your build.
in your forge config.
- [`electron-builder`] has built-in code-signing capabilities. See [electron.build/code-signing](https://www.electron.build/code-signing)
For more info, see the [Mac App Store Submission Guide].
## Notarization
Starting with macOS Catalina, Apple requires applications to be notarized.
"Notarization" as defined by Apple means that you upload your previously signed
application to Apple for additional verification _before_ distributing the app
to your users.
To automate this process, you can use the [`electron-notarize`] module. You
do not necessarily need to complete this step for every build you make  just
the builds you intend to ship to users.
## Mac App Store
See the [Mac App Store Guide].
# Signing Windows builds
@@ -70,8 +86,9 @@ See the [Windows Store Guide].
[`electron-forge`]: https://github.com/electron-userland/electron-forge
[`electron-osx-sign`]: https://github.com/electron-userland/electron-osx-sign
[`electron-packager`]: https://github.com/electron/electron-packager
[`electron-notarize`]: https://github.com/electron/electron-notarize
[`electron-winstaller`]: https://github.com/electron/windows-installer
[Xcode]: https://developer.apple.com/xcode
[signing certificates]: https://github.com/electron-userland/electron-osx-sign/wiki/1.-Getting-Started#certificates
[Mac App Store Submission Guide]: mac-app-store-submission-guide.md
[signing certificates]: https://github.com/electron/electron-osx-sign/wiki/1.-Getting-Started#certificates
[Mac App Store Guide]: mac-app-store-submission-guide.md
[Windows Store Guide]: windows-store-guide.md

View File

@@ -34,7 +34,7 @@ Using the [React Developer Tools][react-devtools] as example:
const os = require('os')
BrowserWindow.addDevToolsExtension(
path.join(os.homedir(), '/Library/Application Support/Google/Chrome/Default/Extensions/fmkadmapgofadopljbjfkapdkoienihi/0.15.0_0')
path.join(os.homedir(), '/Library/Application Support/Google/Chrome/Default/Extensions/fmkadmapgofadopljbjfkapdkoienihi/4.3.0_0')
)
```

View File

@@ -37,7 +37,7 @@ inAppPurchase.on('transactions-updated', (event, transactions) => {
// Check each transaction.
transactions.forEach(function (transaction) {
var payment = transaction.payment
let payment = transaction.payment
switch (transaction.transactionState) {
case 'purchasing':

View File

@@ -56,7 +56,7 @@ can do so by either providing a mirror or an existing cache directory.
#### Mirror
You can use environment variables to override the base URL, the path at which to
look for Electron binaries, and the binary filename. The url used by `electron-download`
look for Electron binaries, and the binary filename. The url used by `@electron/get`
is composed as follows:
```plaintext
@@ -70,7 +70,7 @@ ELECTRON_MIRROR="https://cdn.npm.taobao.org/dist/electron/"
```
#### Cache
Alternatively, you can override the local cache. `electron-download` will cache
Alternatively, you can override the local cache. `@electron/get` will cache
downloaded binaries in a local directory to not stress your network. You can use
that cache folder to provide custom builds of Electron or to avoid making contact
with the network at all.
@@ -82,23 +82,33 @@ with the network at all.
On environments that have been using older versions of Electron, you might find the
cache also in `~/.electron`.
You can also override the local cache location by providing a `ELECTRON_CACHE`
You can also override the local cache location by providing a `electron_config_cache`
environment variable.
The cache contains the version's official zip file as well as a checksum, stored as
a text file. A typical cache might look like this:
```sh
├── electron-v1.7.9-darwin-x64.zip
── electron-v1.8.1-darwin-x64.zip
├── electron-v1.8.2-beta.1-darwin-x64.zip
├── electron-v1.8.2-beta.2-darwin-x64.zip
├── electron-v1.8.2-beta.3-darwin-x64.zip
├── SHASUMS256.txt-1.7.9
├── SHASUMS256.txt-1.8.1
── SHASUMS256.txt-1.8.2-beta.1
├── SHASUMS256.txt-1.8.2-beta.2
├── SHASUMS256.txt-1.8.2-beta.3
├── httpsgithub.comelectronelectronreleasesdownloadv1.7.9electron-v1.7.9-darwin-x64.zip
│ └── electron-v1.7.9-darwin-x64.zip
├── httpsgithub.comelectronelectronreleasesdownloadv1.7.9SHASUMS256.txt
│ └── SHASUMS256.txt
├── httpsgithub.comelectronelectronreleasesdownloadv1.8.1electron-v1.8.1-darwin-x64.zip
│ └── electron-v1.8.1-darwin-x64.zip
├── httpsgithub.comelectronelectronreleasesdownloadv1.8.1SHASUMS256.txt
│ └── SHASUMS256.txt
├── httpsgithub.comelectronelectronreleasesdownloadv1.8.2-beta.1electron-v1.8.2-beta.1-darwin-x64.zip
│ └── electron-v1.8.2-beta.1-darwin-x64.zip
├── httpsgithub.comelectronelectronreleasesdownloadv1.8.2-beta.1SHASUMS256.txt
│ └── SHASUMS256.txt
├── httpsgithub.comelectronelectronreleasesdownloadv1.8.2-beta.2electron-v1.8.2-beta.2-darwin-x64.zip
│ └── electron-v1.8.2-beta.2-darwin-x64.zip
├── httpsgithub.comelectronelectronreleasesdownloadv1.8.2-beta.2SHASUMS256.txt
│ └── SHASUMS256.txt
├── httpsgithub.comelectronelectronreleasesdownloadv1.8.2-beta.3electron-v1.8.2-beta.3-darwin-x64.zip
│ └── electron-v1.8.2-beta.3-darwin-x64.zip
└── httpsgithub.comelectronelectronreleasesdownloadv1.8.2-beta.3SHASUMS256.txt
└── SHASUMS256.txt
```
## Skip binary download

View File

@@ -21,12 +21,12 @@ If your app has its own dark mode you should toggle it on and off in sync with t
this by listening for the theme changed event on Electron's `systemPreferences` module. E.g.
```js
const { systemPreferences } = require('electron')
const { nativeTheme } = require('electron')
systemPreferences.subscribeNotification(
'AppleInterfaceThemeChangedNotification',
function theThemeHasChanged () {
updateMyAppTheme(systemPreferences.isDarkMode())
updateMyAppTheme(nativeTheme.shouldUseDarkColors)
}
)
```

View File

@@ -54,7 +54,7 @@ const { app, BrowserWindow, ipcMain } = require('electron')
let onlineStatusWindow
app.on('ready', () => {
onlineStatusWindow = new BrowserWindow({ width: 0, height: 0, show: false })
onlineStatusWindow = new BrowserWindow({ width: 0, height: 0, show: false, webPreferences: { nodeIntegration: true } })
onlineStatusWindow.loadURL(`file://${__dirname}/online-status.html`)
})

View File

@@ -241,7 +241,7 @@ prevent the use of Node primitives, `contextIsolation` must also be used.
### Why?
Context isolation allows each the scripts on running in the renderer to make
Context isolation allows each of the scripts running in the renderer to make
changes to its JavaScript environment without worrying about conflicting with
the scripts in the Electron API or the preload script.
@@ -422,8 +422,6 @@ on a page directly in the markup using a `<meta>` tag:
<meta http-equiv="Content-Security-Policy" content="default-src 'none'">
```
#### `webRequest.onHeadersReceived([filter, ]listener)`
## 7) Do Not Set `allowRunningInsecureContent` to `true`

View File

@@ -0,0 +1,22 @@
# Web embeds in Electron
If you want to embed (third party) web content in an Electron `BrowserWindow`, there are three options available to you: `<iframe>` tags, `<webview>` tags, and `BrowserViews`. Each one offers slightly different functionality and is useful in different situations. To help you choose between these, this guide will explain the differences and capabilities of each.
## Iframes
Iframes in Electron behave like iframes in regular browsers. An `<iframe>` element in your page can show external web pages, provided that their [Content Security Policy](https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP) allows it. To limit the amount of capabilities a site in an `<iframe>` tag, it's recommended to use the [`sandbox` attribute](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe#attr-sandbox) and only allow the capabilities you want to support.
## WebViews
[WebViews](../api/webview-tag.md) are based on Chromium's WebViews and are not explicitly supported by Electron. We do not guarantee that the WebView API will remain available in future versions of Electron. This is why, if you want to use `<webview>` tags, you will need to set `webviewTag` to `true` in the `webPreferences` of your `BrowserWindow`.
WebViews are a custom element (`<webview>`) that will only work inside Electron.
They are implemented as an "out-of-process iframe". This means that all communication with the `<webview>` is done asynchronously using IPC. The `<webview>` element has many custom methods and events, similar to `webContents`, that allow you much greater control over the contents.
Compared to an `<iframe>`, `<webview>` tends to be slightly slower but offers much greater control in loading and communicating with the third party content and handling various events.
## BrowserViews
[BrowserViews](../api/browser-view.md) are not part of the DOM - instead, they are created in and controlled by your main process. They are simply another layer of web content on top of your existing window. This means that they are completely separate from your own `BrowserWindow` content and that their position is not controlled by the DOM or CSS but by setting the bounds in the main process.
BrowserViews offer the greatest control over their contents, since they implement the `webContents` similarly to how a `BrowserWindow` implements it. However, they are not part of your DOM but are overlaid on top of them, which means you will have to manage their position manually.

View File

@@ -1,4 +1,5 @@
import("//build/config/locales.gni")
import("//electron/buildflags/buildflags.gni")
import("//printing/buildflags/buildflags.gni")
import("//tools/grit/repack.gni")
import("//ui/base/ui_features.gni")
@@ -56,6 +57,7 @@ template("electron_extra_paks") {
"$root_gen_dir/components/components_resources.pak",
"$root_gen_dir/content/browser/tracing/tracing_resources.pak",
"$root_gen_dir/content/content_resources.pak",
"$root_gen_dir/content/dev_ui_content_resources.pak",
"$root_gen_dir/mojo/public/js/mojo_bindings_resources.pak",
"$root_gen_dir/net/net_resources.pak",
"$root_gen_dir/third_party/blink/public/resources/blink_resources.pak",
@@ -64,7 +66,8 @@ template("electron_extra_paks") {
]
deps = [
"//components/resources",
"//content:resources",
"//content:content_resources",
"//content:dev_ui_content_resources",
"//content/browser/tracing:resources",
"//electron:resources",
"//mojo/public/js:resources",
@@ -87,6 +90,13 @@ template("electron_extra_paks") {
sources += [ "$root_gen_dir/chrome/print_preview_resources.pak" ]
deps += [ "//chrome/browser/resources:print_preview_resources" ]
}
if (enable_electron_extensions) {
sources += [
"$root_gen_dir/extensions/extensions_renderer_resources.pak",
"$root_gen_dir/extensions/extensions_resources.pak",
]
deps += [ "//extensions:extensions_resources" ]
}
}
}

View File

@@ -165,6 +165,7 @@ auto_filenames = {
"lib/renderer/web-view/web-view-element.ts",
"lib/renderer/web-view/web-view-impl.ts",
"lib/renderer/web-view/web-view-init.ts",
"lib/renderer/window-setup.ts",
"lib/sandboxed_renderer/api/exports/electron.ts",
"lib/sandboxed_renderer/api/module-list.ts",
"lib/sandboxed_renderer/init.js",
@@ -246,6 +247,7 @@ auto_filenames = {
"lib/browser/api/views/text-field.js",
"lib/browser/api/web-contents-view.js",
"lib/browser/api/web-contents.js",
"lib/browser/chrome-extension-shim.js",
"lib/browser/chrome-extension.js",
"lib/browser/crash-reporter-init.js",
"lib/browser/default-menu.ts",

View File

@@ -14,11 +14,11 @@ filenames = {
default_app_octicon_sources = [
"node_modules/@primer/octicons/build/build.css",
"node_modules/@primer/octicons/build/svg/gear.svg",
"node_modules/@primer/octicons/build/svg/gift.svg",
"node_modules/@primer/octicons/build/svg/gist.svg",
"node_modules/@primer/octicons/build/svg/mark-github.svg",
"node_modules/@primer/octicons/build/svg/gear.svg",
"node_modules/@primer/octicons/build/svg/star.svg",
"node_modules/@primer/octicons/build/svg/gift.svg",
]
lib_sources = [
@@ -98,8 +98,8 @@ filenames = {
"shell/browser/api/atom_api_top_level_window.h",
"shell/browser/api/atom_api_tray.cc",
"shell/browser/api/atom_api_tray.h",
"shell/browser/api/atom_api_url_request.cc",
"shell/browser/api/atom_api_url_request.h",
"shell/browser/api/atom_api_url_loader.cc",
"shell/browser/api/atom_api_url_loader.h",
"shell/browser/api/atom_api_view.cc",
"shell/browser/api/atom_api_view.h",
"shell/browser/api/atom_api_web_contents.cc",
@@ -124,9 +124,9 @@ filenames = {
"shell/browser/api/save_page_handler.cc",
"shell/browser/api/save_page_handler.h",
"shell/browser/atom_autofill_driver.cc",
"shell/browser/atom_autofill_driver.h",
"shell/browser/atom_autofill_driver_factory.cc",
"shell/browser/atom_autofill_driver_factory.h",
"shell/browser/atom_autofill_driver.h",
"shell/browser/atom_browser_client.cc",
"shell/browser/atom_browser_client.h",
"shell/browser/atom_browser_context.cc",
@@ -186,10 +186,10 @@ filenames = {
"shell/browser/linux/unity_service.h",
"shell/browser/login_handler.cc",
"shell/browser/login_handler.h",
"shell/browser/mac/atom_application_delegate.h",
"shell/browser/mac/atom_application_delegate.mm",
"shell/browser/mac/atom_application.h",
"shell/browser/mac/atom_application.mm",
"shell/browser/mac/atom_application_delegate.h",
"shell/browser/mac/atom_application_delegate.mm",
"shell/browser/mac/dict_util.h",
"shell/browser/mac/dict_util.mm",
"shell/browser/mac/in_app_purchase.h",
@@ -227,9 +227,9 @@ filenames = {
"shell/browser/net/cert_verifier_client.cc",
"shell/browser/net/cert_verifier_client.h",
"shell/browser/net/network_context_service.cc",
"shell/browser/net/network_context_service.h",
"shell/browser/net/network_context_service_factory.cc",
"shell/browser/net/network_context_service_factory.h",
"shell/browser/net/network_context_service.h",
"shell/browser/net/node_stream_loader.cc",
"shell/browser/net/node_stream_loader.h",
"shell/browser/net/proxying_url_loader_factory.cc",
@@ -255,16 +255,16 @@ filenames = {
"shell/browser/notifications/mac/notification_presenter_mac.h",
"shell/browser/notifications/mac/notification_presenter_mac.mm",
"shell/browser/notifications/notification.cc",
"shell/browser/notifications/notification_delegate.h",
"shell/browser/notifications/notification.h",
"shell/browser/notifications/notification_delegate.h",
"shell/browser/notifications/notification_presenter.cc",
"shell/browser/notifications/notification_presenter.h",
"shell/browser/notifications/platform_notification_service.cc",
"shell/browser/notifications/platform_notification_service.h",
"shell/browser/notifications/win/notification_presenter_win7.cc",
"shell/browser/notifications/win/notification_presenter_win7.h",
"shell/browser/notifications/win/notification_presenter_win.cc",
"shell/browser/notifications/win/notification_presenter_win.h",
"shell/browser/notifications/win/notification_presenter_win7.cc",
"shell/browser/notifications/win/notification_presenter_win7.h",
"shell/browser/notifications/win/win32_desktop_notifications/common.h",
"shell/browser/notifications/win/win32_desktop_notifications/desktop_notification_controller.cc",
"shell/browser/notifications/win/win32_desktop_notifications/desktop_notification_controller.h",
@@ -296,6 +296,10 @@ filenames = {
"shell/browser/ui/certificate_trust.h",
"shell/browser/ui/certificate_trust_mac.mm",
"shell/browser/ui/certificate_trust_win.cc",
"shell/browser/ui/cocoa/NSColor+Hex.h",
"shell/browser/ui/cocoa/NSColor+Hex.mm",
"shell/browser/ui/cocoa/NSString+ANSI.h",
"shell/browser/ui/cocoa/NSString+ANSI.mm",
"shell/browser/ui/cocoa/atom_bundle_mover.h",
"shell/browser/ui/cocoa/atom_bundle_mover.mm",
"shell/browser/ui/cocoa/atom_inspectable_web_contents_view.h",
@@ -304,10 +308,10 @@ filenames = {
"shell/browser/ui/cocoa/atom_menu_controller.mm",
"shell/browser/ui/cocoa/atom_native_widget_mac.h",
"shell/browser/ui/cocoa/atom_native_widget_mac.mm",
"shell/browser/ui/cocoa/atom_ns_window_delegate.h",
"shell/browser/ui/cocoa/atom_ns_window_delegate.mm",
"shell/browser/ui/cocoa/atom_ns_window.h",
"shell/browser/ui/cocoa/atom_ns_window.mm",
"shell/browser/ui/cocoa/atom_ns_window_delegate.h",
"shell/browser/ui/cocoa/atom_ns_window_delegate.mm",
"shell/browser/ui/cocoa/atom_preview_item.h",
"shell/browser/ui/cocoa/atom_preview_item.mm",
"shell/browser/ui/cocoa/atom_touch_bar.h",
@@ -316,10 +320,6 @@ filenames = {
"shell/browser/ui/cocoa/delayed_native_view_host.h",
"shell/browser/ui/cocoa/event_dispatching_window.h",
"shell/browser/ui/cocoa/event_dispatching_window.mm",
"shell/browser/ui/cocoa/NSColor+Hex.h",
"shell/browser/ui/cocoa/NSColor+Hex.mm",
"shell/browser/ui/cocoa/NSString+ANSI.h",
"shell/browser/ui/cocoa/NSString+ANSI.mm",
"shell/browser/ui/cocoa/root_view_mac.h",
"shell/browser/ui/cocoa/root_view_mac.mm",
"shell/browser/ui/cocoa/views_delegate_mac.h",
@@ -331,34 +331,35 @@ filenames = {
"shell/browser/ui/drag_util.h",
"shell/browser/ui/drag_util_mac.mm",
"shell/browser/ui/drag_util_views.cc",
"shell/browser/ui/file_dialog_gtk.cc",
"shell/browser/ui/file_dialog.h",
"shell/browser/ui/file_dialog_gtk.cc",
"shell/browser/ui/file_dialog_mac.mm",
"shell/browser/ui/file_dialog_win.cc",
"shell/browser/ui/inspectable_web_contents.cc",
"shell/browser/ui/inspectable_web_contents_delegate.h",
"shell/browser/ui/inspectable_web_contents.h",
"shell/browser/ui/inspectable_web_contents_delegate.h",
"shell/browser/ui/inspectable_web_contents_impl.cc",
"shell/browser/ui/inspectable_web_contents_impl.h",
"shell/browser/ui/inspectable_web_contents_view.h",
"shell/browser/ui/inspectable_web_contents_view_delegate.cc",
"shell/browser/ui/inspectable_web_contents_view_delegate.h",
"shell/browser/ui/inspectable_web_contents_view.h",
"shell/browser/ui/inspectable_web_contents_view_mac.h",
"shell/browser/ui/inspectable_web_contents_view_mac.mm",
"shell/browser/ui/message_box_gtk.cc",
"shell/browser/ui/message_box.h",
"shell/browser/ui/message_box_gtk.cc",
"shell/browser/ui/message_box_mac.mm",
"shell/browser/ui/message_box_win.cc",
"shell/browser/ui/tray_icon.cc",
"shell/browser/ui/tray_icon.h",
"shell/browser/ui/tray_icon_cocoa.h",
"shell/browser/ui/tray_icon_cocoa.mm",
"shell/browser/ui/tray_icon_gtk.cc",
"shell/browser/ui/tray_icon_gtk.h",
"shell/browser/ui/tray_icon.h",
"shell/browser/ui/tray_icon_observer.h",
"shell/browser/ui/tray_icon_win.cc",
"shell/browser/ui/views/atom_views_delegate.cc",
"shell/browser/ui/views/atom_views_delegate.h",
"shell/browser/ui/views/atom_views_delegate_win.cc",
"shell/browser/ui/views/autofill_popup_view.cc",
"shell/browser/ui/views/autofill_popup_view.h",
"shell/browser/ui/views/frameless_view.cc",
@@ -413,11 +414,11 @@ filenames = {
"shell/browser/web_view_guest_delegate.h",
"shell/browser/web_view_manager.cc",
"shell/browser/web_view_manager.h",
"shell/browser/win/scoped_hstring.cc",
"shell/browser/win/scoped_hstring.h",
"shell/browser/window_list.cc",
"shell/browser/window_list.h",
"shell/browser/window_list_observer.h",
"shell/browser/win/scoped_hstring.cc",
"shell/browser/win/scoped_hstring.h",
"shell/browser/zoom_level_delegate.cc",
"shell/browser/zoom_level_delegate.h",
"shell/common/api/atom_api_asar.cc",
@@ -432,10 +433,8 @@ filenames = {
"shell/common/api/atom_api_native_image_mac.mm",
"shell/common/api/atom_api_shell.cc",
"shell/common/api/atom_api_v8_util.cc",
"shell/common/api/constructor.h",
"shell/common/api/electron_bindings.cc",
"shell/common/api/electron_bindings.h",
"shell/common/api/constructor.h",
"shell/common/api/features.cc",
"shell/common/application_info.cc",
"shell/common/application_info.h",
@@ -475,6 +474,8 @@ filenames = {
"shell/common/gin_converters/callback_converter.h",
"shell/common/gin_converters/content_converter.cc",
"shell/common/gin_converters/content_converter.h",
"shell/common/gin_converters/extension_converter.cc",
"shell/common/gin_converters/extension_converter.h",
"shell/common/gin_converters/file_dialog_converter.cc",
"shell/common/gin_converters/file_dialog_converter.h",
"shell/common/gin_converters/file_path_converter.h",
@@ -495,15 +496,16 @@ filenames = {
"shell/common/gin_helper/arguments.h",
"shell/common/gin_helper/callback.cc",
"shell/common/gin_helper/callback.h",
"shell/common/gin_helper/constructor.h",
"shell/common/gin_helper/destroyable.cc",
"shell/common/gin_helper/destroyable.h",
"shell/common/gin_helper/dictionary.h",
"shell/common/gin_helper/error_thrower.cc",
"shell/common/gin_helper/error_thrower.h",
"shell/common/gin_helper/event_emitter_caller.cc",
"shell/common/gin_helper/event_emitter_caller.h",
"shell/common/gin_helper/event_emitter.cc",
"shell/common/gin_helper/event_emitter.h",
"shell/common/gin_helper/event_emitter_caller.cc",
"shell/common/gin_helper/event_emitter_caller.h",
"shell/common/gin_helper/function_template.cc",
"shell/common/gin_helper/function_template.h",
"shell/common/gin_helper/locker.cc",
@@ -512,15 +514,18 @@ filenames = {
"shell/common/gin_helper/object_template_builder.h",
"shell/common/gin_helper/persistent_dictionary.cc",
"shell/common/gin_helper/persistent_dictionary.h",
"shell/common/gin_helper/promise.h",
"shell/common/gin_helper/promise.cc",
"shell/common/gin_helper/promise.h",
"shell/common/gin_helper/trackable_object.cc",
"shell/common/gin_helper/trackable_object.h",
"shell/common/gin_helper/wrappable.cc",
"shell/common/gin_helper/wrappable.h",
"shell/common/gin_helper/wrappable_base.h",
"shell/common/heap_snapshot.cc",
"shell/common/heap_snapshot.h",
"shell/common/key_weak_map.h",
"shell/common/keyboard_util.cc",
"shell/common/keyboard_util.h",
"shell/common/key_weak_map.h",
"shell/common/mac/main_application_bundle.h",
"shell/common/mac/main_application_bundle.mm",
"shell/common/mouse_util.cc",
@@ -556,10 +561,10 @@ filenames = {
"shell/renderer/api/context_bridge/render_frame_context_bridge_store.h",
"shell/renderer/atom_autofill_agent.cc",
"shell/renderer/atom_autofill_agent.h",
"shell/renderer/atom_renderer_client.cc",
"shell/renderer/atom_renderer_client.h",
"shell/renderer/atom_render_frame_observer.cc",
"shell/renderer/atom_render_frame_observer.h",
"shell/renderer/atom_renderer_client.cc",
"shell/renderer/atom_renderer_client.h",
"shell/renderer/atom_sandboxed_renderer_client.cc",
"shell/renderer/atom_sandboxed_renderer_client.h",
"shell/renderer/content_settings_observer.cc",
@@ -586,6 +591,8 @@ filenames = {
lib_sources_extensions = [
"shell/browser/extensions/api/runtime/atom_runtime_api_delegate.cc",
"shell/browser/extensions/api/runtime/atom_runtime_api_delegate.h",
"shell/browser/extensions/api/tabs/tabs_api.cc",
"shell/browser/extensions/api/tabs/tabs_api.h",
"shell/browser/extensions/atom_extensions_browser_client.cc",
"shell/browser/extensions/atom_extensions_browser_client.h",
"shell/browser/extensions/atom_browser_context_keyed_service_factories.cc",
@@ -604,12 +611,22 @@ filenames = {
"shell/browser/extensions/atom_extension_web_contents_observer.h",
"shell/browser/extensions/atom_navigation_ui_data.cc",
"shell/browser/extensions/atom_navigation_ui_data.h",
"shell/browser/extensions/electron_process_manager_delegate.cc",
"shell/browser/extensions/electron_process_manager_delegate.h",
"shell/browser/extensions/electron_extensions_api_client.cc",
"shell/browser/extensions/electron_extensions_api_client.h",
"shell/browser/extensions/electron_extensions_browser_api_provider.cc",
"shell/browser/extensions/electron_extensions_browser_api_provider.h",
"shell/browser/extensions/electron_messaging_delegate.cc",
"shell/browser/extensions/electron_messaging_delegate.h",
"shell/common/extensions/atom_extensions_api_provider.cc",
"shell/common/extensions/atom_extensions_api_provider.h",
"shell/common/extensions/atom_extensions_client.cc",
"shell/common/extensions/atom_extensions_client.h",
"shell/renderer/extensions/atom_extensions_renderer_client.cc",
"shell/renderer/extensions/atom_extensions_renderer_client.h",
"shell/renderer/extensions/electron_extensions_dispatcher_delegate.cc",
"shell/renderer/extensions/electron_extensions_dispatcher_delegate.h",
]
app_sources = [

View File

@@ -7,13 +7,13 @@ hunspell_dictionaries = [
"//third_party/hunspell_dictionaries/da-DK-3-0.bdic",
"//third_party/hunspell_dictionaries/de-DE-3-0.bdic",
"//third_party/hunspell_dictionaries/el-GR-3-0.bdic",
"//third_party/hunspell_dictionaries/en-AU-8-0.bdic",
"//third_party/hunspell_dictionaries/en-CA-8-0.bdic",
"//third_party/hunspell_dictionaries/en-GB-8-0.bdic",
"//third_party/hunspell_dictionaries/en-US-8-0.bdic",
"//third_party/hunspell_dictionaries/en-AU-9-0.bdic",
"//third_party/hunspell_dictionaries/en-CA-9-0.bdic",
"//third_party/hunspell_dictionaries/en-GB-9-0.bdic",
"//third_party/hunspell_dictionaries/en-US-9-0.bdic",
"//third_party/hunspell_dictionaries/es-ES-3-0.bdic",
"//third_party/hunspell_dictionaries/et-EE-3-0.bdic",
"//third_party/hunspell_dictionaries/fa-IR-8-0.bdic",
"//third_party/hunspell_dictionaries/fa-IR-9-0.bdic",
"//third_party/hunspell_dictionaries/fo-FO-3-0.bdic",
"//third_party/hunspell_dictionaries/fr-FR-3-0.bdic",
"//third_party/hunspell_dictionaries/he-IL-3-0.bdic",

View File

@@ -116,7 +116,7 @@ BrowserWindow.getFocusedWindow = () => {
BrowserWindow.fromWebContents = (webContents) => {
for (const window of BrowserWindow.getAllWindows()) {
if (window.webContents.equal(webContents)) return window
if (window.webContents && window.webContents.equal(webContents)) return window
}
return null

View File

@@ -163,6 +163,7 @@ const messageBox = (sync, window, options) => {
defaultId = -1,
detail = '',
icon = null,
noLink = false,
message = '',
title = '',
type = 'none'
@@ -173,11 +174,15 @@ const messageBox = (sync, window, options) => {
if (!Array.isArray(buttons)) throw new TypeError('Buttons must be an array')
if (options.normalizeAccessKeys) buttons = buttons.map(normalizeAccessKey)
if (typeof title !== 'string') throw new TypeError('Title must be a string')
if (typeof noLink !== 'boolean') throw new TypeError('noLink must be a boolean')
if (typeof message !== 'string') throw new TypeError('Message must be a string')
if (typeof detail !== 'string') throw new TypeError('Detail must be a string')
if (typeof checkboxLabel !== 'string') throw new TypeError('checkboxLabel must be a string')
checkboxChecked = !!checkboxChecked
if (checkboxChecked && !checkboxLabel) {
throw new Error('checkboxChecked requires that checkboxLabel also be passed')
}
// Choose a default button to get selected when dialog is cancelled.
if (cancelId == null) {
@@ -192,15 +197,13 @@ const messageBox = (sync, window, options) => {
}
}
const flags = options.noLink ? messageBoxOptions.noLink : 0
const settings = {
window,
messageBoxType,
buttons,
defaultId,
cancelId,
flags,
noLink,
title,
message,
detail,

View File

@@ -2,17 +2,13 @@
const url = require('url')
const { EventEmitter } = require('events')
const { Readable } = require('stream')
const { Readable, Writable } = require('stream')
const { app } = require('electron')
const { Session } = process.electronBinding('session')
const { net, Net } = process.electronBinding('net')
const { URLRequest } = net
const { net, Net, _isValidHeaderName, _isValidHeaderValue } = process.electronBinding('net')
const { URLLoader } = net
// Net is an EventEmitter.
Object.setPrototypeOf(Net.prototype, EventEmitter.prototype)
EventEmitter.call(net)
Object.setPrototypeOf(URLRequest.prototype, EventEmitter.prototype)
Object.setPrototypeOf(URLLoader.prototype, EventEmitter.prototype)
const kSupportedProtocols = new Set(['http:', 'https:'])
@@ -40,43 +36,44 @@ const discardableDuplicateHeaders = new Set([
])
class IncomingMessage extends Readable {
constructor (urlRequest) {
constructor (responseHead) {
super()
this.urlRequest = urlRequest
this.shouldPush = false
this.data = []
this.urlRequest.on('data', (event, chunk) => {
this._storeInternalData(chunk)
this._pushInternalData()
})
this.urlRequest.on('end', () => {
this._storeInternalData(null)
this._pushInternalData()
})
this._shouldPush = false
this._data = []
this._responseHead = responseHead
}
get statusCode () {
return this.urlRequest.statusCode
return this._responseHead.statusCode
}
get statusMessage () {
return this.urlRequest.statusMessage
return this._responseHead.statusMessage
}
get headers () {
const filteredHeaders = {}
const rawHeaders = this.urlRequest.rawResponseHeaders
Object.keys(rawHeaders).forEach(header => {
if (header in filteredHeaders && discardableDuplicateHeaders.has(header)) {
const { rawHeaders } = this._responseHead
rawHeaders.forEach(header => {
if (Object.prototype.hasOwnProperty.call(filteredHeaders, header.key) &&
discardableDuplicateHeaders.has(header.key)) {
// do nothing with discardable duplicate headers
} else {
if (header === 'set-cookie') {
if (header.key === 'set-cookie') {
// keep set-cookie as an array per Node.js rules
// see https://nodejs.org/api/http.html#http_message_headers
filteredHeaders[header] = rawHeaders[header]
if (Object.prototype.hasOwnProperty.call(filteredHeaders, header.key)) {
filteredHeaders[header.key].push(header.value)
} else {
filteredHeaders[header.key] = [header.value]
}
} else {
// for non-cookie headers, the values are joined together with ', '
filteredHeaders[header] = rawHeaders[header].join(', ')
if (Object.prototype.hasOwnProperty.call(filteredHeaders, header.key)) {
filteredHeaders[header.key] += `, ${header.value}`
} else {
filteredHeaders[header.key] = header.value
}
}
}
})
@@ -88,11 +85,11 @@ class IncomingMessage extends Readable {
}
get httpVersionMajor () {
return this.urlRequest.httpVersionMajor
return this._responseHead.httpVersion.major
}
get httpVersionMinor () {
return this.urlRequest.httpVersionMinor
return this._responseHead.httpVersion.minor
}
get rawTrailers () {
@@ -104,170 +101,197 @@ class IncomingMessage extends Readable {
}
_storeInternalData (chunk) {
this.data.push(chunk)
this._data.push(chunk)
this._pushInternalData()
}
_pushInternalData () {
while (this.shouldPush && this.data.length > 0) {
const chunk = this.data.shift()
this.shouldPush = this.push(chunk)
while (this._shouldPush && this._data.length > 0) {
const chunk = this._data.shift()
this._shouldPush = this.push(chunk)
}
}
_read () {
this.shouldPush = true
this._shouldPush = true
this._pushInternalData()
}
}
URLRequest.prototype._emitRequestEvent = function (isAsync, ...rest) {
if (isAsync) {
process.nextTick(() => {
this.clientRequest.emit(...rest)
})
} else {
this.clientRequest.emit(...rest)
}
}
URLRequest.prototype._emitResponseEvent = function (isAsync, ...rest) {
if (isAsync) {
process.nextTick(() => {
this._response.emit(...rest)
})
} else {
this._response.emit(...rest)
}
}
class ClientRequest extends EventEmitter {
constructor (options, callback) {
/** Writable stream that buffers up everything written to it. */
class SlurpStream extends Writable {
constructor () {
super()
this._data = Buffer.alloc(0)
}
_write (chunk, encoding, callback) {
this._data = Buffer.concat([this._data, chunk])
callback()
}
data () { return this._data }
}
class ChunkedBodyStream extends Writable {
constructor (clientRequest) {
super()
this._clientRequest = clientRequest
}
_write (chunk, encoding, callback) {
if (this._downstream) {
this._downstream.write(chunk).then(callback, callback)
} else {
// the contract of _write is that we won't be called again until we call
// the callback, so we're good to just save a single chunk.
this._pendingChunk = chunk
this._pendingCallback = callback
// The first write to a chunked body stream begins the request.
this._clientRequest._startRequest()
}
}
_final (callback) {
this._downstream.done()
callback()
}
startReading (pipe) {
if (this._downstream) {
throw new Error('two startReading calls???')
}
this._downstream = pipe
if (this._pendingChunk) {
const doneWriting = (maybeError) => {
const cb = this._pendingCallback
delete this._pendingCallback
delete this._pendingChunk
cb(maybeError)
}
this._downstream.write(this._pendingChunk).then(doneWriting, doneWriting)
}
}
}
function parseOptions (options) {
if (typeof options === 'string') {
options = url.parse(options)
} else {
options = { ...options }
}
const method = (options.method || 'GET').toUpperCase()
let urlStr = options.url
if (!urlStr) {
const urlObj = {}
const protocol = options.protocol || 'http:'
if (!kSupportedProtocols.has(protocol)) {
throw new Error('Protocol "' + protocol + '" not supported')
}
urlObj.protocol = protocol
if (options.host) {
urlObj.host = options.host
} else {
if (options.hostname) {
urlObj.hostname = options.hostname
} else {
urlObj.hostname = 'localhost'
}
if (options.port) {
urlObj.port = options.port
}
}
if (options.path && / /.test(options.path)) {
// The actual regex is more like /[^A-Za-z0-9\-._~!$&'()*+,;=/:@]/
// with an additional rule for ignoring percentage-escaped characters
// but that's a) hard to capture in a regular expression that performs
// well, and b) possibly too restrictive for real-world usage. That's
// why it only scans for spaces because those are guaranteed to create
// an invalid request.
throw new TypeError('Request path contains unescaped characters')
}
const pathObj = url.parse(options.path || '/')
urlObj.pathname = pathObj.pathname
urlObj.search = pathObj.search
urlObj.hash = pathObj.hash
urlStr = url.format(urlObj)
}
const redirectPolicy = options.redirect || 'follow'
if (!['follow', 'error', 'manual'].includes(redirectPolicy)) {
throw new Error('redirect mode should be one of follow, error or manual')
}
if (options.headers != null && typeof options.headers !== 'object') {
throw new TypeError('headers must be an object')
}
const urlLoaderOptions = {
method: method,
url: urlStr,
redirectPolicy,
extraHeaders: options.headers || {}
}
for (const [name, value] of Object.entries(urlLoaderOptions.extraHeaders)) {
if (!_isValidHeaderName(name)) {
throw new Error(`Invalid header name: '${name}'`)
}
if (!_isValidHeaderValue(value.toString())) {
throw new Error(`Invalid value for header '${name}': '${value}'`)
}
}
if (options.session) {
if (options.session instanceof Session) {
urlLoaderOptions.session = options.session
} else {
throw new TypeError('`session` should be an instance of the Session class')
}
} else if (options.partition) {
if (typeof options.partition === 'string') {
urlLoaderOptions.partition = options.partition
} else {
throw new TypeError('`partition` should be a string')
}
}
return urlLoaderOptions
}
class ClientRequest extends Writable {
constructor (options, callback) {
super({ autoDestroy: true })
if (!app.isReady()) {
throw new Error('net module can only be used after app is ready')
}
if (typeof options === 'string') {
options = url.parse(options)
} else {
options = Object.assign({}, options)
}
const method = (options.method || 'GET').toUpperCase()
let urlStr = options.url
if (!urlStr) {
const urlObj = {}
const protocol = options.protocol || 'http:'
if (!kSupportedProtocols.has(protocol)) {
throw new Error('Protocol "' + protocol + '" not supported')
}
urlObj.protocol = protocol
if (options.host) {
urlObj.host = options.host
} else {
if (options.hostname) {
urlObj.hostname = options.hostname
} else {
urlObj.hostname = 'localhost'
}
if (options.port) {
urlObj.port = options.port
}
}
if (options.path && / /.test(options.path)) {
// The actual regex is more like /[^A-Za-z0-9\-._~!$&'()*+,;=/:@]/
// with an additional rule for ignoring percentage-escaped characters
// but that's a) hard to capture in a regular expression that performs
// well, and b) possibly too restrictive for real-world usage. That's
// why it only scans for spaces because those are guaranteed to create
// an invalid request.
throw new TypeError('Request path contains unescaped characters')
}
const pathObj = url.parse(options.path || '/')
urlObj.pathname = pathObj.pathname
urlObj.search = pathObj.search
urlObj.hash = pathObj.hash
urlStr = url.format(urlObj)
}
const redirectPolicy = options.redirect || 'follow'
if (!['follow', 'error', 'manual'].includes(redirectPolicy)) {
throw new Error('redirect mode should be one of follow, error or manual')
}
const urlRequestOptions = {
method: method,
url: urlStr,
redirect: redirectPolicy
}
if (options.session) {
if (options.session instanceof Session) {
urlRequestOptions.session = options.session
} else {
throw new TypeError('`session` should be an instance of the Session class')
}
} else if (options.partition) {
if (typeof options.partition === 'string') {
urlRequestOptions.partition = options.partition
} else {
throw new TypeError('`partition` should be a string')
}
}
const urlRequest = new URLRequest(urlRequestOptions)
// Set back and forward links.
this.urlRequest = urlRequest
urlRequest.clientRequest = this
// This is a copy of the extra headers structure held by the native
// net::URLRequest. The main reason is to keep the getHeader API synchronous
// after the request starts.
this.extraHeaders = {}
if (options.headers) {
for (const key in options.headers) {
this.setHeader(key, options.headers[key])
}
}
// Set when the request uses chunked encoding. Can be switched
// to true only once and never set back to false.
this.chunkedEncodingEnabled = false
urlRequest.on('response', () => {
const response = new IncomingMessage(urlRequest)
urlRequest._response = response
this.emit('response', response)
})
urlRequest.on('login', (event, authInfo, callback) => {
const handled = this.emit('login', authInfo, callback)
if (!handled) {
// If there were no listeners, cancel the authentication request.
callback()
}
})
if (callback) {
this.once('response', callback)
}
}
get chunkedEncoding () {
return this.chunkedEncodingEnabled
const { redirectPolicy, ...urlLoaderOptions } = parseOptions(options)
this._urlLoaderOptions = urlLoaderOptions
this._redirectPolicy = redirectPolicy
this._started = false
}
set chunkedEncoding (value) {
if (!this.urlRequest.notStarted) {
throw new Error('Can\'t set the transfer encoding, headers have been sent')
if (this._started) {
throw new Error('chunkedEncoding can only be set before the request is started')
}
if (typeof this._chunkedEncoding !== 'undefined') {
throw new Error('chunkedEncoding can only be set once')
}
this._chunkedEncoding = !!value
if (this._chunkedEncoding) {
this._body = new ChunkedBodyStream(this)
this._urlLoaderOptions.body = (pipe) => {
this._body.startReading(pipe)
}
}
this.chunkedEncodingEnabled = value
}
setHeader (name, value) {
@@ -277,13 +301,18 @@ class ClientRequest extends EventEmitter {
if (value == null) {
throw new Error('`value` required in setHeader("' + name + '", value)')
}
if (!this.urlRequest.notStarted) {
if (this._started || this._firstWrite) {
throw new Error('Can\'t set headers after they are sent')
}
if (!_isValidHeaderName(name)) {
throw new Error(`Invalid header name: '${name}'`)
}
if (!_isValidHeaderValue(value.toString())) {
throw new Error(`Invalid value for header '${name}': '${value}'`)
}
const key = name.toLowerCase()
this.extraHeaders[key] = value
this.urlRequest.setExtraHeader(name, value.toString())
this._urlLoaderOptions.extraHeaders[key] = value
}
getHeader (name) {
@@ -291,12 +320,8 @@ class ClientRequest extends EventEmitter {
throw new Error('`name` is required for getHeader(name)')
}
if (!this.extraHeaders) {
return
}
const key = name.toLowerCase()
return this.extraHeaders[key]
return this._urlLoaderOptions.extraHeaders[key]
}
removeHeader (name) {
@@ -304,93 +329,144 @@ class ClientRequest extends EventEmitter {
throw new Error('`name` is required for removeHeader(name)')
}
if (!this.urlRequest.notStarted) {
if (this._started || this._firstWrite) {
throw new Error('Can\'t remove headers after they are sent')
}
const key = name.toLowerCase()
delete this.extraHeaders[key]
this.urlRequest.removeExtraHeader(name)
delete this._urlLoaderOptions.extraHeaders[key]
}
_write (chunk, encoding, callback, isLast) {
const chunkIsString = typeof chunk === 'string'
const chunkIsBuffer = chunk instanceof Buffer
if (!chunkIsString && !chunkIsBuffer) {
throw new TypeError('First argument must be a string or Buffer')
_write (chunk, encoding, callback) {
this._firstWrite = true
if (!this._body) {
this._body = new SlurpStream()
this._body.on('finish', () => {
this._urlLoaderOptions.body = this._body.data()
this._startRequest()
})
}
if (chunkIsString) {
// We convert all strings into binary buffers.
chunk = Buffer.from(chunk, encoding)
}
// Since writing to the network is asynchronous, we conservatively
// assume that request headers are written after delivering the first
// buffer to the network IO thread.
if (this.urlRequest.notStarted) {
this.urlRequest.setChunkedUpload(this.chunkedEncoding)
}
// Headers are assumed to be sent on first call to _writeBuffer,
// i.e. after the first call to write or end.
const result = this.urlRequest.write(chunk, isLast)
// The write callback is fired asynchronously to mimic Node.js.
if (callback) {
process.nextTick(callback)
}
return result
// TODO: is this the right way to forward to another stream?
this._body.write(chunk, encoding, callback)
}
write (data, encoding, callback) {
if (this.urlRequest.finished) {
const error = new Error('Write after end')
process.nextTick(writeAfterEndNT, this, error, callback)
return true
_final (callback) {
if (this._body) {
// TODO: is this the right way to forward to another stream?
this._body.end(callback)
} else {
// end() called without a body, go ahead and start the request
this._startRequest()
callback()
}
return this._write(data, encoding, callback, false)
}
end (data, encoding, callback) {
if (this.urlRequest.finished) {
return false
_startRequest () {
this._started = true
const stringifyValues = (obj) => {
const ret = {}
for (const k in obj) {
ret[k] = obj[k].toString()
}
return ret
}
const opts = { ...this._urlLoaderOptions, extraHeaders: stringifyValues(this._urlLoaderOptions.extraHeaders) }
this._urlLoader = new URLLoader(opts)
this._urlLoader.on('response-started', (event, finalUrl, responseHead) => {
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('complete', () => {
if (this._response) { this._response._storeInternalData(null) }
})
this._urlLoader.on('error', (event, netErrorString) => {
const error = new Error(netErrorString)
if (this._response) this._response.destroy(error)
this._die(error)
})
if (typeof data === 'function') {
callback = data
encoding = null
data = null
} else if (typeof encoding === 'function') {
callback = encoding
encoding = null
}
this._urlLoader.on('login', (event, authInfo, callback) => {
const handled = this.emit('login', authInfo, callback)
if (!handled) {
// If there were no listeners, cancel the authentication request.
callback()
}
})
data = data || ''
this._urlLoader.on('redirect', (event, redirectInfo, headers) => {
const { statusCode, newMethod, newUrl } = redirectInfo
if (this._redirectPolicy === 'error') {
this._die(new Error(`Attempted to redirect, but redirect policy was 'error'`))
} else if (this._redirectPolicy === 'manual') {
let _followRedirect = false
this._followRedirectCb = () => { _followRedirect = true }
try {
this.emit('redirect', statusCode, newMethod, newUrl, headers)
} finally {
this._followRedirectCb = null
if (!_followRedirect && !this._aborted) {
this._die(new Error('Redirect was cancelled'))
}
}
} else if (this._redirectPolicy === 'follow') {
// Calling followRedirect() when the redirect policy is 'follow' is
// allowed but does nothing. (Perhaps it should throw an error
// though...? Since the redirect will happen regardless.)
try {
this._followRedirectCb = () => {}
this.emit('redirect', statusCode, newMethod, newUrl, headers)
} finally {
this._followRedirectCb = null
}
} else {
this._die(new Error(`Unexpected redirect policy '${this._redirectPolicy}'`))
}
})
return this._write(data, encoding, callback, true)
this._urlLoader.on('upload-progress', (event, position, total) => {
this._uploadProgress = { active: true, started: true, current: position, total }
this.emit('upload-progress', position, total) // Undocumented, for now
})
this._urlLoader.on('download-progress', (event, current) => {
if (this._response) {
this._response.emit('download-progress', current) // Undocumented, for now
}
})
}
followRedirect () {
this.urlRequest.followRedirect()
if (this._followRedirectCb) {
this._followRedirectCb()
} else {
throw new Error('followRedirect() called, but was not waiting for a redirect')
}
}
abort () {
this.urlRequest.cancel()
if (!this._aborted) {
process.nextTick(() => { this.emit('abort') })
}
this._aborted = true
this._die()
}
_die (err) {
this.destroy(err)
if (this._urlLoader) {
this._urlLoader.cancel()
if (this._response) this._response.destroy(err)
}
}
getUploadProgress () {
return this.urlRequest.getUploadProgress()
return this._uploadProgress ? { ...this._uploadProgress } : { active: false }
}
}
function writeAfterEndNT (self, error, callback) {
self.emit('error', error)
if (callback) callback(error)
}
Net.prototype.request = function (options, callback) {
return new ClientRequest(options, callback)
}

View File

@@ -7,6 +7,7 @@ const path = require('path')
const url = require('url')
const { app, ipcMain, session, deprecate } = electron
const { internalWindowOpen } = require('@electron/internal/browser/guest-window-manager')
const NavigationController = require('@electron/internal/browser/navigation-controller')
const { ipcMainInternal } = require('@electron/internal/browser/ipc-main-internal')
const ipcMainUtils = require('@electron/internal/browser/ipc-main-internal-utils')
@@ -173,7 +174,6 @@ const webFrameMethods = [
'insertCSS',
'insertText',
'removeInsertedCSS',
'setLayoutZoomLevelLimits',
'setVisualZoomLevelLimits'
]
@@ -183,22 +183,25 @@ for (const method of webFrameMethods) {
}
}
const executeJavaScript = (contents, code, hasUserGesture) => {
return ipcMainUtils.invokeInWebContents(contents, false, 'ELECTRON_INTERNAL_RENDERER_WEB_FRAME_METHOD', 'executeJavaScript', code, hasUserGesture)
const waitTillCanExecuteJavaScript = async (webContents) => {
if (webContents.getURL() && !webContents.isLoadingMainFrame()) return
return new Promise((resolve) => {
webContents.once('did-stop-loading', () => {
resolve()
})
})
}
// Make sure WebContents::executeJavaScript would run the code only when the
// WebContents has been loaded.
WebContents.prototype.executeJavaScript = function (code, hasUserGesture) {
if (this.getURL() && !this.isLoadingMainFrame()) {
return executeJavaScript(this, code, hasUserGesture)
} else {
return new Promise((resolve, reject) => {
this.once('did-stop-loading', () => {
executeJavaScript(this, code, hasUserGesture).then(resolve, reject)
})
})
}
WebContents.prototype.executeJavaScript = async function (code, hasUserGesture) {
await waitTillCanExecuteJavaScript(this)
return ipcMainUtils.invokeInWebContents(this, false, 'ELECTRON_INTERNAL_RENDERER_WEB_FRAME_METHOD', 'executeJavaScript', code, hasUserGesture)
}
WebContents.prototype.executeJavaScriptInIsolatedWorld = async function (code, hasUserGesture) {
await waitTillCanExecuteJavaScript(this)
return ipcMainUtils.invokeInWebContents(this, false, 'ELECTRON_INTERNAL_RENDERER_WEB_FRAME_METHOD', 'executeJavaScriptInIsolatedWorld', code, hasUserGesture)
}
// Translate the options of printToPDF.
@@ -273,6 +276,7 @@ WebContents.prototype.getPrinters = function () {
return this._getPrinters()
} else {
console.error('Error: Printing feature is disabled.')
return []
}
}
@@ -394,9 +398,7 @@ WebContents.prototype._init = function () {
width: 800,
height: 600
}
ipcMainInternal.emit('ELECTRON_GUEST_WINDOW_MANAGER_INTERNAL_WINDOW_OPEN',
event, url, referrer, frameName, disposition,
options, additionalFeatures, postData)
internalWindowOpen(event, url, referrer, frameName, disposition, options, additionalFeatures, postData)
})
// Create a new browser window for the native implementation of
@@ -418,8 +420,7 @@ WebContents.prototype._init = function () {
webContents
}
const referrer = { url: '', policy: 'default' }
ipcMainInternal.emit('ELECTRON_GUEST_WINDOW_MANAGER_INTERNAL_WINDOW_OPEN',
event, url, referrer, frameName, disposition, options)
internalWindowOpen(event, url, referrer, frameName, disposition, options)
})
}

View File

@@ -0,0 +1,37 @@
'use strict'
// This is a temporary shim to aid in transition from the old
// BrowserWindow-based extensions stuff to the new native-backed extensions
// API.
if (!process.electronBinding('features').isExtensionsEnabled()) {
throw new Error('Attempted to load JS chrome-extension shim without //extensions support enabled')
}
const { app, session, BrowserWindow, deprecate } = require('electron')
app.once('ready', function () {
const addExtension = function (srcDirectory) {
return session.defaultSession.loadExtension(srcDirectory)
}
const removeExtension = function (name) {
const extension = session.defaultSession.getAllExtensions().find(e => e.name === name)
if (extension) { session.defaultSession.removeExtension(extension.id) }
}
const getExtensions = function () {
const extensions = {}
session.defaultSession.getAllExtensions().forEach(e => {
extensions[e.name] = e
})
return extensions
}
BrowserWindow.addExtension = deprecate.moveAPI(addExtension, 'BrowserWindow.addExtension', 'session.loadExtension')
BrowserWindow.removeExtension = deprecate.moveAPI(removeExtension, 'BrowserWindow.removeExtension', 'session.removeExtension')
BrowserWindow.getExtensions = deprecate.moveAPI(getExtensions, 'BrowserWindow.getExtensions', 'session.getAllExtensions')
BrowserWindow.addDevToolsExtension = deprecate.moveAPI(addExtension, 'BrowserWindow.addDevToolsExtension', 'session.loadExtension')
BrowserWindow.removeDevToolsExtension = deprecate.moveAPI(removeExtension, 'BrowserWindow.removeDevToolsExtension', 'session.removeExtension')
BrowserWindow.getDevToolsExtensions = deprecate.moveAPI(getExtensions, 'BrowserWindow.getDevToolsExtensions', 'session.getAllExtensions')
})

View File

@@ -57,18 +57,25 @@ const getManifestFromPath = function (srcDirectory) {
if (!manifestNameMap[manifest.name]) {
const extensionId = generateExtensionIdFromName(manifest.name)
manifestMap[extensionId] = manifestNameMap[manifest.name] = manifest
let extensionURL = url.format({
protocol: 'chrome-extension',
slashes: true,
hostname: extensionId,
pathname: manifest.devtools_page
})
// Chromium requires that startPage matches '([^:]+:\/\/[^/]*)\/'
// We also can't use the file:// protocol here since that would make Chromium
// treat all extension resources as being relative to root which we don't want.
if (!manifest.devtools_page) extensionURL += '/'
Object.assign(manifest, {
srcDirectory: srcDirectory,
extensionId: extensionId,
// We can not use 'file://' directly because all resources in the extension
// will be treated as relative to the root in Chrome.
startPage: url.format({
protocol: 'chrome-extension',
slashes: true,
hostname: extensionId,
pathname: manifest.devtools_page
})
startPage: extensionURL
})
return manifest
} else if (manifest && manifest.name) {
console.warn(`Attempted to load extension "${manifest.name}" that has already been loaded.`)
@@ -389,7 +396,8 @@ const loadDevToolsExtensions = function (win, manifests) {
})
extensionInfoArray.forEach((extensionInfo) => {
win.devToolsWebContents.executeJavaScript(`Extensions.extensionServer._addExtension(${JSON.stringify(extensionInfo)})`)
const info = JSON.stringify(extensionInfo)
win.devToolsWebContents.executeJavaScript(`Extensions.extensionServer._addExtension(${info})`)
})
}

View File

@@ -1,6 +1,7 @@
'use strict'
const { BrowserWindow, webContents } = require('electron')
const electron = require('electron')
const { BrowserWindow } = electron
const { isSameOrigin } = process.electronBinding('v8_util')
const { ipcMainInternal } = require('@electron/internal/browser/ipc-main-internal')
const ipcMainUtils = require('@electron/internal/browser/ipc-main-internal-utils')
@@ -74,8 +75,10 @@ const mergeBrowserWindowOptions = function (embedder, options) {
}
}
// Sets correct openerId here to give correct options to 'new-window' event handler
options.webPreferences.openerId = embedder.id
if (!webPreferences.nativeWindowOpen) {
// Sets correct openerId here to give correct options to 'new-window' event handler
options.webPreferences.openerId = embedder.id
}
return options
}
@@ -244,13 +247,11 @@ ipcMainInternal.on('ELECTRON_GUEST_WINDOW_MANAGER_WINDOW_OPEN', (event, url, fra
}
const referrer = { url: '', policy: 'default' }
ipcMainInternal.emit('ELECTRON_GUEST_WINDOW_MANAGER_INTERNAL_WINDOW_OPEN', event,
url, referrer, frameName, disposition, options, additionalFeatures)
internalWindowOpen(event, url, referrer, frameName, disposition, options, additionalFeatures)
})
// Routed window.open messages with fully parsed options
ipcMainInternal.on('ELECTRON_GUEST_WINDOW_MANAGER_INTERNAL_WINDOW_OPEN', function (event, url, referrer,
frameName, disposition, options, additionalFeatures, postData) {
function internalWindowOpen (event, url, referrer, frameName, disposition, options, additionalFeatures, postData) {
options = mergeBrowserWindowOptions(event.sender, options)
event.sender.emit('new-window', event, url, frameName, disposition, options, additionalFeatures, referrer)
const { newGuest } = event
@@ -268,11 +269,12 @@ ipcMainInternal.on('ELECTRON_GUEST_WINDOW_MANAGER_INTERNAL_WINDOW_OPEN', functio
} else {
event.returnValue = createGuest(event.sender, url, referrer, frameName, options, postData)
}
})
}
const makeSafeHandler = function (handler) {
return (event, guestId, ...args) => {
const guestContents = webContents.fromId(guestId)
// Access webContents via electron to prevent circular require.
const guestContents = electron.webContents.fromId(guestId)
if (!guestContents) {
throw new Error(`Invalid guestId: ${guestId}`)
}
@@ -289,8 +291,8 @@ const handleMessageSync = function (channel, handler) {
ipcMainUtils.handleSync(channel, makeSafeHandler(handler))
}
const assertCanAccessWindow = function (contents, guestContents) {
if (!canAccessWindow(contents, guestContents)) {
const securityCheck = function (contents, guestContents, check) {
if (!check(contents, guestContents)) {
console.error(`Blocked ${contents.getURL()} from accessing guestId: ${guestContents.id}`)
throw new Error(`Access denied to guestId: ${guestContents.id}`)
}
@@ -303,7 +305,7 @@ const windowMethods = new Set([
])
handleMessage('ELECTRON_GUEST_WINDOW_MANAGER_WINDOW_METHOD', (event, guestContents, method, ...args) => {
assertCanAccessWindow(event.sender, guestContents)
securityCheck(event.sender, guestContents, canAccessWindow)
if (!windowMethods.has(method)) {
console.error(`Blocked ${event.sender.getURL()} from calling method: ${method}`)
@@ -321,6 +323,8 @@ handleMessage('ELECTRON_GUEST_WINDOW_MANAGER_WINDOW_POSTMESSAGE', (event, guestC
// The W3C does not seem to have word on how postMessage should work when the
// origins do not match, so we do not do |canAccessWindow| check here since
// postMessage across origins is useful and not harmful.
securityCheck(event.sender, guestContents, isRelatedWindow)
if (targetOrigin === '*' || isSameOrigin(guestContents.getURL(), targetOrigin)) {
const sourceId = event.sender.id
guestContents._sendInternal('ELECTRON_GUEST_WINDOW_POSTMESSAGE', sourceId, message, sourceOrigin)
@@ -334,7 +338,7 @@ const webContentsMethodsAsync = new Set([
])
handleMessage('ELECTRON_GUEST_WINDOW_MANAGER_WEB_CONTENTS_METHOD', (event, guestContents, method, ...args) => {
assertCanAccessWindow(event.sender, guestContents)
securityCheck(event.sender, guestContents, canAccessWindow)
if (!webContentsMethodsAsync.has(method)) {
console.error(`Blocked ${event.sender.getURL()} from calling method: ${method}`)
@@ -349,7 +353,7 @@ const webContentsMethodsSync = new Set([
])
handleMessageSync('ELECTRON_GUEST_WINDOW_MANAGER_WEB_CONTENTS_METHOD', (event, guestContents, method, ...args) => {
assertCanAccessWindow(event.sender, guestContents)
securityCheck(event.sender, guestContents, canAccessWindow)
if (!webContentsMethodsSync.has(method)) {
console.error(`Blocked ${event.sender.getURL()} from calling method: ${method}`)
@@ -358,3 +362,5 @@ handleMessageSync('ELECTRON_GUEST_WINDOW_MANAGER_WEB_CONTENTS_METHOD', (event, g
return guestContents[method](...args)
})
exports.internalWindowOpen = internalWindowOpen

View File

@@ -154,7 +154,9 @@ require('@electron/internal/browser/devtools')
const features = process.electronBinding('features')
// Load the chrome extension support.
if (!features.isExtensionsEnabled()) {
if (features.isExtensionsEnabled()) {
require('@electron/internal/browser/chrome-extension-shim')
} else {
require('@electron/internal/browser/chrome-extension')
}
@@ -195,13 +197,14 @@ app.on('window-all-closed', () => {
}
})
Promise.all([
import('@electron/internal/browser/default-menu'),
app.whenReady()
]).then(([{ setDefaultApplicationMenu }]) => {
// Create default menu
setDefaultApplicationMenu()
})
const { setDefaultApplicationMenu } = require('@electron/internal/browser/default-menu')
// Create default menu.
//
// Note that the task must be added before loading any app, so we can make sure
// the call is maded before any user window is created, otherwise the default
// menu may show even when user explicitly hides the menu.
app.once('ready', setDefaultApplicationMenu)
if (packagePath) {
// Finally load app's main.js and transfer control to C++.

View File

@@ -152,7 +152,8 @@ const NavigationController = (function () {
NavigationController.prototype.reloadIgnoringCache = function () {
this.pendingIndex = this.currentIndex
return this.webContents._loadURL(this.getURL(), {
extraHeaders: 'pragma: no-cache\n'
extraHeaders: 'pragma: no-cache\n',
reloadIgnoringCache: true
})
}

View File

@@ -23,7 +23,7 @@ const FUNCTION_PROPERTIES = [
// The remote functions in renderer processes.
// id => Function
const rendererFunctions = v8Util.createDoubleIDWeakMap()
const rendererFunctions = v8Util.createDoubleIDWeakMap<(...args: any[]) => void>()
type ObjectMember = {
name: string,
@@ -289,7 +289,7 @@ const unwrapArgs = function (sender: electron.WebContents, frameId: number, cont
case 'function': {
// Merge contextId and meta.id, since meta.id can be the same in
// different webContents.
const objectId = [contextId, meta.id]
const objectId: [string, number] = [contextId, meta.id]
// Cache the callbacks in renderer.
if (rendererFunctions.has(objectId)) {
@@ -321,7 +321,7 @@ const unwrapArgs = function (sender: electron.WebContents, frameId: number, cont
const isRemoteModuleEnabledImpl = function (contents: electron.WebContents) {
const webPreferences = (contents as any).getLastWebPreferences() || {}
return !!webPreferences.enableRemoteModule
return webPreferences.enableRemoteModule != null ? !!webPreferences.enableRemoteModule : true
}
const isRemoteModuleEnabledCache = new WeakMap()
@@ -373,12 +373,12 @@ const logStack = function (contents: electron.WebContents, code: string, stack:
}
handleRemoteCommand('ELECTRON_BROWSER_WRONG_CONTEXT_ERROR', function (event, contextId, passedContextId, id) {
const objectId = [passedContextId, id]
const objectId: [string, number] = [passedContextId, id]
if (!rendererFunctions.has(objectId)) {
// Do nothing if the error has already been reported before.
return
}
removeRemoteListenersAndLogWarning(event.sender, rendererFunctions.get(objectId))
removeRemoteListenersAndLogWarning(event.sender, rendererFunctions.get(objectId)!)
})
handleRemoteCommand('ELECTRON_BROWSER_REQUIRE', function (event, contextId, moduleName, stack) {

View File

@@ -112,11 +112,15 @@ ipcMainUtils.handleSync('ELECTRON_BROWSER_SANDBOX_LOAD', async function (event)
contentScripts = getContentScripts()
}
const webPreferences = event.sender.getLastWebPreferences() || {}
return {
contentScripts,
preloadScripts: await Promise.all(preloadPaths.map(path => getPreloadScript(path))),
isRemoteModuleEnabled: isRemoteModuleEnabled(event.sender),
isWebViewTagEnabled: guestViewManager.isWebViewTagEnabled(event.sender),
guestInstanceId: webPreferences.guestInstanceId,
openerId: webPreferences.openerId,
process: {
arch: process.arch,
platform: process.platform,

View File

@@ -711,31 +711,42 @@
overrideAPISync(Module._extensions, '.node', 1)
overrideAPISync(fs, 'openSync')
// Lazily override the child_process APIs only when child_process is fetched the first time
const originalModuleLoad = Module._load
Module._load = (request, ...args) => {
const loadResult = originalModuleLoad(request, ...args)
if (request === 'child_process') {
if (!v8Util.getHiddenValue(loadResult, 'asar-ready')) {
v8Util.setHiddenValue(loadResult, 'asar-ready', true)
// Just to make it obvious what we are dealing with here
const childProcess = loadResult
const overrideChildProcess = (childProcess) => {
// Executing a command string containing a path to an asar archive
// confuses `childProcess.execFile`, which is internally called by
// `childProcess.{exec,execSync}`, causing Electron to consider the full
// command as a single path to an archive.
const { exec, execSync } = childProcess
childProcess.exec = invokeWithNoAsar(exec)
childProcess.exec[util.promisify.custom] = invokeWithNoAsar(exec[util.promisify.custom])
childProcess.execSync = invokeWithNoAsar(execSync)
// Executing a command string containing a path to an asar
// archive confuses `childProcess.execFile`, which is internally
// called by `childProcess.{exec,execSync}`, causing
// Electron to consider the full command as a single path
// to an archive.
const { exec, execSync } = childProcess
childProcess.exec = invokeWithNoAsar(exec)
childProcess.exec[util.promisify.custom] = invokeWithNoAsar(exec[util.promisify.custom])
childProcess.execSync = invokeWithNoAsar(execSync)
overrideAPI(childProcess, 'execFile')
overrideAPISync(childProcess, 'execFileSync')
}
overrideAPI(childProcess, 'execFile')
overrideAPISync(childProcess, 'execFileSync')
// Lazily override the child_process APIs only when child_process is
// fetched the first time. We will eagerly override the child_process APIs
// when this env var is set so that stack traces generated inside node unit
// tests will match. This env var will only slow things down in users apps
// and should not be used.
if (process.env.ELECTRON_EAGER_ASAR_HOOK_FOR_TESTING) {
overrideChildProcess(require('child_process'))
} else {
const originalModuleLoad = Module._load
Module._load = (request, ...args) => {
const loadResult = originalModuleLoad(request, ...args)
if (request === 'child_process') {
if (!v8Util.getHiddenValue(loadResult, 'asar-ready')) {
v8Util.setHiddenValue(loadResult, 'asar-ready', true)
// Just to make it obvious what we are dealing with here
const childProcess = loadResult
overrideChildProcess(childProcess)
}
}
return loadResult
}
return loadResult
}
}
})()

View File

@@ -54,7 +54,12 @@ class CrashReporter {
}
getUploadedReports () {
return binding.getUploadedReports(this.getCrashesDirectory())
const crashDir = this.getCrashesDirectory()
if (!crashDir) {
throw new Error('crashReporter has not been started')
}
return binding.getUploadedReports(crashDir)
}
getCrashesDirectory () {

View File

@@ -13,6 +13,15 @@ const remoteObjectCache = v8Util.createIDWeakMap()
// An unique ID that can represent current context.
const contextId = v8Util.getHiddenValue(global, 'contextId')
ipcRendererInternal.invoke('ELECTRON_BROWSER_GET_LAST_WEB_PREFERENCES').then(preferences => {
console.log(preferences)
if (!preferences.enableRemoteModule) {
console.warn('%cElectron Deprecation Warning', 'font-weight: bold', "The 'remote' module is deprecated and will be disabled by default in a future version of Electron. To ensure a smooth upgrade and silence this warning, specify {enableRemoteModule: true} in the WebPreferences for this window.")
}
}, (err) => {
console.error('Failed to get web preferences:', err)
})
// Notify the main process when current context is going to be released.
// Note that when the renderer process is destroyed, the message may not be
// sent, we also listen to the "render-view-deleted" event in the main process

View File

@@ -192,6 +192,8 @@ if (nodeIntegration) {
delete global.setImmediate
delete global.clearImmediate
delete global.global
delete global.root
delete global.GLOBAL
})
}
}

View File

@@ -268,7 +268,9 @@ const warnAboutAllowedPopups = function () {
// Logs a warning message about the remote module
const warnAboutRemoteModuleWithRemoteContent = function (webPreferences?: Electron.WebPreferences) {
if (!webPreferences || !webPreferences.enableRemoteModule || isLocalhost()) return
if (!webPreferences || isLocalhost()) return
const remoteModuleEnabled = webPreferences.enableRemoteModule != null ? !!webPreferences.enableRemoteModule : true
if (!remoteModuleEnabled) return
if (getIsRemoteProtocol()) {
const warning = `This renderer process has "enableRemoteModule" enabled

View File

@@ -177,7 +177,7 @@ class BrowserWindowProxy {
export const windowSetup = (
guestInstanceId: number, openerId: number, isHiddenPage: boolean, usesNativeWindowOpen: boolean
) => {
if (guestInstanceId == null) {
if (!process.sandboxed && guestInstanceId == null) {
// Override default window.close.
window.close = function () {
ipcRendererInternal.send('ELECTRON_BROWSER_WINDOW_CLOSE')
@@ -197,10 +197,10 @@ export const windowSetup = (
return null
}
}
}
if (openerId != null) {
window.opener = getOrCreateProxy(openerId)
}
if (openerId != null) {
window.opener = getOrCreateProxy(openerId)
}
// But we do not support prompt().
@@ -208,42 +208,47 @@ export const windowSetup = (
throw new Error('prompt() is and will not be supported.')
}
ipcRendererInternal.on('ELECTRON_GUEST_WINDOW_POSTMESSAGE', function (
_event, sourceId: number, message: any, sourceOrigin: string
) {
// Manually dispatch event instead of using postMessage because we also need to
// set event.source.
//
// Why any? We can't construct a MessageEvent and we can't
// use `as MessageEvent` because you're not supposed to override
// data, origin, and source
const event: any = document.createEvent('Event')
event.initEvent('message', false, false)
if (!usesNativeWindowOpen || openerId != null) {
ipcRendererInternal.on('ELECTRON_GUEST_WINDOW_POSTMESSAGE', function (
_event, sourceId: number, message: any, sourceOrigin: string
) {
// Manually dispatch event instead of using postMessage because we also need to
// set event.source.
//
// Why any? We can't construct a MessageEvent and we can't
// use `as MessageEvent` because you're not supposed to override
// data, origin, and source
const event: any = document.createEvent('Event')
event.initEvent('message', false, false)
event.data = message
event.origin = sourceOrigin
event.source = getOrCreateProxy(sourceId)
event.data = message
event.origin = sourceOrigin
event.source = getOrCreateProxy(sourceId)
window.dispatchEvent(event as MessageEvent)
})
window.history.back = function () {
ipcRendererInternal.send('ELECTRON_NAVIGATION_CONTROLLER_GO_BACK')
window.dispatchEvent(event as MessageEvent)
})
}
window.history.forward = function () {
ipcRendererInternal.send('ELECTRON_NAVIGATION_CONTROLLER_GO_FORWARD')
}
window.history.go = function (offset: number) {
ipcRendererInternal.send('ELECTRON_NAVIGATION_CONTROLLER_GO_TO_OFFSET', +offset)
}
Object.defineProperty(window.history, 'length', {
get: function () {
return ipcRendererInternal.sendSync('ELECTRON_NAVIGATION_CONTROLLER_LENGTH')
if (!process.sandboxed) {
window.history.back = function () {
ipcRendererInternal.send('ELECTRON_NAVIGATION_CONTROLLER_GO_BACK')
}
})
window.history.forward = function () {
ipcRendererInternal.send('ELECTRON_NAVIGATION_CONTROLLER_GO_FORWARD')
}
window.history.go = function (offset: number) {
ipcRendererInternal.send('ELECTRON_NAVIGATION_CONTROLLER_GO_TO_OFFSET', +offset)
}
Object.defineProperty(window.history, 'length', {
get: function () {
return ipcRendererInternal.sendSync('ELECTRON_NAVIGATION_CONTROLLER_LENGTH')
},
set () {}
})
}
if (guestInstanceId != null) {
// Webview `document.visibilityState` tracks window visibility (and ignores

View File

@@ -30,7 +30,13 @@ const { ipcRendererInternal } = require('@electron/internal/renderer/ipc-rendere
const ipcRendererUtils = require('@electron/internal/renderer/ipc-renderer-internal-utils')
const {
contentScripts, preloadScripts, isRemoteModuleEnabled, isWebViewTagEnabled, process: processProps
contentScripts,
preloadScripts,
isRemoteModuleEnabled,
isWebViewTagEnabled,
guestInstanceId,
openerId,
process: processProps
} = ipcRendererUtils.invokeSync('ELECTRON_BROWSER_SANDBOX_LOAD')
process.isRemoteModuleEnabled = isRemoteModuleEnabled
@@ -109,6 +115,11 @@ function preloadRequire (module) {
const { hasSwitch } = process.electronBinding('command_line')
const contextIsolation = hasSwitch('context-isolation')
const isHiddenPage = hasSwitch('hidden-page')
const usesNativeWindowOpen = true
// The arguments to be passed to isolated world.
const isolatedWorldArgs = { ipcRendererInternal, guestInstanceId, isHiddenPage, openerId, usesNativeWindowOpen }
switch (window.location.protocol) {
case 'devtools:': {
@@ -127,6 +138,10 @@ switch (window.location.protocol) {
break
}
default: {
// Override default web functions.
const { windowSetup } = require('@electron/internal/renderer/window-setup')
windowSetup(guestInstanceId, openerId, isHiddenPage, usesNativeWindowOpen)
// Inject content scripts.
if (!process.electronBinding('features').isExtensionsEnabled()) {
require('@electron/internal/renderer/content-scripts-injector')(contentScripts)
@@ -134,14 +149,17 @@ switch (window.location.protocol) {
}
}
const guestInstanceId = binding.guestInstanceId && parseInt(binding.guestInstanceId)
// Load webview tag implementation.
if (process.isMainFrame) {
const { webViewInit } = require('@electron/internal/renderer/web-view/web-view-init')
webViewInit(contextIsolation, isWebViewTagEnabled, guestInstanceId)
}
// Pass the arguments to isolatedWorld.
if (contextIsolation) {
v8Util.setHiddenValue(global, 'isolated-world-args', isolatedWorldArgs)
}
// Wrap the script into a function executed in global scope. It won't have
// access to the current scope, so we'll expose a few objects as arguments:
//

View File

@@ -1,32 +0,0 @@
config("native_mate_config") {
include_dirs = [ "." ]
}
source_set("native_mate") {
deps = [
"//base",
"//net",
"//third_party/electron_node:node_lib",
"//v8:v8_headers",
]
public_configs = [ ":native_mate_config" ]
include_dirs = [ ".." ]
sources = [
"native_mate/arguments.cc",
"native_mate/arguments.h",
"native_mate/compat.h",
"native_mate/constructor.h",
"native_mate/converter.cc",
"native_mate/converter.h",
"native_mate/dictionary.cc",
"native_mate/dictionary.h",
"native_mate/function_template.cc",
"native_mate/function_template.h",
"native_mate/handle.h",
"native_mate/object_template_builder.cc",
"native_mate/object_template_builder_deprecated.h",
"native_mate/wrappable.cc",
"native_mate/wrappable.h",
"native_mate/wrappable_base.h",
]
}

View File

@@ -1,27 +0,0 @@
// Copyright 2014 The Chromium Authors. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View File

@@ -1,56 +0,0 @@
> A fork of Chromium's [gin library][chromium-gin-lib] that makes it easier to
> marshal types between C++ and JavaScript.
# Overview
`native-mate` was forked from `gin` so that it could be used in
[Electron][electron] without conflicting with Node's Environment. It has also
been extended to allow Electron to create classes in JavaScript.
With the help of Chromium's `base` library, `native-mate` makes writing JS
bindings very easy, and most of the intricate details of converting V8 types
to C++ types and back are taken care of auto-magically. In most cases there's
no need to use the raw V8 API to implement an API binding.
For example, here's an API binding that doesn't use `native-mate`:
```c++
// static
void Shell::OpenItem(const v8::FunctionCallbackInfo<v8::Value>& args) {
base::FilePath file_path;
if (!FromV8Arguments(args, &file_path))
return node::ThrowTypeError("Bad argument");
platform_util::OpenItem(file_path);
}
// static
void Shell::Initialize(v8::Handle<v8::Object> target) {
NODE_SET_METHOD(target, "openItem", OpenItem);
}
```
And here's the same API binding using `native-mate`:
```c++
void Initialize(v8::Handle<v8::Object> exports) {
mate::Dictionary dict(v8::Isolate::GetCurrent(), exports);
dict.SetMethod("openItem", &platform_util::OpenItem);
}
```
# Code Structure
* `converter.h` - Templatized JS<->C++ conversion routines for many common C++
types. You can define your own by specializing `Converter`.
* `function_template.h` - Create JavaScript functions that dispatch to any C++
function, member function pointer, or `base::Callback`.
* `object_template_builder_deprecated.h` - A handy utility for creation of `v8::ObjectTemplate`.
* `wrappable.h` - Base class for C++ classes that want to be owned by the V8 GC.
Wrappable objects are automatically deleted when GC discovers that nothing in
the V8 heap refers to them. This is also an easy way to expose C++ objects to
JavaScript.
[chromium-gin-lib]: https://code.google.com/p/chromium/codesearch#chromium/src/gin/README.md&sq=package:chromium
[electron]: https://electronjs.org/

View File

@@ -1,61 +0,0 @@
// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE.chromium file.
#include "native_mate/arguments.h"
#include "base/strings/stringprintf.h"
#include "native_mate/converter.h"
namespace mate {
namespace {
std::string V8TypeAsString(v8::Isolate* isolate, v8::Local<v8::Value> value) {
if (value.IsEmpty())
return "<empty handle>";
v8::MaybeLocal<v8::String> details =
value->ToDetailString(isolate->GetCurrentContext());
std::string result;
if (!details.IsEmpty())
ConvertFromV8(isolate, details.ToLocalChecked(), &result);
return result;
}
} // namespace
Arguments::Arguments() = default;
Arguments::Arguments(const v8::FunctionCallbackInfo<v8::Value>& info)
: isolate_(info.GetIsolate()), info_(&info) {}
Arguments::~Arguments() = default;
v8::Local<v8::Value> Arguments::PeekNext() const {
if (next_ >= info_->Length())
return v8::Local<v8::Value>();
return (*info_)[next_];
}
v8::Local<v8::Value> Arguments::ThrowError() const {
if (insufficient_arguments_)
return ThrowTypeError("Insufficient number of arguments.");
return ThrowTypeError(base::StringPrintf(
"Error processing argument at index %d, conversion failure from %s",
next_, V8TypeAsString(isolate_, (*info_)[next_]).c_str()));
}
v8::Local<v8::Value> Arguments::ThrowError(const std::string& message) const {
isolate_->ThrowException(v8::Exception::Error(StringToV8(isolate_, message)));
return v8::Undefined(isolate_);
}
v8::Local<v8::Value> Arguments::ThrowTypeError(
const std::string& message) const {
isolate_->ThrowException(
v8::Exception::TypeError(StringToV8(isolate_, message)));
return v8::Undefined(isolate_);
}
} // namespace mate

View File

@@ -1,111 +0,0 @@
// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE.chromium file.
#ifndef NATIVE_MATE_NATIVE_MATE_ARGUMENTS_H_
#define NATIVE_MATE_NATIVE_MATE_ARGUMENTS_H_
#include <string>
#include <vector>
#include "base/macros.h"
#include "base/optional.h"
#include "native_mate/converter.h"
// =============================== NOTICE ===============================
// Do not add code here, native_mate is being removed. Any new code
// should use gin instead.
namespace mate {
// Arguments is a wrapper around v8::FunctionCallbackInfo that integrates
// with Converter to make it easier to marshall arguments and return values
// between V8 and C++.
class Arguments {
public:
Arguments();
explicit Arguments(const v8::FunctionCallbackInfo<v8::Value>& info);
~Arguments();
v8::Local<v8::Object> GetHolder() const { return info_->Holder(); }
template <typename T>
bool GetHolder(T* out) {
return mate::ConvertFromV8(isolate_, info_->Holder(), out);
}
template <typename T>
bool GetData(T* out) {
return ConvertFromV8(isolate_, info_->Data(), out);
}
template <typename T>
bool GetNext(base::Optional<T>* out) {
if (next_ >= info_->Length())
return true;
v8::Local<v8::Value> val = (*info_)[next_];
bool success = ConvertFromV8(isolate_, val, out);
if (success)
next_++;
return success;
}
template <typename T>
bool GetNext(T* out) {
if (next_ >= info_->Length()) {
insufficient_arguments_ = true;
return false;
}
v8::Local<v8::Value> val = (*info_)[next_];
bool success = mate::ConvertFromV8(isolate_, val, out);
if (success)
next_++;
return success;
}
template <typename T>
bool GetRemaining(std::vector<T>* out) {
if (next_ >= info_->Length()) {
insufficient_arguments_ = true;
return false;
}
int remaining = info_->Length() - next_;
out->resize(remaining);
for (int i = 0; i < remaining; ++i) {
v8::Local<v8::Value> val = (*info_)[next_++];
if (!ConvertFromV8(isolate_, val, &out->at(i)))
return false;
}
return true;
}
v8::Local<v8::Object> GetThis() { return info_->This(); }
bool IsConstructCall() const { return info_->IsConstructCall(); }
int Length() const { return info_->Length(); }
template <typename T>
void Return(const T& val) {
info_->GetReturnValue().Set(ConvertToV8(isolate_, val));
}
v8::Local<v8::Value> PeekNext() const;
v8::Local<v8::Value> ThrowError() const;
v8::Local<v8::Value> ThrowError(const std::string& message) const;
v8::Local<v8::Value> ThrowTypeError(const std::string& message) const;
v8::Isolate* isolate() const { return isolate_; }
const v8::FunctionCallbackInfo<v8::Value>& info() const { return *info_; }
private:
v8::Isolate* isolate_ = nullptr;
const v8::FunctionCallbackInfo<v8::Value>* info_ = nullptr;
int next_ = 0;
bool insufficient_arguments_ = false;
};
} // namespace mate
#endif // NATIVE_MATE_NATIVE_MATE_ARGUMENTS_H_

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