Compare commits

...

128 Commits

Author SHA1 Message Date
Electron Bot
258f245e74 Bump v12.0.5 2021-04-20 16:32:33 -07:00
trop[bot]
d0fdf5a374 build: fix docs only change script to pull all files not just 30 (#28742)
Co-authored-by: Samuel Attard <samuel.r.attard@gmail.com>
2021-04-19 18:28:45 -07:00
trop[bot]
3d82985602 docs(build-instructions): clarify that these are for building Electron itself (#28727)
Co-authored-by: Mark Lee <electronjs@lazymalevolence.com>
2021-04-19 20:11:13 -04:00
trop[bot]
93342d9302 build: read node files as binary files (#28736)
Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
2021-04-19 19:58:40 -04:00
trop[bot]
50094b3a25 chore: clean up some spec things (#28730)
Co-authored-by: Samuel Attard <samuel.r.attard@gmail.com>
2021-04-19 12:54:54 -07:00
trop[bot]
13284a3a57 fix: do not handle write errors after request is aborted (#28721)
This fixes a flake on linux CI which started recently where the "write"
promise is being rejected after the request has been aborted /
cancelled.  In this case we should drop the error to the floor but
instead we pass it down the stack where it eventually emits a now
unhandled error event.

Example failure: https://app.circleci.com/pipelines/github/electron/electron/38072/workflows/c1faf19b-aa41-4f99-a564-165729222859/jobs/838813

Verified fix by running the test that caused it 10000 times before fix
and 10000 times after.  ~50 failures before, 0 after.

Co-authored-by: Samuel Attard <samuel.r.attard@gmail.com>
2021-04-19 11:26:16 -07:00
Keeley Hammond
5da6ee1fc1 fix: invoke the window open handler for _blank links (#28498) (#28664)
* fix: invoke the window open handler for _blank links

* add test
2021-04-15 14:22:14 -07:00
Electron Bot
4de3e451ac chore: bump chromium to 89.0.4389.128 (12-x-y) (#28659)
* chore: bump chromium in DEPS to 89.0.4389.128

* update patches
2021-04-14 13:27:11 -04:00
trop[bot]
d27046272e build: do not require vsts token for releases (#28650)
Co-authored-by: Samuel Attard <sattard@slack-corp.com>
2021-04-14 11:44:27 +02:00
Electron Bot
9ce7c51247 Bump v12.0.4 2021-04-13 13:40:56 -07:00
Electron Bot
840ac755b8 chore: cherry-pick 02f84c745fc0 from v8 (#28638)
* chore: cherry-pick 02f84c745fc0 from v8

* update patches
2021-04-13 13:29:19 -07:00
Electron Bot
8115520d2a Bump v12.0.3 2021-04-13 07:40:27 -07:00
trop[bot]
92e3b1305c build: better error handling for release builds (#28628)
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2021-04-13 10:27:57 -04:00
Michaela Laurencin
93dab148c8 fix: enable system maximization for frameless windows except if transparent (#28207) (#28622)
* fix: move widget maximization check

* fix linting error

* change workaround to only effect transparent windows

* disable menu maximize and restore for transparent windows

* disable double clicking title bar max/unmax for transparent windows

* add docs change and address review
2021-04-13 09:49:42 -04:00
trop[bot]
e100c22a26 fix: crash on invalid select-serial-port callback (#28618)
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2021-04-12 11:58:25 -04:00
Jeremy Rose
4efeaa090a chore: cherry-pick 162efe98330e from chromium (#28601)
* chore: cherry-pick 162efe98330e from chromium

* update patches

Co-authored-by: Electron Bot <electron@github.com>
2021-04-12 01:39:33 -07:00
trop[bot]
93c6c8c103 docs: define the name of the preload script (#28610)
Co-authored-by: KSneijders <32707500+KSneijders@users.noreply.github.com>
2021-04-12 00:13:53 -07:00
trop[bot]
df9a01bb53 docs: systemPreferences.subscribeWorkspaceNotification return type (#28614)
Co-authored-by: Samuel Maddock <samuel.maddock@gmail.com>
2021-04-12 00:13:07 -07:00
Robo
5c10eb4c26 fix: load source maps from custom protocols and asar bundles (#28616) 2021-04-11 23:57:09 -07:00
trop[bot]
f836ef0f47 chore: don't minimize js in development (#28585)
Co-authored-by: Jeremy Rose <nornagon@nornagon.net>
2021-04-09 16:09:41 +09:00
Cheng Zhao
274f6f75b5 fix: allow accessing file:// when web security is disabled (#28560)
* fix: allow accessing file:// when web security is disabled

* fixup lint after merge

Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
2021-04-09 09:46:36 +09:00
Cheng Zhao
2f42c2c76e fix: support wasm-eval csp behind WebAssemblyCSP flag (#28575)
* feat: support wasm-eval csp behind WebAssemblyCSP flag

* update patches

Co-authored-by: Electron Bot <electron@github.com>
2021-04-08 04:31:44 -07:00
Fedor Indutny
1cf09e7aab backport 3b21b6d from v8 to fix profiler crash (#28531) 2021-04-07 14:49:20 +09:00
trop[bot]
06580db96d fix: call UnregisterIsolate consistently (#28555)
* fix: call `UnregisterIsolate` consistently

`JavascriptEnvironment` is the class that calls `RegisterIsolate()`
so it should be the one to call `UnregisterIsolate`, and this can happen
right before disposing the aforementioned `isolate`.

See: https://github.com/electron/electron/pull/28468

* fix

Co-authored-by: Fedor Indutny <fedor@indutny.com>
2021-04-07 10:08:06 +09:00
Jeremy Rose
337e691089 fix: pass postData to new-window event (#28543)
* fix: pass postData to new-window event (#28513)

* Update api-browser-window-spec.ts
2021-04-07 10:00:16 +09:00
trop[bot]
731fe11db6 ci: Add goma fallback flag (#28545)
* ci: fallback to local compile if goma auth fails

* use correct flag

Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
2021-04-07 09:48:16 +09:00
trop[bot]
9e4f6bf8b4 fix: dialog DCHECK on Linux (#28533)
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2021-04-06 11:30:33 -04:00
trop[bot]
59328b6f8f fix: reject task append to JumpList when description exceeds 260 characters (#28525)
* fix: reject task when description exceeds 260 characters

* Switched out wcslen() for size() [linear -> constant time]

* Included comment describing the need for the additional check

* Added information about character limit to documentation

* Added newline character to end of jump-list-category.md

Co-authored-by: SushiJackal <weingaben@gmail.com>
2021-04-05 23:57:13 -07:00
trop[bot]
facc12eafa docs: the minimum supported version of macOS is now 10.11 (#28515)
* chore: the minimum supported version is now 10.11

Chromium bumped this version back in December

* Update support.md

Co-authored-by: Samuel Attard <sam@electronjs.org>
2021-04-05 13:03:41 -07:00
trop[bot]
d9ce3ac776 fix: free IsolateData in ~NodeEnvironment (#28483)
This seems to just have been missing here, leaking memory
(and breaking the API contract for Node.js embedding).

Co-authored-by: Anna Henningsen <anna@addaleax.net>
2021-04-02 00:15:54 -07:00
Jeremy Rose
6314637ae9 fix: put RemoteCertVerifier upstream from the caching and coalescing layers (#28358) (#28465) 2021-03-31 13:56:53 -07:00
Electron Bot
00d5c6ad53 chore: bump chromium to 89.0.4389.114 (12-x-y) (#28461)
* chore: bump chromium in DEPS to 89.0.4389.114

* update patches
2021-03-31 13:56:35 -07:00
Antón Molleda
7ac905dd77 docs: remove application-packaging.md (#28457)
This tutorial was removed as part of
https://github.com/electron/electron/pull/26239 but was not deleted when
the documentation was backported in
https://github.com/electron/electron/pull/28396
2021-03-31 01:33:29 -07:00
trop[bot]
d99ab3fb41 chore: update Community link in default menu (#28458)
Co-authored-by: Erick Zhao <erick@hotmail.ca>
2021-03-31 01:32:00 -07:00
trop[bot]
80ca7be524 fix: handle an unparsable pdf manifest (#28452)
Co-authored-by: Samuel Attard <sattard@slack-corp.com>
2021-03-30 23:21:06 -07:00
Shelley Vohr
deb667054c fix: errors thrown in functions over the contextBridge (#28447)
* fix: errors thrown in functions over the contextBridge

* spec: add a test

* fix: ensure exception is a v8::Object
2021-03-30 23:20:43 -07:00
Antón Molleda
22f6abc4f5 docs: backport current tutorials to 12-x-y (#28396) 2021-03-30 11:53:59 -07:00
trop[bot]
c023c480bb feat: initialize field trials from command line arguments (#28403)
Fixes: #27877

Co-authored-by: Saúl Ibarra Corretgé <s@saghul.net>
2021-03-29 00:25:36 -07:00
Erick Zhao
dd24a4b0f6 fix: make TouchBarPopover and TouchBarGroup work (#27901) (#28411)
* fix: use correct `orderedItem` touchbar property

* fix: correct parent in touchbar group and popover

* fix: preserve property hook order
2021-03-29 00:10:41 -07:00
trop[bot]
bb612d7a05 docs: add missing line in web-contents.md (#28400)
* Update web-contents.md

The text block was rendered as part of the `features` property, not the `handler`

* fix linting

Co-authored-by: Alexander Prinzhorn <alexander@prinzhorn.it>
2021-03-26 12:39:00 -05:00
trop[bot]
cf69f9a4ce fix: disappearing thumbar after win.hide() (#28389)
* fix: disappearing thumbar after win.hide()

* Add descriptive comment

Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2021-03-25 12:16:53 -07:00
Will Anderson
d4eed90145 docs: update Node API renderer example to use contextBridge (#28371) 2021-03-24 19:42:47 -04:00
trop[bot]
8f05f313ce fix: isolate Pepper plugins (#28373)
* fix: isolate Pepper plugins

Following suit with a recent change to the same method in Chromium, we
should also isloate Pepper plugins.

* docs: add more context to comment

* fix: remove unsupported test flag behavior

Co-authored-by: clavin <cwatford@slack-corp.com>
2021-03-24 19:31:07 -04:00
trop[bot]
592a1aed0f doc: desktopCapturer menu position (#28363)
desktopCapturer can be used in both main process and renderer process

Co-authored-by: liulun <xland@live.cn>
2021-03-24 16:59:21 +09:00
Erick Zhao
fc2762c66a docs: MessagePorts guide (#27678) (#28357)
Co-authored-by: Jeremy Rose <jeremya@chromium.org>
2021-03-24 10:44:50 +09:00
trop[bot]
9f48ef1c78 fix: make sure service worker scheme is registered with allowServiceWorkers (#28355)
* Fix custom scheme not registered as service worker scheme

* ServiceWorker loaders do not have WebContents associated

* Add test for service worker

* Revert "Fix custom scheme not registered as service worker scheme"

This reverts commit a249235b22.

* Add scheme to ServiceWorkerSchemes

Co-authored-by: Cheng Zhao <zcbenz@gmail.com>
2021-03-24 10:43:20 +09:00
trop[bot]
574b705f22 fix: window.print() in pdf plugin (#28352)
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2021-03-24 10:02:14 +09:00
Electron Bot
17c970b6a2 Bump v12.0.2 2021-03-23 12:19:10 -07:00
trop[bot]
1f4ffe4f68 fix: escape URL passed to shell.openExternal on windows (#28341)
Co-authored-by: Samuel Attard <sattard@slack-corp.com>
2021-03-23 05:15:40 -07:00
trop[bot]
d121bcbbb5 fix: libuv hang on Windows (#28337)
* fix: libuv hang on Windows

* test: add a hang test

Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2021-03-23 03:00:36 -07:00
trop[bot]
d2a342c74d refactor: prefer embedder-focused InitializeNodeWithArgs (#28324)
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2021-03-22 12:37:13 -07:00
trop[bot]
c19e1ee30e fix: DesktopCapturer gc'd prior to capture completion (#28281)
desktopCapture.getSources() returns a promise which should resolve
when capturing finishes. Internally it creates an instance of
DesktopCapturer which is responsible for resolving or rejecting
the promise.

Between the time DesktopCapturer starts capturing frames and when
it finishes, it's possible for its handle to be GC'd leading to
it never resolving.

These changes pin the instance of DesktopCapturer until it either
finishes or errors.

fixes #25595

Co-authored-by: samuelmaddock <samuel.maddock@gmail.com>
2021-03-22 11:02:51 +09:00
trop[bot]
508075f870 fix: drag region offsets in BrowserViews (#28296)
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2021-03-22 10:58:58 +09:00
trop[bot]
c34103d912 test: use new uuid for each ServiceWorker test (#28311)
Co-authored-by: Cheng Zhao <zcbenz@gmail.com>
2021-03-22 10:57:16 +09:00
trop[bot]
7487fe91fe fix: bad menu position when no positioning item specified (#28277)
Co-authored-by: Jeremy Rose <nornagon@nornagon.net>
2021-03-19 10:21:10 +09:00
Will Anderson
7b21bc543b docs: Update Quick Start Guide for Electron 12 (#28227)
* docs: Update Quick Start Guide for Electron 12

With `contextIsolation` enabled by default in Electron 12, the Getting Started Guide no longer works as it is written. In order for the basic example to display values from `process.versions`, we need to add a `preload.js` to the example.

* Trigger Build
2021-03-18 15:12:27 +09:00
trop[bot]
6c09c2c644 docs: document the parameter structure of hookWindowMessage (#28214)
Fixes #28178

Co-authored-by: Samuel Attard <samuel.r.attard@gmail.com>
2021-03-16 15:44:06 -07:00
trop[bot]
44eb30fa71 fix: revert "refactor: mmap asar files (#24470)" (#28202)
This reverts commit 01a2e23194.

Co-authored-by: Jeremy Rose <nornagon@nornagon.net>
2021-03-16 19:21:02 +09:00
Electron Bot
c528ed5a8d chore: bump chromium to 89.0.4389.90 (12-x-y) (#28174)
* chore: bump chromium in DEPS to 89.0.4389.90

* update patches
2021-03-15 14:13:36 -04:00
trop[bot]
15f29aa971 chore: cherry-pick 1fe571a from node (#28109)
* chore: cherry-pick 1fe571a from node

Backports https://github.com/nodejs/node/pull/37000

* Fix merge error

Co-authored-by: deepak1556 <hop2deep@gmail.com>
Co-authored-by: Cheng Zhao <zcbenz@gmail.com>
2021-03-15 11:53:06 -04:00
trop[bot]
312682d655 test: reliably wait for spellchecker to load (#28190)
Co-authored-by: Cheng Zhao <zcbenz@gmail.com>
2021-03-15 00:28:48 -07:00
trop[bot]
8397716dab fix: handle a nil backgroundColor in win.getBackgroundColor() (#28188)
* fix: handle a nil backgroundColor in win.getBackgroundColor()

* spec: add crash case

* fix: update to fix native_views transparent color

* chore: fix lint

Co-authored-by: Samuel Attard <sattard@slack-corp.com>
Co-authored-by: Samuel Attard <sam@electronjs.org>
2021-03-15 11:45:19 +09:00
trop[bot]
23075f8620 fix: convert system colors to device color space in systemPreferences (#28172)
Co-authored-by: Samuel Attard <sattard@slack-corp.com>
2021-03-13 05:01:19 -08:00
Erick Zhao
90d94e468e fix: delay emitting NotifyIcon events on Windows (#26668) (#28111)
* wip?

* attempt to use weakptr

* apply posttask change to other balloon events

* chore: add clarifying comment on weakptr

* refactor: move weakptr include to implementation

(it's not needed in the header file)

* refactor: use default initializer for weak factory

* refactor: move weakptr usage outside of loop

* fix: convert mouse events as well

* refactor: use member function for balloon events

* fix: check if wicon is truthy in callback

* refactor: bind mouse events with member function

* refactor: inline lparams

* refactor: inline getkeyboardmodifiers()

* chore: correct GetKeyboardModifiers typo
2021-03-13 10:47:07 +09:00
trop[bot]
5cc6d79d17 fix: change #if defined(OS_MACOSX) to #if defined(OS_MAC) (#28152)
Co-authored-by: Milan Burda <milan.burda@gmail.com>
2021-03-12 16:43:45 +09:00
trop[bot]
8f825d35f7 docs: fix cookies event documentation for type generation (#28139)
Co-authored-by: Samuel Attard <sattard@slack-corp.com>
2021-03-11 16:22:39 -08:00
Electron Bot
05972074e3 Bump v12.0.1 2021-03-10 13:11:09 -08:00
Keeley Hammond
21ac61270a fix: ensure child window transparency (#28107)
* fix: ensure child window transparency works

Windows opened via window.open and intecepted via setWindowOpenHandler
or the `new-window` event should (a) have the correct background color
and (b) that background color should be transparent if specified.

The changes in api_web_contents fix (a) and the changes in
web_contents_preferences fix (b).

Notes: Child windows with specified background colors or transpency now
work as intended

* fix: set background_color in blink prefs apply logic

* fix: apply changes for 12

* fix: background_color patch simplification

* update patches

Co-authored-by: Samuel Attard <sattard@slack-corp.com>
Co-authored-by: Electron Bot <electron@github.com>
2021-03-10 13:08:44 -08:00
trop[bot]
f0500fae4c fix: capturePage not resolving with hidden windows (#28075)
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2021-03-10 09:38:30 +09:00
trop[bot]
5f2f4182c4 fix: pass IsScreen via parameter instead of sync IPC method (#28080)
Co-authored-by: Cheng Zhao <zcbenz@gmail.com>
2021-03-10 09:21:53 +09:00
Electron Bot
ac8db00a70 chore: bump chromium to 89.0.4389.82 (12-x-y) (#27960)
* chore: bump chromium in DEPS to 89.0.4389.72

* chore: bump chromium in DEPS to 89.0.4389.82
2021-03-09 11:08:06 -08:00
trop[bot]
ab5d0f4c8b chore: remove obsolete native node module patch (#28056)
* chore: remove obsolete native node module patch

* update patches

* Fix merge error

Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
Co-authored-by: Electron Bot <electron@github.com>
Co-authored-by: Cheng Zhao <zcbenz@gmail.com>
2021-03-09 19:51:16 +09:00
trop[bot]
203116867b build: call goma_ctl.py ensure_start directly (#28060)
Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
2021-03-09 16:05:42 +09:00
trop[bot]
67a67270f5 test: ignore the ready event from PDF Viewer (#28049)
Co-authored-by: Cheng Zhao <zcbenz@gmail.com>
2021-03-09 09:11:34 +09:00
trop[bot]
83a3eb64ec docs: setWindowOpenHandler should show object return (#28036)
* Should use object return

* Fix lint

Co-authored-by: Domenic Horner <domenic@tgxn.net>
Co-authored-by: Cheng Zhao <github@zcbenz.com>
2021-03-08 11:21:14 -05:00
trop[bot]
8b1260184a docs: update WebPreferences default values for Electron 12 (#28037)
Updates the values for `contextIsolation` and `worldSafeExecuteJavaScript` for Electron 12.

Co-authored-by: Erick Zhao <erick@hotmail.ca>
2021-03-08 11:07:20 -05:00
trop[bot]
f13ddca55f fix: navigator.setAppBadge/clearAppBadge from a service worker (#28011)
Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
2021-03-08 09:32:50 +09:00
trop[bot]
f1c4265072 chore: Add a condition to crashReporter deprecate log (#28013)
* Add a condition to crashReporter deprecate log

When developer set  submitURL to '' crash reports will be saved  at `...\AppData\Roaming\...\Crashpad\reports`, will not be uploaded to the server.
So  at this time `deprecate.log('Sending uncompressed crash reports....')`  is  unnecessary.

* Update lib/browser/api/crash-reporter.ts

change to check uploadToServer

Co-authored-by: Jeremy Rose <nornagon@nornagon.net>

Co-authored-by: liulun <xland@live.cn>
Co-authored-by: Jeremy Rose <nornagon@nornagon.net>
2021-03-07 16:31:37 +09:00
trop[bot]
f5de5e9131 fix: warning when worldSafeExecuteJavaScript is disabled (#27969)
Co-authored-by: Milan Burda <milan.burda@gmail.com>
2021-03-05 10:15:11 +09:00
trop[bot]
a73949315c test: fix contextIsolation value for later added test (#28005)
Co-authored-by: Cheng Zhao <zcbenz@gmail.com>
2021-03-05 10:03:25 +09:00
trop[bot]
189f7e0e4e feat: expose des-ede3 cipher (#27992)
Co-authored-by: Jeremy Rose <nornagon@nornagon.net>
2021-03-04 15:52:46 -05:00
Robo
2950f03e83 chore: cherry-pick 67fe5a41bff from chromium (#27991)
Backports https://chromium-review.googlesource.com/c/chromium/src/+/2666008
2021-03-04 15:39:59 -05:00
trop[bot]
ca417e435c fix: check web_contents() for destroyed WebContents (#27966)
Co-authored-by: Cheng Zhao <zcbenz@gmail.com>
2021-03-04 17:01:15 +09:00
trop[bot]
5237108396 fix: offset browserview drag regions on macOS (#27988)
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2021-03-04 16:33:11 +09:00
Electron Bot
3ae63c9a06 Bump v12.0.0 2021-03-01 16:47:13 -08:00
trop[bot]
8828382b23 feat: enable context isolation by default (#27949)
* feat: enable context isolation by default

* chore: set default in ctx iso getter

* spec: make all specs work with the new contextIsolation default

* spec: fix affinity specs

* spec: update tests for new ctx iso default

* spec: update tests for new ctx iso default

* spec: update tests for new ctx iso default

* spec: update tests for new ctx iso default

* chore: move stray prod deps to dev deps

* spec: update tests for new ctx iso default

* turn off contextIsolation for visibility tests

* turn off contextIsolation for <webview> tag nodeintegration attribute loads native modules when navigation happens

Co-authored-by: Samuel Attard <samuel.r.attard@gmail.com>
Co-authored-by: Samuel Attard <sattard@slack-corp.com>
Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
2021-03-01 19:35:03 -05:00
trop[bot]
0e714d19c5 fix: ensure owner window valid (#27947)
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2021-03-01 19:33:45 -05:00
Electron Bot
aec412e35d chore: bump chromium to 89.0.4389.69 (12-x-y) (#27907)
* chore: bump chromium in DEPS to 89.0.4389.69

* update patches

Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
2021-03-01 16:48:59 -05:00
John Kleinschmidt
4b2d791212 chore: revert webFrameMain.executeJavaScriptInIsolatedWorld method (#27926) (#27937)
(cherry picked from commit 84d0e827a3)

Co-authored-by: Keeley Hammond <VerteDinde@users.noreply.github.com>
2021-03-01 13:34:40 -08:00
Shelley Vohr
fd629c16cb fix: set WebContents background color ubiquitously #27592 (#27593) (#27942)
Move it from LoadURL to RenderViewCreated which is present
in all window creation cases and is called early enough to be
relevant from user prespective and after RenderWidgetHostView
is already present.

Co-authored-by: marekharanczyk <48673767+marekharanczyk@users.noreply.github.com>
2021-03-01 13:32:35 -08:00
Keeley Hammond
007c960f3c fix: values return from the ctx bridge with dynamic property support should themselves support dynamic properties (#27940)
Co-authored-by: Samuel Attard <sattard@slack-corp.com>
2021-03-01 15:17:47 -05:00
Keeley Hammond
b2636e171a ci: ignore errors deleting user app directories on WOA testing (#27939) 2021-03-01 13:58:34 -05:00
Keeley Hammond
e7e1801443 fix: race-condition in electron.net (#27938) 2021-03-01 13:50:03 -05:00
Keeley Hammond
0baf9997ad fix: navigator.bluetooth.requestDevice (#27927)
* fix: navigator.bluetooth.requestDevice

* remove permission observer methods not implemented in 12-x-y

Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
2021-03-01 13:14:41 -05:00
Electron Bot
e65e989650 Bump v12.0.0-beta.31 2021-03-01 07:00:59 -08:00
Shelley Vohr
26a18c26d7 chore: bump node in DEPS to v14.16.0 (#27911)
* chore: bump node in DEPS to v14.16.0

* bootstrap: refactor to use more primordials

https://github.com/nodejs/node/pull/35999

* chore: update filenames list

Co-authored-by: Electron Bot <electron@github.com>
2021-03-01 20:47:44 +09:00
Electron Bot
a52c88ec4d Bump v12.0.0-beta.30 2021-02-25 07:01:19 -08:00
Erick Zhao
0ee559cd29 fix: cherry-pick 5c7ad5393f74 from chromium (#27598)
* fix: cherry-pick 5c7ad5393f74 from chromium

* patch

* mas fix

Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
2021-02-24 12:44:13 -08:00
trop[bot]
dfed04b71b docs: fix header level of some events in app.md (#27887)
Co-authored-by: Jeremy Rose <jeremya@chromium.org>
2021-02-24 20:36:34 +09:00
trop[bot]
d628fa07b5 fix: cap sendInputEvent text length at n-1 (#27855)
Co-authored-by: Jeremy Rose <nornagon@nornagon.net>
2021-02-24 18:07:27 +09:00
Jeremy Rose
f0c7789544 fix: ECDH.setPrivateKey correctly sets the key (#27688) (#27856)
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2021-02-24 18:06:49 +09:00
trop[bot]
d00e869560 fix: isFullScreen typo (#27864)
* fix isFullScreen typo

* Update lib/browser/api/base-window.ts

Co-authored-by: John Kleinschmidt <jkleinsc@github.com>

Co-authored-by: Tony Wu <tonywoo@fb.com>
Co-authored-by: Tony <TonyWuu@users.noreply.github.com>
Co-authored-by: John Kleinschmidt <jkleinsc@github.com>
2021-02-24 18:05:32 +09:00
Shelley Vohr
b70e42024a fix: libuv hang when nodeIntegrationInSubframes enabled (#27879) 2021-02-24 17:58:32 +09:00
Electron Bot
44adc8ddb4 chore: bump chromium to 89.0.4389.58 (12-x-y) (#27759)
* chore: bump chromium in DEPS to 89.0.4389.47

* chore: bump chromium in DEPS to 89.0.4389.58

* update patches

Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
2021-02-23 16:27:25 -05:00
Electron Bot
9e30fe0f96 Bump v12.0.0-beta.29 2021-02-23 08:35:33 -08:00
Erick Zhao
7180b2b13f docs: remove v5 and v6 modernization docs (#27858) 2021-02-22 12:21:21 -08:00
trop[bot]
c734baf8d4 fix: gather crash data for unexpected helper path (#27828)
Co-authored-by: Jeremy Rose <nornagon@nornagon.net>
2021-02-22 11:42:25 -05:00
trop[bot]
a859436f7a revert: patch libuv to use posix_spawn on macOS (#27026) (#27810)
* Revert "perf: patch libuv to use posix_spawn on macOS (#27026)"

This reverts commit f69c11105f.

* Update .patches

Co-authored-by: VerteDinde <khammond@slack-corp.com>
Co-authored-by: Robo <hop2deep@gmail.com>
2021-02-22 10:06:29 -05:00
Electron Bot
3144f992f7 Bump v12.0.0-beta.28 2021-02-22 07:01:39 -08:00
trop[bot]
98f57a20e7 fix: enableBlinkFeatures warning in webviews (#27790)
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2021-02-19 15:46:36 +09:00
trop[bot]
f6007654f9 fix: don't create last saved path if none exists (#27806)
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2021-02-19 15:44:10 +09:00
trop[bot]
84a4a7a944 fix: restore window event redispatching on mac (#27769)
Co-authored-by: clavin <cwatford@slack-corp.com>
2021-02-19 15:41:35 +09:00
Electron Bot
1b6e3596f2 Bump v12.0.0-beta.27 2021-02-18 07:01:33 -08:00
Eryk Rakowski
573784967c feat: add win.setTopBrowserView() so that BrowserViews can be raised (#27007) (#27713)
* feat: Raise a browser view via `BrowserWindow.setTopBrowserView()`.

This is similar to removing and re-adding a browser view, but avoids a visible flicker as the browser view is not removed from the window when using `setTopBrowserView`. Note: if the given browser view is not attached to the window, it will be added.

This commit contains the macOS implementation.

* feat: setTopBrowserView support for Windows and Linux

* docs: add info about setTopBrowserView

* docs: Clarify behavior when browserView is not yet attached.

* fix: throw en error when browserView is not attached to the window

* fix: build error

* fix: test

* fix: add test case

* fix: tests

* fix: reparenting

* fix: close second window in tests

Co-authored-by: sentialx <sentialx@gmail.com>

Co-authored-by: Stewart Lord <stew@offbynone.com>
2021-02-18 17:09:26 +09:00
trop[bot]
d55b399976 fix: check WebContents before emitting render-process-gone event (#27756)
Co-authored-by: Cheng Zhao <zcbenz@gmail.com>
2021-02-18 10:15:46 +09:00
trop[bot]
b8941d084d fix: pdf viewer missing resources (#27747)
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2021-02-17 13:24:13 -08:00
trop[bot]
afffbadf5b test: fix flaky did-change-theme-color test (#27746)
* test: move did-change-theme-color test to main

* test: enable did-change-theme-color test for WOA

Co-authored-by: Cheng Zhao <zcbenz@gmail.com>
2021-02-17 10:58:56 +09:00
Jeremy Rose
c3bce9c664 feat: implement allowFileAccess loadExtension option (#27702)
Co-authored-by: Сковорода Никита Андреевич <chalkerx@gmail.com>
Co-authored-by: Samuel Maddock <samuel.maddock@gmail.com>
2021-02-16 15:20:20 -08:00
Electron Bot
33f6ff40fc chore: bump chromium to 89.0.4389.47 (12-x-y) (#27591)
Co-authored-by: Charles Kerr <charles@charleskerr.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
Co-authored-by: Jeremy Rose <nornagon@nornagon.net>
2021-02-16 15:17:43 -08:00
Keeley Hammond
777f23af0d feat: add display-capture api to session permissions (#27696) 2021-02-16 08:00:15 -08:00
Electron Bot
f6992db54b Bump v12.0.0-beta.26 2021-02-15 07:01:13 -08:00
trop[bot]
8cdd20e97a feat: add exit code to render-process-gone details (#27677)
Co-authored-by: Jeremy Rose <nornagon@nornagon.net>
2021-02-15 09:39:49 +09:00
trop[bot]
962f1aa7d4 fix: crash in crypto.createDiffieHellman (#27700)
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2021-02-11 11:04:27 -05:00
Electron Bot
0961044dc8 Bump v12.0.0-beta.25 2021-02-11 07:03:07 -08:00
trop[bot]
e1f06510f8 refactor: load preload script directly as a string (#27661)
Co-authored-by: Milan Burda <milan.burda@gmail.com>
2021-02-10 10:16:25 -06:00
trop[bot]
b6bdbcf485 chore: cherry-pick 0c8b6e41 from v8 (#27685)
* chore: cherry-pick 0c8b6e41 from v8

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

* update patches

* update patches

Co-authored-by: deepak1556 <hop2deep@gmail.com>
Co-authored-by: Electron Bot <electron@github.com>
2021-02-09 20:55:49 -08:00
trop[bot]
417230a67a perf: patch libuv to use posix_spawn on macOS (#27656)
* perf: patch libuv to use posix_spawn on macOS

patch libuv to fix a performance regression in macOS >= 11

Spawning child processes in an Electron application with a hardened
runtime has become slow in macOS Big Sur. This patch is a squashed
version of https://github.com/libuv/libuv/pull/3064

This patch should be removed when libuv PR 3064 is merged.

Fixes: https://github.com/libuv/libuv/issues/3050
Fixes: https://github.com/electron/electron/issues/26143
PR-URL: https://github.com/libuv/libuv/pull/3064

Authored-by: Juan Pablo Canepa <jpcanepa@gmail.com>
Co-authored-by: Marcello Bastéa-Forte <marcello@descript.com>
Electron patch prepared by: Pat DeSantis <pdesantis3@gmail.com>

* Remove trailing whitespaces from patch file

* update patches

* Update patch description

Co-authored-by: Pat DeSantis <pdesantis3@gmail.com>
Co-authored-by: Electron Bot <electron@github.com>
2021-02-09 20:52:23 -08:00
Shelley Vohr
fe876bd55b fix: BrowserView rendering flicker (#27658) 2021-02-09 15:05:40 -05:00
298 changed files with 14495 additions and 4122 deletions

View File

@@ -308,9 +308,10 @@ step-setup-goma-for-build: &step-setup-goma-for-build
npm install
mkdir third_party
node -e "require('./src/utils/goma.js').downloadAndPrepare({ gomaOneForAll: true })"
node -e "require('./src/utils/goma.js').ensure()"
third_party/goma/goma_ctl.py ensure_start
echo 'export GN_GOMA_FILE='`node -e "console.log(require('./src/utils/goma.js').gnFilePath)"` >> $BASH_ENV
echo 'export LOCAL_GOMA_DIR='`node -e "console.log(require('./src/utils/goma.js').dir)"` >> $BASH_ENV
echo 'export GOMA_FALLBACK_ON_AUTH_FAILURE=true' >> $BASH_ENV
cd ..
step-restore-brew-cache: &step-restore-brew-cache

View File

@@ -4,4 +4,3 @@
APPVEYOR_CLOUD_TOKEN=
CIRCLE_TOKEN=
ELECTRON_GITHUB_TOKEN=
VSTS_TOKEN=

4
.gitignore vendored
View File

@@ -68,4 +68,6 @@ ts-gen
.depshash-target
# Used to accelerate builds after sync
patches/mtime-cache.json
patches/mtime-cache.json
spec/fixtures/logo.png

View File

@@ -648,6 +648,7 @@ source_set("electron_lib") {
}
if (enable_pdf_viewer) {
deps += [
"//chrome/browser/resources/pdf:pdf_resources",
"//components/pdf/browser",
"//components/pdf/renderer",
"//pdf:pdf_ppapi",

4
DEPS
View File

@@ -14,9 +14,9 @@ gclient_gn_args = [
vars = {
'chromium_version':
'89.0.4388.2',
'89.0.4389.128',
'node_version':
'v14.15.1',
'v14.16.0',
'nan_version':
'2c4ee8a32a299eada3cd6e468bbd0a473bfea96d',
'squirrel.mac_version':

View File

@@ -1 +1 @@
12.0.0-beta.24
12.0.5

View File

@@ -36,6 +36,7 @@ environment:
ELECTRON_ENABLE_STACK_DUMPING: 1
MOCHA_REPORTER: mocha-multi-reporters
MOCHA_MULTI_REPORTERS: mocha-appveyor-reporter, tap
GOMA_FALLBACK_ON_AUTH_FAILURE: true
notifications:
- provider: Webhook
url: https://electron-mission-control.herokuapp.com/rest/appveyor-hook

View File

@@ -93,6 +93,6 @@ steps:
condition: always()
- powershell: |
Remove-Item -path $env:APPDATA/Electron* -Recurse -Force
Remove-Item -path $env:APPDATA/Electron* -Recurse -Force -ErrorAction Ignore
displayName: 'Delete user app data directories'
condition: always()

View File

@@ -163,7 +163,7 @@ if ((globalThis.process || binding.process).argv.includes("--profile-electron-in
setImmediate: false
},
optimization: {
minimize: true,
minimize: env.mode === 'production',
minimizer: [
new TerserPlugin({
terserOptions: {

View File

@@ -22,6 +22,11 @@ template("webpack_build") {
"//electron/typings/internal-electron.d.ts",
] + invoker.inputs
mode = "development"
if (is_official_build) {
mode = "production"
}
args = [
"--config",
rebase_path(invoker.config_file),
@@ -29,6 +34,7 @@ template("webpack_build") {
"--output-path=" + rebase_path(get_path_info(invoker.out_file, "dir")),
"--env.buildflags=" +
rebase_path("$target_gen_dir/buildflags/buildflags.h"),
"--env.mode=" + mode,
]
deps += [ "buildflags" ]

View File

@@ -91,11 +91,6 @@ These individual tutorials expand on topics discussed in the guide above.
* Electron Releases & Developer Feedback
* [Versioning Policy](tutorial/electron-versioning.md)
* [Release Timelines](tutorial/electron-timelines.md)
* [Packaging App Source Code with asar](tutorial/application-packaging.md)
* [Generating asar Archives](tutorial/application-packaging.md#generating-asar-archives)
* [Using asar Archives](tutorial/application-packaging.md#using-asar-archives)
* [Limitations](tutorial/application-packaging.md#limitations-of-the-node-api)
* [Adding Unpacked Files to asar Archives](tutorial/application-packaging.md#adding-unpacked-files-to-asar-archives)
* [Testing Widevine CDM](tutorial/testing-widevine-cdm.md)
---
@@ -149,15 +144,14 @@ These individual tutorials expand on topics discussed in the guide above.
### Modules for the Renderer Process (Web Page):
* [contextBridge](api/context-bridge.md)
* [desktopCapturer](api/desktop-capturer.md)
* [ipcRenderer](api/ipc-renderer.md)
* [remote](api/remote.md)
* [webFrame](api/web-frame.md)
### Modules for Both Processes:
* [clipboard](api/clipboard.md)
* [crashReporter](api/crash-reporter.md)
* [desktopCapturer](api/desktop-capturer.md)
* [nativeImage](api/native-image.md)
* [shell](api/shell.md)

View File

@@ -391,7 +391,7 @@ which contains more information about why the render process disappeared. It
isn't always because it crashed. The `killed` boolean can be replaced by
checking `reason === 'killed'` when you switch to that event.
#### Event: 'render-process-gone'
### Event: 'render-process-gone'
Returns:
@@ -406,11 +406,14 @@ Returns:
* `oom` - Process ran out of memory
* `launch-failed` - Process never successfully launched
* `integrity-failure` - Windows code integrity checks failed
* `exitCode` Integer - The exit code of the process, unless `reason` is
`launch-failed`, in which case `exitCode` will be a platform-specific
launch failure error code.
Emitted when the renderer process unexpectedly disappears. This is normally
because it was crashed or killed.
#### Event: 'child-process-gone'
### Event: 'child-process-gone'
Returns:
@@ -926,6 +929,10 @@ re-add a removed item to a custom category earlier than that will result in the
entire custom category being omitted from the Jump List. The list of removed
items can be obtained using `app.getJumpListSettings()`.
**Note:** The maximum length of a Jump List item's `description` property is
260 characters. Beyond this limit, the item will not be added to the Jump
List, nor will it be displayed.
Here's a very simple example of creating a custom Jump List:
```javascript

View File

@@ -265,7 +265,7 @@ It creates a new `BrowserWindow` with native properties as set by the `options`.
be the absolute file path to the script.
When node integration is turned off, the preload script can reintroduce
Node global symbols back to the global scope. See example
[here](process.md#event-loaded).
[here](context-bridge.md#exposing-node-global-symbols).
* `sandbox` Boolean (optional) - If set, this will sandbox the renderer
associated with the window, making it compatible with the Chromium
OS-level sandbox and disabling the Node.js engine. This is not the same as
@@ -337,7 +337,7 @@ It creates a new `BrowserWindow` with native properties as set by the `options`.
more details.
* `contextIsolation` Boolean (optional) - Whether to run Electron APIs and
the specified `preload` script in a separate JavaScript context. Defaults
to `false`. The context that the `preload` script runs in will only have
to `true`. The context that the `preload` script runs in will only have
access to its own dedicated `document` and `window` globals, as well as
its own set of JavaScript builtins (`Array`, `Object`, `JSON`, etc.),
which are all invisible to the loaded content. The Electron API will only
@@ -349,8 +349,7 @@ It creates a new `BrowserWindow` with native properties as set by the `options`.
context in the dev tools by selecting the 'Electron Isolated Context'
entry in the combo box at the top of the Console tab.
* `worldSafeExecuteJavaScript` Boolean (optional) - If true, values returned from `webFrame.executeJavaScript` will be sanitized to ensure JS values
can't unsafely cross between worlds when using `contextIsolation`. The default
is `false`. In Electron 12, the default will be changed to `true`. _Deprecated_
can't unsafely cross between worlds when using `contextIsolation`. Defaults to `true`. _Deprecated_
* `nativeWindowOpen` Boolean (optional) - Whether to use native
`window.open()`. Defaults to `false`. Child windows will always have node
integration disabled unless `nodeIntegrationInSubFrames` is true. **Note:** This option is currently
@@ -735,7 +734,7 @@ The method will also not return if the extension's manifest is missing or incomp
is emitted.
**Note:** This method is deprecated. Instead, use
[`ses.loadExtension(path)`](session.md#sesloadextensionpath).
[`ses.loadExtension(path)`](session.md#sesloadextensionpath-options).
#### `BrowserWindow.removeExtension(name)` _Deprecated_
@@ -777,7 +776,7 @@ The method will also not return if the extension's manifest is missing or incomp
is emitted.
**Note:** This method is deprecated. Instead, use
[`ses.loadExtension(path)`](session.md#sesloadextensionpath).
[`ses.loadExtension(path)`](session.md#sesloadextensionpath-options).
#### `BrowserWindow.removeDevToolsExtension(name)` _Deprecated_
@@ -1405,6 +1404,8 @@ The native type of the handle is `HWND` on Windows, `NSView*` on macOS, and
* `message` Integer
* `callback` Function
* `wParam` any - The `wParam` provided to the WndProc
* `lParam` any - The `lParam` provided to the WndProc
Hooks a windows message. The `callback` is called when
the message is received in the WndProc.
@@ -1457,7 +1458,7 @@ Returns `Boolean` - Whether the window's document has been edited.
Returns `Promise<NativeImage>` - Resolves with a [NativeImage](native-image.md)
Captures a snapshot of the page within `rect`. Omitting `rect` will capture the whole visible page.
Captures a snapshot of the page within `rect`. Omitting `rect` will capture the whole visible page. If the page is not visible, `rect` may be empty.
#### `win.loadURL(url[, options])`
@@ -1867,6 +1868,13 @@ Replacement API for setBrowserView supporting work with multi browser views.
* `browserView` [BrowserView](browser-view.md)
#### `win.setTopBrowserView(browserView)` _Experimental_
* `browserView` [BrowserView](browser-view.md)
Raises `browserView` above other `BrowserView`s attached to `win`.
Throws an error if `browserView` is not attached to `win`.
#### `win.getBrowserViews()` _Experimental_
Returns `BrowserView[]` - an array of all BrowserViews that have been attached

View File

@@ -80,6 +80,12 @@ This switch can not be used in `app.commandLine.appendSwitch` since it is parsed
earlier than user's app is loaded, but you can set the `ELECTRON_ENABLE_LOGGING`
environment variable to achieve the same effect.
## --force-fieldtrials=`trials`
Field trials to be forcefully enabled or disabled.
For example: `WebRTC-Audio-Red-For-Opus/Enabled/`
### --host-rules=`rules`
A comma-separated list of `rules` that control how hostnames are mapped.

View File

@@ -33,7 +33,7 @@ page you load in your renderer executes code in this world.
### Isolated World
When `contextIsolation` is enabled in your `webPreferences`, your `preload` scripts run in an
When `contextIsolation` is enabled in your `webPreferences` (this is the default behavior since Electron 12.0.0), your `preload` scripts run in an
"Isolated World". You can read more about context isolation and what it affects in the
[security](../tutorial/security.md#3-enable-context-isolation-for-remote-content) docs.
@@ -109,3 +109,22 @@ has been included below for completeness:
| `Symbol` | N/A | ❌ | ❌ | Symbols cannot be copied across contexts so they are dropped |
If the type you care about is not in the above table, it is probably not supported.
### Exposing Node Global Symbols
The `contextBridge` can be used by the preload script to give your renderer access to Node APIs.
The table of supported types described above also applies to Node APIs that you expose through `contextBridge`.
Please note that many Node APIs grant access to local system resources.
Be very cautious about which globals and APIs you expose to untrusted remote content.
```javascript
const { contextBridge } = require('electron')
const crypto = require('crypto')
contextBridge.exposeInMainWorld('nodeCrypto', {
sha256sum (data) {
const hash = crypto.createHash('sha256')
hash.update(data)
return hash.digest('hex')
}
})
```

View File

@@ -45,6 +45,8 @@ The following events are available on instances of `Cookies`:
#### Event: 'changed'
Returns:
* `event` Event
* `cookie` [Cookie](structures/cookie.md) - The cookie that was changed.
* `cause` String - The cause of the change with one of the following values:

View File

@@ -15,7 +15,7 @@ extension capabilities.
Electron only supports loading unpacked extensions (i.e., `.crx` files do not
work). Extensions are installed per-`session`. To load an extension, call
[`ses.loadExtension`](session.md#sesloadextensionpath):
[`ses.loadExtension`](session.md#sesloadextensionpath-options):
```js
const { session } = require('electron')

View File

@@ -82,8 +82,11 @@ win.show()
* The `blur` filter only applies to the web page, so there is no way to apply
blur effect to the content below the window (i.e. other applications open on
the user's system).
* On Windows operating systems, transparent windows will not work when DWM is
* The window will not be transparent when DevTools is opened.
* On Windows operating systems,
* transparent windows will not work when DWM is
disabled.
* transparent windows can not be maximized using the Windows system menu or by double clicking the title bar. The reasoning behind this can be seen on [this pull request](https://github.com/electron/electron/pull/28207).
* On Linux, users have to put `--enable-transparent-visuals --disable-gpu` in
the command line to disable GPU and allow ARGB to make transparent window,
this is caused by an upstream bug that [alpha channel doesn't work on some

View File

@@ -1,10 +0,0 @@
## Modernization
The Electron team is currently undergoing an initiative to modernize our API in a few concrete ways. These include: updating our modules to use idiomatic JS properties instead of separate `getPropertyX` and `setPropertyX`, converting callbacks to promises, and removing some other anti-patterns present in our APIs. The current status of the Promise initiative can be tracked in the [promisification](promisification.md) tracking file.
As we work to perform these updates, we seek to create the least disruptive amount of change at any given time, so as many changes as possible will be introduced in a backward compatible manner and deprecated after enough time has passed to give users a chance to upgrade their API calls.
This document and its child documents will be updated to reflect the latest status of our API changes.
* [Promisification](promisification.md)
* [Property Updates](property-updates.md)

View File

@@ -1,42 +0,0 @@
## Promisification
The Electron team recently underwent an initiative to convert callback-based APIs to Promise-based ones. See converted functions below:
- [app.getFileIcon(path[, options], callback)](https://github.com/electron/electron/blob/master/docs/api/app.md#getFileIcon)
- [contents.capturePage([rect, ]callback)](https://github.com/electron/electron/blob/master/docs/api/web-contents.md#capturePage)
- [contents.executeJavaScript(code[, userGesture, callback])](https://github.com/electron/electron/blob/master/docs/api/web-contents.md#executeJavaScript)
- [contents.printToPDF(options, callback)](https://github.com/electron/electron/blob/master/docs/api/web-contents.md#printToPDF)
- [contents.savePage(fullPath, saveType, callback)](https://github.com/electron/electron/blob/master/docs/api/web-contents.md#savePage)
- [contentTracing.getCategories(callback)](https://github.com/electron/electron/blob/master/docs/api/content-tracing.md#getCategories)
- [contentTracing.startRecording(options, callback)](https://github.com/electron/electron/blob/master/docs/api/content-tracing.md#startRecording)
- [contentTracing.stopRecording(resultFilePath, callback)](https://github.com/electron/electron/blob/master/docs/api/content-tracing.md#stopRecording)
- [contentTracing.getTraceBufferUsage(callback)](https://github.com/electron/electron/blob/master/docs/api/content-tracing.md#getTraceBufferUsage)
- [cookies.flushStore(callback)](https://github.com/electron/electron/blob/master/docs/api/cookies.md#flushStore)
- [cookies.get(filter, callback)](https://github.com/electron/electron/blob/master/docs/api/cookies.md#get)
- [cookies.remove(url, name, callback)](https://github.com/electron/electron/blob/master/docs/api/cookies.md#remove)
- [cookies.set(details, callback)](https://github.com/electron/electron/blob/master/docs/api/cookies.md#set)
- [debugger.sendCommand(method[, commandParams, callback])](https://github.com/electron/electron/blob/master/docs/api/debugger.md#sendCommand)
- [desktopCapturer.getSources(options, callback)](https://github.com/electron/electron/blob/master/docs/api/desktop-capturer.md#getSources)
- [dialog.showOpenDialog([browserWindow, ]options[, callback])](https://github.com/electron/electron/blob/master/docs/api/dialog.md#showOpenDialog)
- [dialog.showSaveDialog([browserWindow, ]options[, callback])](https://github.com/electron/electron/blob/master/docs/api/dialog.md#showSaveDialog)
- [inAppPurchase.purchaseProduct(productID, quantity, callback)](https://github.com/electron/electron/blob/master/docs/api/in-app-purchase.md#purchaseProduct)
- [inAppPurchase.getProducts(productIDs, callback)](https://github.com/electron/electron/blob/master/docs/api/in-app-purchase.md#getProducts)
- [dialog.showMessageBox([browserWindow, ]options[, callback])](https://github.com/electron/electron/blob/master/docs/api/dialog.md#showMessageBox)
- [dialog.showCertificateTrustDialog([browserWindow, ]options, callback)](https://github.com/electron/electron/blob/master/docs/api/dialog.md#showCertificateTrustDialog)
- [netLog.stopLogging([callback])](https://github.com/electron/electron/blob/master/docs/api/net-log.md#stopLogging)
- [protocol.isProtocolHandled(scheme, callback)](https://github.com/electron/electron/blob/master/docs/api/protocol.md#isProtocolHandled)
- [ses.clearHostResolverCache([callback])](https://github.com/electron/electron/blob/master/docs/api/session.md#clearHostResolverCache)
- [ses.clearStorageData([options, callback])](https://github.com/electron/electron/blob/master/docs/api/session.md#clearStorageData)
- [ses.setProxy(config, callback)](https://github.com/electron/electron/blob/master/docs/api/session.md#setProxy)
- [ses.resolveProxy(url, callback)](https://github.com/electron/electron/blob/master/docs/api/session.md#resolveProxy)
- [ses.getCacheSize(callback)](https://github.com/electron/electron/blob/master/docs/api/session.md#getCacheSize)
- [ses.clearAuthCache(options[, callback])](https://github.com/electron/electron/blob/master/docs/api/session.md#clearAuthCache)
- [ses.clearCache(callback)](https://github.com/electron/electron/blob/master/docs/api/session.md#clearCache)
- [ses.getBlobData(identifier, callback)](https://github.com/electron/electron/blob/master/docs/api/session.md#getBlobData)
- [shell.openExternal(url[, options, callback])](https://github.com/electron/electron/blob/master/docs/api/shell.md#openExternal)
- [webFrame.executeJavaScript(code[, userGesture, callback])](https://github.com/electron/electron/blob/master/docs/api/web-frame.md#executeJavaScript)
- [webFrame.executeJavaScriptInIsolatedWorld(worldId, scripts[, userGesture, callback])](https://github.com/electron/electron/blob/master/docs/api/web-frame.md#executeJavaScriptInIsolatedWorld)
- [webviewTag.capturePage([rect, ]callback)](https://github.com/electron/electron/blob/master/docs/api/webview-tag.md#capturePage)
- [webviewTag.executeJavaScript(code[, userGesture, callback])](https://github.com/electron/electron/blob/master/docs/api/webview-tag.md#executeJavaScript)
- [webviewTag.printToPDF(options, callback)](https://github.com/electron/electron/blob/master/docs/api/webview-tag.md#printToPDF)
- [win.capturePage([rect, ]callback)](https://github.com/electron/electron/blob/master/docs/api/browser-window.md#capturePage)

View File

@@ -1,41 +0,0 @@
## Property Updates
The Electron team is currently undergoing an initiative to convert separate getter and setter functions in Electron to bespoke properties with `get` and `set` functionality. During this transition period, both the new properties and old getters and setters of these functions will work correctly and be documented.
## Candidates
* `BrowserWindow`
* `menubarVisible`
* `crashReporter` module
* `uploadToServer`
* `webFrame` modules
* `zoomFactor`
* `zoomLevel`
* `audioMuted`
* `<webview>`
* `zoomFactor`
* `zoomLevel`
* `audioMuted`
## Converted Properties
* `app` module
* `accessibilitySupport`
* `applicationMenu`
* `badgeCount`
* `name`
* `DownloadItem` class
* `savePath`
* `BrowserWindow` module
* `autoHideMenuBar`
* `resizable`
* `maximizable`
* `minimizable`
* `fullscreenable`
* `movable`
* `closable`
* `backgroundThrottling`
* `NativeImage`
* `isMacTemplateImage`
* `SystemPreferences` module
* `appLevelAppearance`

View File

@@ -42,19 +42,6 @@ In sandboxed renderers the `process` object contains only a subset of the APIs:
Emitted when Electron has loaded its internal initialization script and is
beginning to load the web page or the main script.
It can be used by the preload script to add removed Node global symbols back to
the global scope when node integration is turned off:
```javascript
// preload.js
const _setImmediate = setImmediate
const _clearImmediate = clearImmediate
process.once('loaded', () => {
global.setImmediate = _setImmediate
global.clearImmediate = _clearImmediate
})
```
## Properties
### `process.defaultApp` _Readonly_

View File

@@ -492,6 +492,7 @@ win.webContents.session.setCertificateVerifyProc((request, callback) => {
* `permission` String - The type of requested permission.
* `clipboard-read` - Request access to read from the clipboard.
* `media` - Request access to media devices such as camera, microphone and speakers.
* `display-capture` - Request access to capture the screen.
* `mediaKeySystem` - Request access to DRM protected content.
* `geolocation` - Request access to user's current location.
* `notifications` - Request notification creation and the ability to display them in the user's system tray.
@@ -742,9 +743,13 @@ will not work on non-persistent (in-memory) sessions.
**Note:** On macOS and Windows 10 this word will be removed from the OS custom dictionary as well
#### `ses.loadExtension(path)`
#### `ses.loadExtension(path[, options])`
* `path` String - Path to a directory containing an unpacked Chrome extension
* `options` Object (optional)
* `allowFileAccess` Boolean - Whether to allow the extension to read local files over `file://`
protocol and inject content scripts into `file://` pages. This is required e.g. for loading
devtools extensions on `file://` URLs. Defaults to false.
Returns `Promise<Extension>` - resolves when the extension is loaded.
@@ -767,7 +772,11 @@ const { app, session } = require('electron')
const path = require('path')
app.on('ready', async () => {
await session.defaultSession.loadExtension(path.join(__dirname, 'react-devtools'))
await session.defaultSession.loadExtension(
path.join(__dirname, 'react-devtools'),
// allowFileAccess is required to load the devtools extension on file:// URLs.
{ allowFileAccess: true }
)
// Note that in order to use the React DevTools extension, you'll need to
// download and unzip a copy of the extension.
})

View File

@@ -19,3 +19,7 @@
property set then its `type` is assumed to be `tasks`. If the `name` property
is set but the `type` property is omitted then the `type` is assumed to be
`custom`.
**Note:** The maximum length of a Jump List item's `description` property is
260 characters. Beyond this limit, the item will not be added to the Jump
List, nor will it be displayed.

View File

@@ -17,7 +17,7 @@
* `title` String (optional) - The text to be displayed for the item in the Jump List.
Should only be set if `type` is `task`.
* `description` String (optional) - Description of the task (displayed in a tooltip).
Should only be set if `type` is `task`.
Should only be set if `type` is `task`. Maximum length 260 characters.
* `iconPath` String (optional) - The absolute path to an icon to be displayed in a
Jump List, which can be an arbitrary resource file that contains an icon
(e.g. `.ico`, `.exe`, `.dll`). You can usually specify `process.execPath` to

View File

@@ -1,6 +1,6 @@
# UploadFile Object
* `type` String - `file`.
* `type` 'file' - `file`.
* `filePath` String - Path of file to be uploaded.
* `offset` Integer - Defaults to `0`.
* `length` Integer - Number of bytes to read from `offset`.

View File

@@ -1,4 +1,4 @@
# UploadRawData Object
* `type` String - `rawData`.
* `type` 'rawData' - `rawData`.
* `bytes` Buffer - Data to be uploaded.

View File

@@ -130,6 +130,8 @@ This is necessary for events such as `NSUserDefaultsDidChangeNotification`.
* `userInfo` Record<String, unknown>
* `object` String
Returns `Number` - The ID of this subscription
Same as `subscribeNotification`, but uses `NSWorkspace.sharedWorkspace.notificationCenter`.
This is necessary for events such as `NSWorkspaceDidActivateApplicationNotification`.

View File

@@ -402,6 +402,9 @@ Returns:
* `oom` - Process ran out of memory
* `launch-failed` - Process never successfully launched
* `integrity-failure` - Windows code integrity checks failed
* `exitCode` Integer - The exit code of the process, unless `reason` is
`launch-failed`, in which case `exitCode` will be a platform-specific
launch failure error code.
Emitted when the renderer process unexpectedly disappears. This is normally
because it was crashed or killed.
@@ -1166,6 +1169,7 @@ Ignore application menu shortcuts while this web contents is focused.
* `url` String - The _resolved_ version of the URL passed to `window.open()`. e.g. opening a window with `window.open('foo')` will yield something like `https://the-origin/the/current/path/foo`.
* `frameName` String - Name of the window provided in `window.open()`
* `features` String - Comma separated list of window features provided to `window.open()`.
Returns `{action: 'deny'} | {action: 'allow', overrideBrowserWindowOptions?: BrowserWindowConstructorOptions}` - `deny` cancels the creation of the new
window. `allow` will allow the new window to be created. Specifying `overrideBrowserWindowOptions` allows customization of the created window.
Returning an unrecognized value such as a null, undefined, or an object

View File

@@ -86,17 +86,6 @@ In the browser window some HTML APIs like `requestFullScreen` can only be
invoked by a gesture from the user. Setting `userGesture` to `true` will remove
this limitation.
#### `frame.executeJavaScriptInIsolatedWorld(worldId, code[, 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.
* `code` String
* `userGesture` Boolean (optional) - Default is `false`.
Returns `Promise<unknown>` - A promise that resolves with the result of the executed
code or is rejected if execution throws or results in a rejected promise.
Works like `executeJavaScript` but evaluates `scripts` in an isolated context.
#### `frame.reload()`
Returns `boolean` - Whether the reload was initiated successfully. Only results in `false` when the frame has no history.

View File

@@ -83,9 +83,9 @@ const mainWindow = new BrowserWindow()
mainWindow.webContents.setWindowOpenHandler(({ url }) => {
if (url.startsWith('https://github.com/')) {
return true
return { action: 'allow' }
}
return false
return { action: 'deny' }
})
mainWindow.webContents.on('did-create-window', (childWindow) => {

View File

@@ -6,14 +6,20 @@ Breaking changes will be documented here, and deprecation warnings added to JS c
This document uses the following convention to categorize breaking changes:
- **API Changed:** An API was changed in such a way that code that has not been updated is guaranteed to throw an exception.
- **Behavior Changed:** The behavior of Electron has changed, but not in such a way that an exception will necessarily be thrown.
- **Default Changed:** Code depending on the old default may break, not necessarily throwing an exception. The old behavior can be restored by explicitly specifying the value.
- **Deprecated:** An API was marked as deprecated. The API will continue to function, but will emit a deprecation warning, and will be removed in a future release.
- **Removed:** An API or feature was removed, and is no longer supported by Electron.
* **API Changed:** An API was changed in such a way that code that has not been updated is guaranteed to throw an exception.
* **Behavior Changed:** The behavior of Electron has changed, but not in such a way that an exception will necessarily be thrown.
* **Default Changed:** Code depending on the old default may break, not necessarily throwing an exception. The old behavior can be restored by explicitly specifying the value.
* **Deprecated:** An API was marked as deprecated. The API will continue to function, but will emit a deprecation warning, and will be removed in a future release.
* **Removed:** An API or feature was removed, and is no longer supported by Electron.
## Planned Breaking API Changes (14.0)
### API Changed: `window.(open)`
The optional parameter `frameName` will no longer set the title of the window. This now follows the specification described by the [native documentation](https://developer.mozilla.org/en-US/docs/Web/API/Window/open#parameters) under the corresponding parameter `windowName`.
If you were using this parameter to set the title of a window, you can instead use [win.setTitle(title)](https://www.electronjs.org/docs/api/browser-window#winsettitletitle).
### Removed: `worldSafeExecuteJavaScript`
In Electron 14, `worldSafeExecuteJavaScript` will be removed. There is no alternative, please
@@ -24,6 +30,28 @@ You will be affected by this change if you use either `webFrame.executeJavaScrip
## Planned Breaking API Changes (13.0)
### API Changed: `session.setPermissionCheckHandler(handler)`
The `handler` methods first parameter was previously always a `webContents`, it can now sometimes be `null`. You should use the `requestingOrigin`, `embeddingOrigin` and `securityOrigin` properties to respond to the permission check correctly. As the `webContents` can be `null` it can no longer be relied on.
```js
// Old code
session.setPermissionCheckHandler((webContents, permission) => {
if (webContents.getURL().startsWith('https://google.com/') && permission === 'notification') {
return true
}
return false
})
// Replace with
session.setPermissionCheckHandler((webContents, permission, requestingOrigin) => {
if (new URL(requestingOrigin).hostname === 'google.com' && permission === 'notification') {
return true
}
return false
})
```
### Removed: `shell.moveItemToTrash()`
The deprecated synchronous `shell.moveItemToTrash()` API has been removed. Use
@@ -36,6 +64,78 @@ shell.moveItemToTrash(path)
shell.trashItem(path).then(/* ... */)
```
### Removed: `BrowserWindow` extension APIs
The deprecated extension APIs have been removed:
* `BrowserWindow.addExtension(path)`
* `BrowserWindow.addDevToolsExtension(path)`
* `BrowserWindow.removeExtension(name)`
* `BrowserWindow.removeDevToolsExtension(name)`
* `BrowserWindow.getExtensions()`
* `BrowserWindow.getDevToolsExtensions()`
Use the session APIs instead:
* `ses.loadExtension(path)`
* `ses.removeExtension(extension_id)`
* `ses.getAllExtensions()`
```js
// Removed in Electron 13
BrowserWindow.addExtension(path)
BrowserWindow.addDevToolsExtension(path)
// Replace with
session.defaultSession.loadExtension(path)
```
```js
// Removed in Electron 13
BrowserWindow.removeExtension(name)
BrowserWindow.removeDevToolsExtension(name)
// Replace with
session.defaultSession.removeExtension(extension_id)
```
```js
// Removed in Electron 13
BrowserWindow.getExtensions()
BrowserWindow.getDevToolsExtensions()
// Replace with
session.defaultSession.getAllExtensions()
```
### Removed: methods in `systemPreferences`
The following `systemPreferences` methods have been deprecated:
* `systemPreferences.isDarkMode()`
* `systemPreferences.isInvertedColorScheme()`
* `systemPreferences.isHighContrastColorScheme()`
Use the following `nativeTheme` properties instead:
* `nativeTheme.shouldUseDarkColors`
* `nativeTheme.shouldUseInvertedColorScheme`
* `nativeTheme.shouldUseHighContrastColors`
```js
// Removed in Electron 13
systemPreferences.isDarkMode()
// Replace with
nativeTheme.shouldUseDarkColors
// Removed in Electron 13
systemPreferences.isInvertedColorScheme()
// Replace with
nativeTheme.shouldUseInvertedColorScheme
// Removed in Electron 13
systemPreferences.isHighContrastColorScheme()
// Replace with
nativeTheme.shouldUseHighContrastColors
```
## Planned Breaking API Changes (12.0)
### Removed: Pepper Flash support
@@ -60,6 +160,9 @@ the previous behavior, `contextIsolation: false` must be specified in WebPrefere
We [recommend having contextIsolation enabled](https://github.com/electron/electron/blob/master/docs/tutorial/security.md#3-enable-context-isolation-for-remote-content) for the security of your application.
Another implication is that `require()` cannot be used in the renderer process unless
`nodeIntegration` is `true` and `contextIsolation` is `false`.
For more details see: https://github.com/electron/electron/issues/23506
### Removed: `crashReporter.getCrashesDirectory()`
@@ -79,12 +182,12 @@ app.getPath('crashDumps')
The following `crashReporter` methods are no longer available in the renderer
process:
- `crashReporter.start`
- `crashReporter.getLastCrashReport`
- `crashReporter.getUploadedReports`
- `crashReporter.getUploadToServer`
- `crashReporter.setUploadToServer`
- `crashReporter.getCrashesDirectory`
* `crashReporter.start`
* `crashReporter.getLastCrashReport`
* `crashReporter.getUploadedReports`
* `crashReporter.getUploadToServer`
* `crashReporter.setUploadToServer`
* `crashReporter.getCrashesDirectory`
They should be called only from the main process.
@@ -135,6 +238,7 @@ shell.trashItem(path).then(/* ... */)
## Planned Breaking API Changes (11.0)
### Removed: `BrowserView.{destroy, fromId, fromWebContents, getAllViews}` and `id` property of `BrowserView`
The experimental APIs `BrowserView.{destroy, fromId, fromWebContents, getAllViews}`
have now been removed. Additionally, the `id` property of `BrowserView`
has also been removed.
@@ -174,12 +278,12 @@ app.getPath('crashDumps')
Calling the following `crashReporter` methods from the renderer process is
deprecated:
- `crashReporter.start`
- `crashReporter.getLastCrashReport`
- `crashReporter.getUploadedReports`
- `crashReporter.getUploadToServer`
- `crashReporter.setUploadToServer`
- `crashReporter.getCrashesDirectory`
* `crashReporter.start`
* `crashReporter.getLastCrashReport`
* `crashReporter.getUploadedReports`
* `crashReporter.getUploadToServer`
* `crashReporter.setUploadToServer`
* `crashReporter.getCrashesDirectory`
The only non-deprecated methods remaining in the `crashReporter` module in the
renderer are `addExtraParameter`, `removeExtraParameter` and `getParameters`.
@@ -221,6 +325,7 @@ We [recommend moving away from the remote
module](https://medium.com/@nornagon/electrons-remote-module-considered-harmful-70d69500f31).
### `protocol.unregisterProtocol`
### `protocol.uninterceptProtocol`
The APIs are now synchronous and the optional callback is no longer needed.
@@ -233,14 +338,23 @@ protocol.unregisterProtocol(scheme)
```
### `protocol.registerFileProtocol`
### `protocol.registerBufferProtocol`
### `protocol.registerStringProtocol`
### `protocol.registerHttpProtocol`
### `protocol.registerStreamProtocol`
### `protocol.interceptFileProtocol`
### `protocol.interceptStringProtocol`
### `protocol.interceptBufferProtocol`
### `protocol.interceptHttpProtocol`
### `protocol.interceptStreamProtocol`
The APIs are now synchronous and the optional callback is no longer needed.
@@ -285,6 +399,7 @@ For more detailed information see [#18397](https://github.com/electron/electron/
### Deprecated: `BrowserWindow` extension APIs
The following extension APIs have been deprecated:
* `BrowserWindow.addExtension(path)`
* `BrowserWindow.addDevToolsExtension(path)`
* `BrowserWindow.removeExtension(name)`
@@ -293,6 +408,7 @@ The following extension APIs have been deprecated:
* `BrowserWindow.getDevToolsExtensions()`
Use the session APIs instead:
* `ses.loadExtension(path)`
* `ses.removeExtension(extension_id)`
* `ses.getAllExtensions()`
@@ -373,7 +489,7 @@ Clone Algorithm][SCA], the same algorithm used to serialize messages for
`postMessage`. This brings about a 2x performance improvement for large
messages, but also brings some breaking changes in behavior.
- Sending Functions, Promises, WeakMaps, WeakSets, or objects containing any
* Sending Functions, Promises, WeakMaps, WeakSets, or objects containing any
such values, over IPC will now throw an exception, instead of silently
converting the functions to `undefined`.
@@ -387,21 +503,21 @@ ipcRenderer.send('channel', { value: 3, someFunction: () => {} })
// => throws Error("() => {} could not be cloned.")
```
- `NaN`, `Infinity` and `-Infinity` will now be correctly serialized, instead
* `NaN`, `Infinity` and `-Infinity` will now be correctly serialized, instead
of being converted to `null`.
- Objects containing cyclic references will now be correctly serialized,
* Objects containing cyclic references will now be correctly serialized,
instead of being converted to `null`.
- `Set`, `Map`, `Error` and `RegExp` values will be correctly serialized,
* `Set`, `Map`, `Error` and `RegExp` values will be correctly serialized,
instead of being converted to `{}`.
- `BigInt` values will be correctly serialized, instead of being converted to
* `BigInt` values will be correctly serialized, instead of being converted to
`null`.
- Sparse arrays will be serialized as such, instead of being converted to dense
* Sparse arrays will be serialized as such, instead of being converted to dense
arrays with `null`s.
- `Date` objects will be transferred as `Date` objects, instead of being
* `Date` objects will be transferred as `Date` objects, instead of being
converted to their ISO string representation.
- Typed Arrays (such as `Uint8Array`, `Uint16Array`, `Uint32Array` and so on)
* Typed Arrays (such as `Uint8Array`, `Uint16Array`, `Uint32Array` and so on)
will be transferred as such, instead of being converted to Node.js `Buffer`.
- Node.js `Buffer` objects will be transferred as `Uint8Array`s. You can
* Node.js `Buffer` objects will be transferred as `Uint8Array`s. You can
convert a `Uint8Array` back to a Node.js `Buffer` by wrapping the underlying
`ArrayBuffer`:
@@ -470,6 +586,7 @@ limits are now fixed at a minimum of 0.25 and a maximum of 5.0, as defined
### Deprecated events in `systemPreferences`
The following `systemPreferences` events have been deprecated:
* `inverted-color-scheme-changed`
* `high-contrast-color-scheme-changed`
@@ -487,11 +604,13 @@ nativeTheme.on('updated', () => { /* ... */ })
### Deprecated: methods in `systemPreferences`
The following `systemPreferences` methods have been deprecated:
* `systemPreferences.isDarkMode()`
* `systemPreferences.isInvertedColorScheme()`
* `systemPreferences.isHighContrastColorScheme()`
Use the following `nativeTheme` properties instead:
* `nativeTheme.shouldUseDarkColors`
* `nativeTheme.shouldUseInvertedColorScheme`
* `nativeTheme.shouldUseHighContrastColors`
@@ -612,6 +731,55 @@ Note that `webkitdirectory` no longer exposes the path to the selected folder.
If you require the path to the selected folder rather than the folder contents,
see the `dialog.showOpenDialog` API ([link](https://github.com/electron/electron/blob/master/docs/api/dialog.md#dialogshowopendialogbrowserwindow-options)).
### API Changed: Callback-based versions of promisified APIs
Electron 5 and Electron 6 introduced Promise-based versions of existing
asynchronous APIs and deprecated their older, callback-based counterparts.
In Electron 7, all deprecated callback-based APIs are now removed.
These functions now only return Promises:
* `app.getFileIcon()` [#15742](https://github.com/electron/electron/pull/15742)
* `app.dock.show()` [#16904](https://github.com/electron/electron/pull/16904)
* `contentTracing.getCategories()` [#16583](https://github.com/electron/electron/pull/16583)
* `contentTracing.getTraceBufferUsage()` [#16600](https://github.com/electron/electron/pull/16600)
* `contentTracing.startRecording()` [#16584](https://github.com/electron/electron/pull/16584)
* `contentTracing.stopRecording()` [#16584](https://github.com/electron/electron/pull/16584)
* `contents.executeJavaScript()` [#17312](https://github.com/electron/electron/pull/17312)
* `cookies.flushStore()` [#16464](https://github.com/electron/electron/pull/16464)
* `cookies.get()` [#16464](https://github.com/electron/electron/pull/16464)
* `cookies.remove()` [#16464](https://github.com/electron/electron/pull/16464)
* `cookies.set()` [#16464](https://github.com/electron/electron/pull/16464)
* `debugger.sendCommand()` [#16861](https://github.com/electron/electron/pull/16861)
* `dialog.showCertificateTrustDialog()` [#17181](https://github.com/electron/electron/pull/17181)
* `inAppPurchase.getProducts()` [#17355](https://github.com/electron/electron/pull/17355)
* `inAppPurchase.purchaseProduct()`[#17355](https://github.com/electron/electron/pull/17355)
* `netLog.stopLogging()` [#16862](https://github.com/electron/electron/pull/16862)
* `session.clearAuthCache()` [#17259](https://github.com/electron/electron/pull/17259)
* `session.clearCache()` [#17185](https://github.com/electron/electron/pull/17185)
* `session.clearHostResolverCache()` [#17229](https://github.com/electron/electron/pull/17229)
* `session.clearStorageData()` [#17249](https://github.com/electron/electron/pull/17249)
* `session.getBlobData()` [#17303](https://github.com/electron/electron/pull/17303)
* `session.getCacheSize()` [#17185](https://github.com/electron/electron/pull/17185)
* `session.resolveProxy()` [#17222](https://github.com/electron/electron/pull/17222)
* `session.setProxy()` [#17222](https://github.com/electron/electron/pull/17222)
* `shell.openExternal()` [#16176](https://github.com/electron/electron/pull/16176)
* `webContents.loadFile()` [#15855](https://github.com/electron/electron/pull/15855)
* `webContents.loadURL()` [#15855](https://github.com/electron/electron/pull/15855)
* `webContents.hasServiceWorker()` [#16535](https://github.com/electron/electron/pull/16535)
* `webContents.printToPDF()` [#16795](https://github.com/electron/electron/pull/16795)
* `webContents.savePage()` [#16742](https://github.com/electron/electron/pull/16742)
* `webFrame.executeJavaScript()` [#17312](https://github.com/electron/electron/pull/17312)
* `webFrame.executeJavaScriptInIsolatedWorld()` [#17312](https://github.com/electron/electron/pull/17312)
* `webviewTag.executeJavaScript()` [#17312](https://github.com/electron/electron/pull/17312)
* `win.capturePage()` [#15743](https://github.com/electron/electron/pull/15743)
These functions now have two forms, synchronous and Promise-based asynchronous:
* `dialog.showMessageBox()`/`dialog.showMessageBoxSync()` [#17298](https://github.com/electron/electron/pull/17298)
* `dialog.showOpenDialog()`/`dialog.showOpenDialogSync()` [#16973](https://github.com/electron/electron/pull/16973)
* `dialog.showSaveDialog()`/`dialog.showSaveDialogSync()` [#17054](https://github.com/electron/electron/pull/17054)
## Planned Breaking API Changes (6.0)
### API Changed: `win.setMenu(null)` is now `win.removeMenu()`
@@ -623,19 +791,6 @@ win.setMenu(null)
win.removeMenu()
```
### API Changed: `contentTracing.getTraceBufferUsage()` is now a promise
```js
// Deprecated
contentTracing.getTraceBufferUsage((percentage, value) => {
// do something
})
// Replace with
contentTracing.getTraceBufferUsage().then(infoObject => {
// infoObject has percentage and value fields
})
```
### API Changed: `electron.screen` in the renderer process should be accessed via `remote`
```js
@@ -774,6 +929,31 @@ webFrame.setSpellCheckProvider('en-US', {
})
```
### API Changed: `webContents.getZoomLevel` and `webContents.getZoomFactor` are now synchronous
`webContents.getZoomLevel` and `webContents.getZoomFactor` no longer take callback parameters,
instead directly returning their number values.
```js
// Deprecated
webContents.getZoomLevel((level) => {
console.log(level)
})
// Replace with
const level = webContents.getZoomLevel()
console.log(level)
```
```js
// Deprecated
webContents.getZoomFactor((factor) => {
console.log(factor)
})
// Replace with
const factor = webContents.getZoomFactor()
console.log(factor)
```
## Planned Breaking API Changes (4.0)
The following list includes the breaking API changes made in Electron 4.0.

View File

@@ -1,6 +1,8 @@
# Build Instructions
Follow the guidelines below for building Electron.
Follow the guidelines below for building **Electron itself**, for the purposes of creating custom Electron binaries. For bundling and distributing your app code with the prebuilt Electron binaries, see the [application distribution][application-distribution] guide.
[application-distribution]: ../tutorial/application-distribution.md
## Platform prerequisites
@@ -86,8 +88,6 @@ $ gclient sync -f
```sh
$ cd src
$ export CHROMIUM_BUILDTOOLS_PATH=`pwd`/buildtools
# this next line is needed only if building with sccache
$ export GN_EXTRA_ARGS="${GN_EXTRA_ARGS} cc_wrapper=\"${PWD}/electron/external_binaries/sccache\""
$ gn gen out/Testing --args="import(\"//electron/build/args/testing.gn\") $GN_EXTRA_ARGS"
```
@@ -141,12 +141,6 @@ This will build all of what was previously 'libchromiumcontent' (i.e. the
`content/` directory of `chromium` and its dependencies, incl. WebKit and V8),
so it will take a while.
To speed up subsequent builds, you can use [sccache][sccache]. Add the GN arg
`cc_wrapper = "sccache"` by running `gn args out/Testing` to bring up an
editor and adding a line to the end of the file.
[sccache]: https://github.com/mozilla/sccache
The built executable will be under `./out/Testing`:
```sh
@@ -189,7 +183,6 @@ Not all combinations of source and target CPU/OS are supported by Chromium.
| Windows x64 | Windows x86 | Automatically tested |
| Linux x64 | Linux x86 | Automatically tested |
If you test other combinations and find them to work, please update this document :)
See the GN reference for allowable values of [`target_os`][target_os values]

View File

@@ -1,6 +1,8 @@
# Build Instructions (Linux)
Follow the guidelines below for building Electron on Linux.
Follow the guidelines below for building **Electron itself** on Linux, for the purposes of creating custom Electron binaries. For bundling and distributing your app code with the prebuilt Electron binaries, see the [application distribution][application-distribution] guide.
[application-distribution]: ../tutorial/application-distribution.md
## Prerequisites
@@ -55,6 +57,15 @@ $ sudo dnf install clang dbus-devel gtk3-devel libnotify-devel \
nss-devel python-dbusmock openjdk-8-jre
```
On Arch Linux / Manjaro, install the following libraries:
```sh
$ sudo pacman -Syu base-devel clang libdbus gtk2 libnotify \
libgnome-keyring alsa-lib libcap libcups libxtst \
libxss nss gcc-multilib curl gperf bison \
python2 python-dbusmock jdk8-openjdk
```
Other distributions may offer similar packages for installation via package
managers such as pacman. Or one can compile from source code.

View File

@@ -1,6 +1,8 @@
# Build Instructions (macOS)
Follow the guidelines below for building Electron on macOS.
Follow the guidelines below for building **Electron itself** on macOS, for the purposes of creating custom Electron binaries. For bundling and distributing your app code with the prebuilt Electron binaries, see the [application distribution][application-distribution] guide.
[application-distribution]: ../tutorial/application-distribution.md
## Prerequisites

View File

@@ -1,6 +1,8 @@
# Build Instructions (Windows)
Follow the guidelines below for building Electron on Windows.
Follow the guidelines below for building **Electron itself** on Windows, for the purposes of creating custom Electron binaries. For bundling and distributing your app code with the prebuilt Electron binaries, see the [application distribution][application-distribution] guide.
[application-distribution]: ../tutorial/application-distribution.md
## Prerequisites

View File

@@ -66,11 +66,11 @@ formatted correctly.
Electron APIs uses the same capitalization scheme as Node.js:
- When the module itself is a class like `BrowserWindow`, use `PascalCase`.
- When the module is a set of APIs, like `globalShortcut`, use `camelCase`.
- When the API is a property of object, and it is complex enough to be in a
* When the module itself is a class like `BrowserWindow`, use `PascalCase`.
* When the module is a set of APIs, like `globalShortcut`, use `camelCase`.
* When the API is a property of object, and it is complex enough to be in a
separate chapter like `win.webContents`, use `mixedCase`.
- For other non-module APIs, use natural titles, like `<webview> Tag` or
* For other non-module APIs, use natural titles, like `<webview> Tag` or
`Process Object`.
When creating a new API, it is preferred to use getters and setters instead of

View File

@@ -33,8 +33,7 @@ contributing, and more. Please use the issue tracker for bugs only!
To submit a bug report:
When opening a new issue in the [`electron/electron` issue tracker](https://github.com/electron/electron/issues/new/choose), users
will be presented with [a template](https://github.com/electron/electron/blob/master/.github/ISSUE_TEMPLATE/Bug_report.md)
that should be filled in.
will be presented with a template that should be filled in.
If you believe that you have found a bug in Electron, please fill out the template
to the best of your ability.

View File

@@ -36,9 +36,9 @@ $ git fetch upstream
Build steps and dependencies differ slightly depending on your operating system.
See these detailed guides on building Electron locally:
* [Building on macOS](https://electronjs.org/docs/development/build-instructions-macos)
* [Building on Linux](https://electronjs.org/docs/development/build-instructions-linux)
* [Building on Windows](https://electronjs.org/docs/development/build-instructions-windows)
* [Building on macOS](build-instructions-macos.md)
* [Building on Linux](build-instructions-linux.md)
* [Building on Windows](build-instructions-windows.md)
Once you've built the project locally, you're ready to start making changes!
@@ -63,7 +63,7 @@ or tests in the `spec/` folder.
Please be sure to run `npm run lint` from time to time on any code changes
to ensure that they follow the project's code style.
See [coding style](https://electronjs.org/docs/development/coding-style) for
See [coding style](coding-style.md) for
more information about best practice when modifying code in different parts of
the project.
@@ -91,29 +91,29 @@ Before a pull request can be merged, it **must** have a pull request title with
Examples of commit messages with semantic prefixes:
- `fix: don't overwrite prevent_default if default wasn't prevented`
- `feat: add app.isPackaged() method`
- `docs: app.isDefaultProtocolClient is now available on Linux`
* `fix: don't overwrite prevent_default if default wasn't prevented`
* `feat: add app.isPackaged() method`
* `docs: app.isDefaultProtocolClient is now available on Linux`
Common prefixes:
- fix: A bug fix
- feat: A new feature
- docs: Documentation changes
- test: Adding missing tests or correcting existing tests
- build: Changes that affect the build system
- ci: Changes to our CI configuration files and scripts
- perf: A code change that improves performance
- refactor: A code change that neither fixes a bug nor adds a feature
- style: Changes that do not affect the meaning of the code (linting)
- vendor: Bumping a dependency like libchromiumcontent or node
* fix: A bug fix
* feat: A new feature
* docs: Documentation changes
* test: Adding missing tests or correcting existing tests
* build: Changes that affect the build system
* ci: Changes to our CI configuration files and scripts
* perf: A code change that improves performance
* refactor: A code change that neither fixes a bug nor adds a feature
* style: Changes that do not affect the meaning of the code (linting)
* vendor: Bumping a dependency like libchromiumcontent or node
Other things to keep in mind when writing a commit message:
1. The first line should:
- contain a short description of the change (preferably 50 characters or less,
* contain a short description of the change (preferably 50 characters or less,
and no more than 72 characters)
- be entirely in lowercase with the exception of proper nouns, acronyms, and
* be entirely in lowercase with the exception of proper nouns, acronyms, and
the words that refer to code, like function/variable names
2. Keep the second line blank.
3. Wrap all other lines at 72 columns.
@@ -144,7 +144,7 @@ master.
### Step 7: Test
Bug fixes and features should always come with tests. A
[testing guide](https://electronjs.org/docs/development/testing) has been
[testing guide](testing.md) has been
provided to make the process easier. Looking at other tests to see how they
should be structured can also help.

View File

@@ -8,9 +8,9 @@
<body>
<h1>Hello World!</h1>
<p>
We are using node <script>document.write(process.versions.node)</script>,
Chrome <script>document.write(process.versions.chrome)</script>,
and Electron <script>document.write(process.versions.electron)</script>.
We are using Node.js <span id="node-version"></span>,
Chromium <span id="chrome-version"></span>,
and Electron <span id="electron-version"></span>.
</p>
</body>
</html>

View File

@@ -1,18 +1,27 @@
const { app, BrowserWindow } = require('electron')
const path = require('path')
function createWindow () {
const win = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
nodeIntegration: true
preload: path.join(__dirname, 'preload.js')
}
})
win.loadFile('index.html')
}
app.whenReady().then(createWindow)
app.whenReady().then(() => {
createWindow()
app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0) {
createWindow()
}
})
})
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
@@ -20,8 +29,3 @@ app.on('window-all-closed', () => {
}
})
app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0) {
createWindow()
}
})

View File

@@ -0,0 +1,11 @@
window.addEventListener('DOMContentLoaded', () => {
const replaceText = (selector, text) => {
const element = document.getElementById(selector)
if (element) element.innerText = text
}
for (const type of ['chrome', 'node', 'electron']) {
replaceText(`${type}-version`, process.versions[type])
}
})

View File

@@ -49,6 +49,7 @@ For API references, there are exceptions to this rule.
* No nesting lists more than 2 levels (due to the markdown renderer).
* All `js` and `javascript` code blocks are linted with
[standard-markdown](https://www.npmjs.com/package/standard-markdown).
* For unordered lists, use asterisks instead of dashes
## Picking words

View File

@@ -43,6 +43,6 @@ If the V8 context crashes, the DevTools will display this message.
`DevTools was disconnected from the page. Once page is reloaded, DevTools will automatically reconnect.`
Chromium logs can be enabled via the `ELECTRON_ENABLE_LOGGING` environment variable. For more information, see the [environment variables documentation](https://www.electronjs.org/docs/api/environment-variables#electron_enable_logging).
Chromium logs can be enabled via the `ELECTRON_ENABLE_LOGGING` environment variable. For more information, see the [environment variables documentation](../api/environment-variables.md#electron_enable_logging).
Alternatively, the command line argument `--enable-logging` can be passed. More information is available in the [command line switches documentation](https://www.electronjs.org/docs/api/command-line-switches#--enable-logging).
Alternatively, the command line argument `--enable-logging` can be passed. More information is available in the [command line switches documentation](../api/command-line-switches.md#--enable-logging).

View File

@@ -1,25 +1,38 @@
# Application Distribution
To distribute your app with Electron, you need to package and rebrand it. The easiest way to do this is to use one of the following third party packaging tools:
## Overview
To distribute your app with Electron, you need to package and rebrand it.
To do this, you can either use specialized tooling or manual approaches.
## With tooling
You can use the following tools to distribute your application:
* [electron-forge](https://github.com/electron-userland/electron-forge)
* [electron-builder](https://github.com/electron-userland/electron-builder)
* [electron-packager](https://github.com/electron/electron-packager)
These tools will take care of all the steps you need to take to end up with a distributable Electron applications, such as packaging your application, rebranding the executable, setting the right icons and optionally creating installers.
These tools will take care of all the steps you need to take to end up with a
distributable Electron application, such as bundling your application,
rebranding the executable, and setting the right icons.
You can check the example of how to package your app with `electron-forge` in
our [Quick Start Guide](quick-start.md#package-and-distribute-the-application).
## Manual distribution
You can also choose to manually get your app ready for distribution. The steps needed to do this are outlined below.
### With prebuilt binaries
To distribute your app with Electron, you need to download Electron's [prebuilt
To distribute your app manually, you need to download Electron's [prebuilt
binaries](https://github.com/electron/electron/releases). Next, the folder
containing your app should be named `app` and placed in Electron's resources
directory as shown in the following examples. Note that the location of
Electron's prebuilt binaries is indicated with `electron/` in the examples
below.
directory as shown in the following examples.
On macOS:
> *NOTE:* the location of Electron's prebuilt binaries is indicated
with `electron/` in the examples below.
*On macOS:*
```plaintext
electron/Electron.app/Contents/Resources/app/
@@ -28,7 +41,7 @@ electron/Electron.app/Contents/Resources/app/
└── index.html
```
On Windows and Linux:
*On Windows and Linux:*
```plaintext
electron/resources/app
@@ -37,47 +50,44 @@ electron/resources/app
└── index.html
```
Then execute `Electron.app` (or `electron` on Linux, `electron.exe` on Windows),
and Electron will start as your app. The `electron` directory will then be
your distribution to deliver to final users.
Then execute `Electron.app` on macOS, `electron` on Linux, or `electron.exe`
on Windows, and Electron will start as your app. The `electron` directory
will then be your distribution to deliver to users.
## Packaging Your App into a File
### With an app source code archive
Apart from shipping your app by copying all of its source files, you can also
package your app into an [asar](https://github.com/electron/asar) archive to avoid
exposing your app's source code to users.
Instead of from shipping your app by copying all of its source files, you can
package your app into an [asar] archive to improve the performance of reading
files on platforms like Windows, if you are not already using a bundler such
as Parcel or Webpack.
To use an `asar` archive to replace the `app` folder, you need to rename the
archive to `app.asar`, and put it under Electron's resources directory like
below, and Electron will then try to read the archive and start from it.
On macOS:
*On macOS:*
```plaintext
electron/Electron.app/Contents/Resources/
└── app.asar
```
On Windows and Linux:
*On Windows and Linux:*
```plaintext
electron/resources/
└── app.asar
```
More details can be found in [Application packaging](application-packaging.md).
You can find more details on how to use `asar` in the
[`electron/asar` repository][asar].
## Rebranding with Downloaded Binaries
### Rebranding with downloaded binaries
After bundling your app into Electron, you will want to rebrand Electron
before distributing it to users.
### Windows
You can rename `electron.exe` to any name you like, and edit its icon and other
information with tools like [rcedit](https://github.com/electron/rcedit).
### macOS
#### macOS
You can rename `Electron.app` to any name you want, and you also have to rename
the `CFBundleDisplayName`, `CFBundleIdentifier` and `CFBundleName` fields in the
@@ -104,60 +114,20 @@ MyApp.app/Contents
   └── MyApp Helper
```
### Linux
#### Windows
You can rename `electron.exe` to any name you like, and edit its icon and other
information with tools like [rcedit](https://github.com/electron/rcedit).
#### Linux
You can rename the `electron` executable to any name you like.
## Rebranding by Rebuilding Electron from Source
### Rebranding by rebuilding Electron from source
It is also possible to rebrand Electron by changing the product name and
building it from source. To do this you need to set the build argument
corresponding to the product name (`electron_product_name = "YourProductName"`)
in the `args.gn` file and rebuild.
### Creating a Custom Electron Fork
Creating a custom fork of Electron is almost certainly not something you will
need to do in order to build your app, even for "Production Level" applications.
Using a tool such as `electron-packager` or `electron-forge` will allow you to
"Rebrand" Electron without having to do these steps.
You need to fork Electron when you have custom C++ code that you have patched
directly into Electron, that either cannot be upstreamed, or has been rejected
from the official version. As maintainers of Electron, we very much would like
to make your scenario work, so please try as hard as you can to get your changes
into the official version of Electron, it will be much much easier on you, and
we appreciate your help.
#### Creating a Custom Release with surf-build
1. Install [Surf](https://github.com/surf-build/surf), via npm:
`npm install -g surf-build@latest`
2. Create a new S3 bucket and create the following empty directory structure:
```sh
- electron/
- symbols/
- dist/
```
3. Set the following Environment Variables:
* `ELECTRON_GITHUB_TOKEN` - a token that can create releases on GitHub
* `ELECTRON_S3_ACCESS_KEY`, `ELECTRON_S3_BUCKET`, `ELECTRON_S3_SECRET_KEY` -
the place where you'll upload Node.js headers as well as symbols
* `ELECTRON_RELEASE` - Set to `true` and the upload part will run, leave unset
and `surf-build` will do CI-type checks, appropriate to run for every
pull request.
* `CI` - Set to `true` or else it will fail
* `GITHUB_TOKEN` - set it to the same as `ELECTRON_GITHUB_TOKEN`
* `SURF_TEMP` - set to `C:\Temp` on Windows to prevent path too long issues
* `TARGET_ARCH` - set to `ia32` or `x64`
4. In `script/upload.py`, you _must_ set `ELECTRON_REPO` to your fork (`MYORG/electron`),
especially if you are a contributor to Electron proper.
5. `surf-build -r https://github.com/MYORG/electron -s YOUR_COMMIT -n 'surf-PLATFORM-ARCH'`
6. Wait a very, very long time for the build to complete.
[asar]: https://github.com/electron/asar

View File

@@ -1,194 +0,0 @@
# Application Packaging
To mitigate [issues](https://github.com/joyent/node/issues/6960) around long
path names on Windows, slightly speed up `require` and conceal your source code
from cursory inspection, you can choose to package your app into an [asar][asar]
archive with little changes to your source code.
Most users will get this feature for free, since it's supported out of the box
by [`electron-packager`][electron-packager], [`electron-forge`][electron-forge],
and [`electron-builder`][electron-builder]. If you are not using any of these
tools, read on.
## Generating `asar` Archives
An [asar][asar] archive is a simple tar-like format that concatenates files
into a single file. Electron can read arbitrary files from it without unpacking
the whole file.
Steps to package your app into an `asar` archive:
### 1. Install the asar Utility
```sh
$ npm install -g asar
```
### 2. Package with `asar pack`
```sh
$ asar pack your-app app.asar
```
## Using `asar` Archives
In Electron there are two sets of APIs: Node APIs provided by Node.js and Web
APIs provided by Chromium. Both APIs support reading files from `asar` archives.
### Node API
With special patches in Electron, Node APIs like `fs.readFile` and `require`
treat `asar` archives as virtual directories, and the files in it as normal
files in the filesystem.
For example, suppose we have an `example.asar` archive under `/path/to`:
```sh
$ asar list /path/to/example.asar
/app.js
/file.txt
/dir/module.js
/static/index.html
/static/main.css
/static/jquery.min.js
```
Read a file in the `asar` archive:
```javascript
const fs = require('fs')
fs.readFileSync('/path/to/example.asar/file.txt')
```
List all files under the root of the archive:
```javascript
const fs = require('fs')
fs.readdirSync('/path/to/example.asar')
```
Use a module from the archive:
```javascript
require('./path/to/example.asar/dir/module.js')
```
You can also display a web page in an `asar` archive with `BrowserWindow`:
```javascript
const { BrowserWindow } = require('electron')
const win = new BrowserWindow()
win.loadURL('file:///path/to/example.asar/static/index.html')
```
### Web API
In a web page, files in an archive can be requested with the `file:` protocol.
Like the Node API, `asar` archives are treated as directories.
For example, to get a file with `$.get`:
```html
<script>
let $ = require('./jquery.min.js')
$.get('file:///path/to/example.asar/file.txt', (data) => {
console.log(data)
})
</script>
```
### Treating an `asar` Archive as a Normal File
For some cases like verifying the `asar` archive's checksum, we need to read the
content of an `asar` archive as a file. For this purpose you can use the built-in
`original-fs` module which provides original `fs` APIs without `asar` support:
```javascript
const originalFs = require('original-fs')
originalFs.readFileSync('/path/to/example.asar')
```
You can also set `process.noAsar` to `true` to disable the support for `asar` in
the `fs` module:
```javascript
const fs = require('fs')
process.noAsar = true
fs.readFileSync('/path/to/example.asar')
```
## Limitations of the Node API
Even though we tried hard to make `asar` archives in the Node API work like
directories as much as possible, there are still limitations due to the
low-level nature of the Node API.
### Archives Are Read-only
The archives can not be modified so all Node APIs that can modify files will not
work with `asar` archives.
### Working Directory Can Not Be Set to Directories in Archive
Though `asar` archives are treated as directories, there are no actual
directories in the filesystem, so you can never set the working directory to
directories in `asar` archives. Passing them as the `cwd` option of some APIs
will also cause errors.
### Extra Unpacking on Some APIs
Most `fs` APIs can read a file or get a file's information from `asar` archives
without unpacking, but for some APIs that rely on passing the real file path to
underlying system calls, Electron will extract the needed file into a
temporary file and pass the path of the temporary file to the APIs to make them
work. This adds a little overhead for those APIs.
APIs that requires extra unpacking are:
* `child_process.execFile`
* `child_process.execFileSync`
* `fs.open`
* `fs.openSync`
* `process.dlopen` - Used by `require` on native modules
### Fake Stat Information of `fs.stat`
The `Stats` object returned by `fs.stat` and its friends on files in `asar`
archives is generated by guessing, because those files do not exist on the
filesystem. So you should not trust the `Stats` object except for getting file
size and checking file type.
### Executing Binaries Inside `asar` Archive
There are Node APIs that can execute binaries like `child_process.exec`,
`child_process.spawn` and `child_process.execFile`, but only `execFile` is
supported to execute binaries inside `asar` archive.
This is because `exec` and `spawn` accept `command` instead of `file` as input,
and `command`s are executed under shell. There is no reliable way to determine
whether a command uses a file in asar archive, and even if we do, we can not be
sure whether we can replace the path in command without side effects.
## Adding Unpacked Files to `asar` Archives
As stated above, some Node APIs will unpack the file to the filesystem when
called. Apart from the performance issues, various anti-virus scanners might
be triggered by this behavior.
As a workaround, you can leave various files unpacked using the `--unpack` option.
In the following example, shared libraries of native Node.js modules will not be
packed:
```sh
$ asar pack app app.asar --unpack *.node
```
After running the command, you will notice that a folder named `app.asar.unpacked`
was created together with the `app.asar` file. It contains the unpacked files
and should be shipped together with the `app.asar` archive.
[asar]: https://github.com/electron/asar
[electron-packager]: https://github.com/electron/electron-packager
[electron-forge]: https://github.com/electron-userland/electron-forge
[electron-builder]: https://github.com/electron-userland/electron-builder

View File

@@ -189,18 +189,18 @@ You can get a code signing certificate from a lot of resellers. Prices vary, so
it may be worth your time to shop around. Popular resellers include:
* [digicert](https://www.digicert.com/code-signing/microsoft-authenticode.htm)
* [Comodo](https://www.comodo.com/landing/ssl-certificate/authenticode-signature/)
* [Sectigo](https://sectigo.com/ssl-certificates-tls/code-signing)
* [GoDaddy](https://au.godaddy.com/web-security/code-signing-certificate)
* Amongst others, please shop around to find one that suits your needs, Google
is your friend 😄
There are a number of tools for signing your packaged app:
- [`electron-winstaller`] will generate an installer for windows and sign it for
* [`electron-winstaller`] will generate an installer for windows and sign it for
you
- [`electron-forge`] can sign installers it generates through the
* [`electron-forge`] can sign installers it generates through the
Squirrel.Windows or MSI targets.
- [`electron-builder`] can sign some of its windows targets
* [`electron-builder`] can sign some of its windows targets
## Windows Store

View File

@@ -19,7 +19,7 @@ the system's dark mode setting. You can do this by using the
If you want to manually switch between light/dark modes, you can do this by
setting the desired mode in the
[themeSource](https://www.electronjs.org/docs/api/native-theme#nativethemethemesource)
[themeSource](../api/native-theme.md#nativethemethemesource)
property of the `nativeTheme` module. This property's value will be propagated
to your Renderer process. Any CSS rules related to `prefers-color-scheme` will
be updated accordingly.
@@ -96,7 +96,7 @@ color scheme, and update the "Current Theme Source" label to `System`.
To add listeners and handlers, add the following lines to the `renderer.js` file:
```js
```javascript
const { ipcRenderer } = require('electron')
document.getElementById('toggle-dark-mode').addEventListener('click', async () => {
@@ -130,7 +130,7 @@ active using the `nativeTheme.shouldUseDarkColors` property, and set the
`themeSource` to the opposite theme.
* Upon receiving `dark-mode:system`, we reset the `themeSource` to `system`.
```js
```javascript
const { app, BrowserWindow, ipcMain, nativeTheme } = require('electron')
function createWindow () {
@@ -154,7 +154,7 @@ function createWindow () {
})
ipcMain.handle('dark-mode:system', () => {
nativeTheme.themeSouce = 'system'
nativeTheme.themeSource = 'system'
})
}
@@ -180,7 +180,7 @@ attribute. The value of `prefers-color-scheme` will follow your
Create a `styles.css` file and add the following lines:
```css
```css fiddle='docs/fiddles/features/macos-dark-mode'
@media (prefers-color-scheme: dark) {
body { background: #333; color: white; }
}

View File

@@ -35,7 +35,6 @@ $ code electron-quick-start
}
```
#### 3. Debugging
Set some breakpoints in `main.js`, and start debugging in the [Debug View](https://code.visualstudio.com/docs/editor/debugging). You should be able to hit the breakpoints.
@@ -84,16 +83,16 @@ $ code electron-quick-start
]
}
```
**Configuration Notes**
- `cppvsdbg` requires the [built-in C/C++ extension](https://marketplace.visualstudio.com/items?itemName=ms-vscode.cpptools) be enabled.
- `${workspaceFolder}` is the full path to Chromium's `src` directory.
- `your-executable-location` will be one of the following depending on a few items:
- `Testing`: If you are using the default settings of [Electron's Build-Tools](https://github.com/electron/build-tools) or the default instructions when [building from source](https://www.electronjs.org/docs/development/build-instructions-gn#building).
- `Release`: If you built a Release build rather than a Testing build.
- `your-directory-name`: If you modified this during your build process from the default, this will be whatever you specified.
- The `args` array string `"your-electron-project-path"` should be the absolute path to either the directory or `main.js` file of the Electron project you are using for testing. In this example, it should be your path to `electron-quick-start`.
* `cppvsdbg` requires the [built-in C/C++ extension](https://marketplace.visualstudio.com/items?itemName=ms-vscode.cpptools) be enabled.
* `${workspaceFolder}` is the full path to Chromium's `src` directory.
* `your-executable-location` will be one of the following depending on a few items:
* `Testing`: If you are using the default settings of [Electron's Build-Tools](https://github.com/electron/build-tools) or the default instructions when [building from source](https://www.electronjs.org/docs/development/build-instructions-gn#building).
* `Release`: If you built a Release build rather than a Testing build.
* `your-directory-name`: If you modified this during your build process from the default, this will be whatever you specified.
* The `args` array string `"your-electron-project-path"` should be the absolute path to either the directory or `main.js` file of the Electron project you are using for testing. In this example, it should be your path to `electron-quick-start`.
#### 3. Debugging

View File

@@ -32,6 +32,7 @@ Using the [React Developer Tools][react-devtools] as an example:
* on macOS it is `~/Library/Application Support/Google/Chrome/Default/Extensions`.
1. Pass the location of the extension to the [`ses.loadExtension`][load-extension]
API. For React Developer Tools `v4.9.0`, it looks something like:
```javascript
const { app, session } = require('electron')
const path = require('path')
@@ -96,7 +97,7 @@ of the extension is not working as expected.
[devtools-extension]: https://developer.chrome.com/extensions/devtools
[session]: ../api/session.md
[react-devtools]: https://chrome.google.com/webstore/detail/react-developer-tools/fmkadmapgofadopljbjfkapdkoienihi
[load-extension]: ../api/session.md#sesloadextensionpath
[load-extension]: ../api/session.md#sesloadextensionpath-options
[extension-structure]: ../api/structures/extension.md
[remove-extension]: ../api/session.md#sesremoveextensionextensionid
[electron-devtools-installer]: https://github.com/MarshallOfSound/electron-devtools-installer

View File

@@ -18,4 +18,5 @@
| 9.0.0 | 2020-02-06 | 2020-05-19 | M83 | v12.14 |
| 10.0.0 | 2020-05-21 | 2020-08-25 | M85 | v12.16 |
| 11.0.0 | 2020-08-27 | 2020-11-17 | M87 | v12.18 |
| 12.0.0 | 2020-11-19 | 2021-03-02 | M89 | v14.x |
| 12.0.0 | 2020-11-19 | 2021-03-02 | M89 | v14.16 |
| 13.0.0 | 2021-03-04 | 2021-05-25 | M91 | v14.x |

View File

@@ -2,7 +2,7 @@
> A detailed look at our versioning policy and implementation.
As of version 2.0.0, Electron follows [semver](#semver). The following command will install the most recent stable build of Electron:
As of version 2.0.0, Electron follows [SemVer](#semver). The following command will install the most recent stable build of Electron:
```sh
npm install --save-dev electron
@@ -16,11 +16,11 @@ npm install --save-dev electron@latest
## Version 1.x
Electron versions *< 2.0* did not conform to the [semver](https://semver.org) spec: major versions corresponded to end-user API changes, minor versions corresponded to Chromium major releases, and patch versions corresponded to new features and bug fixes. While convenient for developers merging features, it creates problems for developers of client-facing applications. The QA testing cycles of major apps like Slack, Stride, Teams, Skype, VS Code, Atom, and Desktop can be lengthy and stability is a highly desired outcome. There is a high risk in adopting new features while trying to absorb bug fixes.
Electron versions *< 2.0* did not conform to the [SemVer](https://semver.org) spec: major versions corresponded to end-user API changes, minor versions corresponded to Chromium major releases, and patch versions corresponded to new features and bug fixes. While convenient for developers merging features, it creates problems for developers of client-facing applications. The QA testing cycles of major apps like Slack, Stride, Teams, Skype, VS Code, Atom, and Desktop can be lengthy and stability is a highly desired outcome. There is a high risk in adopting new features while trying to absorb bug fixes.
Here is an example of the 1.x strategy:
![](../images/versioning-sketch-0.png)
![1.x Versioning](../images/versioning-sketch-0.png)
An app developed with `1.8.1` cannot take the `1.8.3` bug fix without either absorbing the `1.8.2` feature, or by backporting the fix and maintaining a new release line.
@@ -28,7 +28,7 @@ An app developed with `1.8.1` cannot take the `1.8.3` bug fix without either abs
There are several major changes from our 1.x strategy outlined below. Each change is intended to satisfy the needs and priorities of developers/maintainers and app developers.
1. Strict use of semver
1. Strict use of SemVer
2. Introduction of semver-compliant `-beta` tags
3. Introduction of [conventional commit messages](https://conventionalcommits.org/)
4. Well-defined stabilization branches
@@ -36,11 +36,11 @@ There are several major changes from our 1.x strategy outlined below. Each chang
We will cover in detail how git branching works, how npm tagging works, what developers should expect to see, and how one can backport changes.
# semver
# SemVer
From 2.0 onward, Electron will follow semver.
From 2.0 onward, Electron will follow SemVer.
Below is a table explicitly mapping types of changes to their corresponding category of semver (e.g. Major, Minor, Patch).
Below is a table explicitly mapping types of changes to their corresponding category of SemVer (e.g. Major, Minor, Patch).
| Major Version Increments | Minor Version Increments | Patch Version Increments |
| ------------------------------- | ---------------------------------- | ----------------------------- |
@@ -54,12 +54,12 @@ Note that most Chromium updates will be considered breaking. Fixes that can be b
Stabilization branches are branches that run parallel to master, taking in only cherry-picked commits that are related to security or stability. These branches are never merged back to master.
![](../images/versioning-sketch-1.png)
![Stabilization Branches](../images/versioning-sketch-1.png)
Since Electron 8, stabilization branches are always **major** version lines, and named against the following template `$MAJOR-x-y` e.g. `8-x-y`. Prior to that we used **minor** version lines and named them as `$MAJOR-$MINOR-x` e.g. `2-0-x`
We allow for multiple stabilization branches to exist simultaneously, and intend to support at least two in parallel at all times, backporting security fixes as necessary.
![](../images/versioning-sketch-2.png)
![Multiple Stability Branches](../images/versioning-sketch-2.png)
Older lines will not be supported by GitHub, but other groups can take ownership and backport stability and security fixes on their own. We discourage this, but recognize that it makes life easier for many app developers.
@@ -70,13 +70,13 @@ Developers want to know which releases are _safe_ to use. Even seemingly innocen
* Use `~2.0.0` to admit only stability or security related fixes to your `2.0.0` release.
* Use `^2.0.0` to admit non-breaking _reasonably stable_ feature work as well as security and bug fixes.
Whats important about the second point is that apps using `^` should still be able to expect a reasonable level of stability. To accomplish this, semver allows for a _pre-release identifier_ to indicate a particular version is not yet _safe_ or _stable_.
Whats important about the second point is that apps using `^` should still be able to expect a reasonable level of stability. To accomplish this, SemVer allows for a _pre-release identifier_ to indicate a particular version is not yet _safe_ or _stable_.
Whatever you choose, you will periodically have to bump the version in your `package.json` as breaking changes are a fact of Chromium life.
The process is as follows:
1. All new major and minor releases lines begin with a beta series indicated by semver prerelease tags of `beta.N`, e.g. `2.0.0-beta.1`. After the first beta, subsequent beta releases must meet all of the following conditions:
1. All new major and minor releases lines begin with a beta series indicated by SemVer prerelease tags of `beta.N`, e.g. `2.0.0-beta.1`. After the first beta, subsequent beta releases must meet all of the following conditions:
1. The change is backwards API-compatible (deprecations are allowed)
2. The risk to meeting our stability timeline must be low.
2. If allowed changes need to be made once a release is beta, they are applied and the prerelease tag is incremented, e.g. `2.0.0-beta.2`.
@@ -86,7 +86,7 @@ e.g. `2.0.1`.
Specifically, the above means:
1. Admitting non-breaking-API changes before Week 3 in the beta cycle is okay, even if those changes have the potential to cause moderate side-effects
1. Admitting non-breaking-API changes before Week 3 in the beta cycle is okay, even if those changes have the potential to cause moderate side-effects.
2. Admitting feature-flagged changes, that do not otherwise alter existing code paths, at most points in the beta cycle is okay. Users can explicitly enable those flags in their apps.
3. Admitting features of any sort after Week 3 in the beta cycle is 👎 without a very good reason.
@@ -104,17 +104,17 @@ For each major and minor bump, you should expect to see something like the follo
An example lifecycle in pictures:
* A new release branch is created that includes the latest set of features. It is published as `2.0.0-beta.1`.
![](../images/versioning-sketch-3.png)
![New Release Branch](../images/versioning-sketch-3.png)
* A bug fix comes into master that can be backported to the release branch. The patch is applied, and a new beta is published as `2.0.0-beta.2`.
![](../images/versioning-sketch-4.png)
![Bugfix Backport to Beta](../images/versioning-sketch-4.png)
* The beta is considered _generally stable_ and it is published again as a non-beta under `2.0.0`.
![](../images/versioning-sketch-5.png)
![Beta to Stable](../images/versioning-sketch-5.png)
* Later, a zero-day exploit is revealed and a fix is applied to master. We backport the fix to the `2-0-x` line and release `2.0.1`.
![](../images/versioning-sketch-6.png)
![Security Backports](../images/versioning-sketch-6.png)
A few examples of how various semver ranges will pick up new releases:
A few examples of how various SemVer ranges will pick up new releases:
![](../images/versioning-sketch-7.png)
![Semvers and Releases](../images/versioning-sketch-7.png)
# Missing Features: Alphas
@@ -136,16 +136,16 @@ Feature flags are a common practice in Chromium, and are well-established in the
We seek to increase clarity at all levels of the update and releases process. Starting with `2.0.0` we will require pull requests adhere to the [Conventional Commits](https://conventionalcommits.org/) spec, which can be summarized as follows:
* Commits that would result in a semver **major** bump must start their body with `BREAKING CHANGE:`.
* Commits that would result in a semver **minor** bump must start with `feat:`.
* Commits that would result in a semver **patch** bump must start with `fix:`.
* Commits that would result in a SemVer **major** bump must start their body with `BREAKING CHANGE:`.
* Commits that would result in a SemVer **minor** bump must start with `feat:`.
* Commits that would result in a SemVer **patch** bump must start with `fix:`.
* We allow squashing of commits, provided that the squashed message adheres to the above message format.
* It is acceptable for some commits in a pull request to not include a semantic prefix, as long as the pull request title contains a meaningful encompassing semantic message.
# Versioned `master`
- The `master` branch will always contain the next major version `X.0.0-nightly.DATE` in its `package.json`
- Release branches are never merged back to master
- Release branches _do_ contain the correct version in their `package.json`
- As soon as a release branch is cut for a major, master must be bumped to the next major. I.e. `master` is always versioned as the next theoretical release branch
* The `master` branch will always contain the next major version `X.0.0-nightly.DATE` in its `package.json`
* Release branches are never merged back to master
* Release branches _do_ contain the correct version in their `package.json`
* As soon as a release branch is cut for a major, master must be bumped to the next major. I.e. `master` is always versioned as the next theoretical release branch

View File

@@ -17,7 +17,7 @@ Starting with a working application from the
[Quick Start Guide](quick-start.md), update the `main.js` file with the
following lines:
```js
```javascript fiddle='docs/fiddles/features/keyboard-shortcuts/local'
const { Menu, MenuItem } = require('electron')
const menu = new Menu()
@@ -56,7 +56,7 @@ Starting with a working application from the
[Quick Start Guide](quick-start.md), update the `main.js` file with the
following lines:
```js
```javascript fiddle='docs/fiddles/features/keyboard-shortcuts/global'
const { app, globalShortcut } = require('electron')
app.whenReady().then(() => {
@@ -101,7 +101,7 @@ Starting with a working application from the
[Quick Start Guide](quick-start.md), update the `main.js` file with the
following lines:
```js
```javascript fiddle='docs/fiddles/features/keyboard-shortcuts/interception-from-main'
const { app, BrowserWindow } = require('electron')
app.whenReady().then(() => {

View File

@@ -24,7 +24,7 @@ Starting with a working application from the
[Quick Start Guide](quick-start.md), update the `main.js` file with the
following lines:
```javascript
```javascript fiddle='docs/fiddles/features/macos-dock-menu'
const { app, Menu } = require('electron')
const dockMenu = Menu.buildFromTemplate([

View File

@@ -0,0 +1,325 @@
# MessagePorts in Electron
[`MessagePort`][]s are a web feature that allow passing messages between
different contexts. It's like `window.postMessage`, but on different channels.
The goal of this document is to describe how Electron extends the Channel
Messaging model, and to give some examples of how you might use MessagePorts in
your app.
Here is a very brief example of what a MessagePort is and how it works:
```js
// renderer.js ///////////////////////////////////////////////////////////////
// MessagePorts are created in pairs. A connected pair of message ports is
// called a channel.
const channel = new MessageChannel()
// The only difference between port1 and port2 is in how you use them. Messages
// sent to port1 will be received by port2 and vice-versa.
const port1 = channel.port1
const port2 = channel.port2
// It's OK to send a message on the channel before the other end has registered
// a listener. Messages will be queued until a listener is registered.
port2.postMessage({ answer: 42 })
// Here we send the other end of the channel, port1, to the main process. It's
// also possible to send MessagePorts to other frames, or to Web Workers, etc.
ipcRenderer.postMessage('port', null, [port1])
```
```js
// main.js ///////////////////////////////////////////////////////////////////
// In the main process, we receive the port.
ipcMain.on('port', (event) => {
// When we receive a MessagePort in the main process, it becomes a
// MessagePortMain.
const port = event.ports[0]
// MessagePortMain uses the Node.js-style events API, rather than the
// web-style events API. So .on('message', ...) instead of .onmessage = ...
port.on('message', (event) => {
// data is { answer: 42 }
const data = event.data
})
// MessagePortMain queues messages until the .start() method has been called.
port.start()
})
```
The [Channel Messaging API][] documentation is a great way to learn more about
how MessagePorts work.
## MessagePorts in the main process
In the renderer, the `MessagePort` class behaves exactly as it does on the web.
The main process is not a web page, though—it has no Blink integration—and so
it does not have the `MessagePort` or `MessageChannel` classes. In order to
handle and interact with MessagePorts in the main process, Electron adds two
new classes: [`MessagePortMain`][] and [`MessageChannelMain`][]. These behave
similarly to the analogous classes in the renderer.
`MessagePort` objects can be created in either the renderer or the main
process, and passed back and forth using the [`ipcRenderer.postMessage`][] and
[`WebContents.postMessage`][] methods. Note that the usual IPC methods like
`send` and `invoke` cannot be used to transfer `MessagePort`s, only the
`postMessage` methods can transfer `MessagePort`s.
By passing `MessagePort`s via the main process, you can connect two pages that
might not otherwise be able to communicate (e.g. due to same-origin
restrictions).
## Extension: `close` event
Electron adds one feature to `MessagePort` that isn't present on the web, in
order to make MessagePorts more useful. That is the `close` event, which is
emitted when the other end of the channel is closed. Ports can also be
implicitly closed by being garbage-collected.
In the renderer, you can listen for the `close` event either by assigning to
`port.onclose` or by calling `port.addEventListener('close', ...)`. In the main
process, you can listen for the `close` event by calling `port.on('close',
...)`.
## Example use cases
### Worker process
In this example, your app has a worker process implemented as a hidden window.
You want the app page to be able to communicate directly with the worker
process, without the performance overhead of relaying via the main process.
```js
// main.js ///////////////////////////////////////////////////////////////////
const { BrowserWindow, app, ipcMain, MessageChannelMain } = require('electron')
app.whenReady().then(async () => {
// The worker process is a hidden BrowserWindow, so that it will have access
// to a full Blink context (including e.g. <canvas>, audio, fetch(), etc.)
const worker = new BrowserWindow({
show: false,
webPreferences: { nodeIntegration: true }
})
await worker.loadFile('worker.html')
// The main window will send work to the worker process and receive results
// over a MessagePort.
const mainWindow = new BrowserWindow({
webPreferences: { nodeIntegration: true }
})
mainWindow.loadFile('app.html')
// We can't use ipcMain.handle() here, because the reply needs to transfer a
// MessagePort.
ipcMain.on('request-worker-channel', (event) => {
// For security reasons, let's make sure only the frames we expect can
// access the worker.
if (event.senderFrame === mainWindow.webContents.mainFrame) {
// Create a new channel ...
const { port1, port2 } = new MessageChannelMain()
// ... send one end to the worker ...
worker.webContents.postMessage('new-client', null, [port1])
// ... and the other end to the main window.
event.senderFrame.postMessage('provide-worker-channel', null, [port2])
// Now the main window and the worker can communicate with each other
// without going through the main process!
}
})
})
```
```html
<!-- worker.html ------------------------------------------------------------>
<script>
const { ipcRenderer } = require('electron')
function doWork(input) {
// Something cpu-intensive.
return input * 2
}
// We might get multiple clients, for instance if there are multiple windows,
// or if the main window reloads.
ipcRenderer.on('new-client', (event) => {
const [ port ] = event.ports
port.onmessage = (event) => {
// The event data can be any serializable object (and the event could even
// carry other MessagePorts with it!)
const result = doWork(event.data)
port.postMessage(result)
}
})
</script>
```
```html
<!-- app.html --------------------------------------------------------------->
<script>
const { ipcRenderer } = require('electron')
// We request that the main process sends us a channel we can use to
// communicate with the worker.
ipcRenderer.send('request-worker-channel')
ipcRenderer.once('provide-worker-channel', (event) => {
// Once we receive the reply, we can take the port...
const [ port ] = event.ports
// ... register a handler to receive results ...
port.onmessage = (event) => {
console.log('received result:', event.data)
}
// ... and start sending it work!
port.postMessage(21)
})
</script>
```
### Reply streams
Electron's built-in IPC methods only support two modes: fire-and-forget
(e.g. `send`), or request-response (e.g. `invoke`). Using MessageChannels, you
can implement a "response stream", where a single request responds with a
stream of data.
```js
// renderer.js ///////////////////////////////////////////////////////////////
function makeStreamingRequest (element, callback) {
// MessageChannels are lightweight--it's cheap to create a new one for each
// request.
const { port1, port2 } = new MessageChannel()
// We send one end of the port to the main process ...
ipcRenderer.postMessage(
'give-me-a-stream',
{ element, count: 10 },
[port2]
)
// ... and we hang on to the other end. The main process will send messages
// to its end of the port, and close it when it's finished.
port1.onmessage = (event) => {
callback(event.data)
}
port1.onclose = () => {
console.log('stream ended')
}
}
makeStreamingRequest(42, (data) => {
console.log('got response data:', event.data)
})
// We will see "got response data: 42" 10 times.
```
```js
// main.js ///////////////////////////////////////////////////////////////////
ipcMain.on('give-me-a-stream', (event, msg) => {
// The renderer has sent us a MessagePort that it wants us to send our
// response over.
const [replyPort] = event.ports
// Here we send the messages synchronously, but we could just as easily store
// the port somewhere and send messages asynchronously.
for (let i = 0; i < msg.count; i++) {
replyPort.postMessage(msg.element)
}
// We close the port when we're done to indicate to the other end that we
// won't be sending any more messages. This isn't strictly necessary--if we
// didn't explicitly close the port, it would eventually be garbage
// collected, which would also trigger the 'close' event in the renderer.
replyPort.close()
})
```
### Communicating directly between the main process and the main world of a context-isolated page
When [context isolation][] is enabled, IPC messages from the main process to
the renderer are delivered to the isolated world, rather than to the main
world. Sometimes you want to deliver messages to the main world directly,
without having to step through the isolated world.
```js
// main.js ///////////////////////////////////////////////////////////////////
const { BrowserWindow, app, MessageChannelMain } = require('electron')
const path = require('path')
app.whenReady().then(async () => {
// Create a BrowserWindow with contextIsolation enabled.
const bw = new BrowserWindow({
webPreferences: {
contextIsolation: true,
preload: path.join(__dirname, 'preload.js')
}
})
bw.loadURL('index.html')
// We'll be sending one end of this channel to the main world of the
// context-isolated page.
const { port1, port2 } = new MessageChannelMain()
// It's OK to send a message on the channel before the other end has
// registered a listener. Messages will be queued until a listener is
// registered.
port2.postMessage({ test: 21 })
// We can also receive messages from the main world of the renderer.
port2.on('message', (event) => {
console.log('from renderer main world:', event.data)
})
port2.start()
// The preload script will receive this IPC message and transfer the port
// over to the main world.
bw.webContents.postMessage('main-world-port', null, [port1])
})
```
```js
// preload.js ////////////////////////////////////////////////////////////////
const { ipcRenderer } = require('electron')
// We need to wait until the main world is ready to receive the message before
// sending the port. We create this promise in the preload so it's guaranteed
// to register the onload listener before the load event is fired.
const windowLoaded = new Promise(resolve => {
window.onload = resolve
})
ipcRenderer.on('main-world-port', async (event) => {
await windowLoaded
// We use regular window.postMessage to transfer the port from the isolated
// world to the main world.
window.postMessage('main-world-port', '*', event.ports)
})
```
```html
<!-- index.html ------------------------------------------------------------->
<script>
window.onmessage = (event) => {
// event.source === window means the message is coming from the preload
// script, as opposed to from an <iframe> or other source.
if (event.source === window && event.data === 'main-world-port') {
const [ port ] = event.ports
// Once we have the port, we can communicate directly with the main
// process.
port.onmessage = (event) => {
console.log('from main process:', event.data)
port.postMessage(event.data * 2)
}
}
}
</script>
```
[context isolation]: context-isolation.md
[`ipcRenderer.postMessage`]: ../api/ipc-renderer.md#ipcrendererpostmessagechannel-message-transfer
[`WebContents.postMessage`]: ../api/web-contents.md#contentspostmessagechannel-message-transfer
[`MessagePortMain`]: ../api/message-port-main.md
[`MessageChannelMain`]: ../api/message-channel-main.md
[`MessagePort`]: https://developer.mozilla.org/en-US/docs/Web/API/MessagePort
[Channel Messaging API]: https://developer.mozilla.org/en-US/docs/Web/API/Channel_Messaging_API

View File

@@ -25,7 +25,7 @@ Starting with a working application from the
and add the following lines to the `renderer.js` file:
```js
```javascript
const { ipcRenderer } = require('electron')
document.getElementById('drag').ondragstart = (event) => {
@@ -40,7 +40,7 @@ and forward the information to the Main process.
In the Main process(`main.js` file), expand the received event with a path to the file that is
being dragged and an icon:
```javascript
```javascript fiddle='docs/fiddles/features/drag-and-drop'
const { ipcMain } = require('electron')
ipcMain.on('ondragstart', (event, filePath) => {
@@ -52,7 +52,7 @@ ipcMain.on('ondragstart', (event, filePath) => {
```
After launching the Electron application, try dragging and dropping
the item from the BroswerWindow onto your desktop. In this guide,
the item from the BrowserWindow onto your desktop. In this guide,
the item is a Markdown file located in the root of the project:
![Drag and drop](../images/drag-and-drop.gif)

View File

@@ -28,7 +28,7 @@ Assuming you have a working Electron application from the
and add the `renderer.js` file:
```js
```javascript fiddle='docs/fiddles/features/notifications/renderer'
const myNotification = new Notification('Title', {
body: 'Notification from the Renderer process'
})
@@ -52,7 +52,7 @@ message that was generated after triggering the `onclick` event:
Starting with a working application from the
[Quick Start Guide](quick-start.md), update the `main.js` file with the following lines:
```js
```javascript fiddle='docs/fiddles/features/notifications/main'
const { Notification } = require('electron')
function showNotification () {

View File

@@ -1,59 +1,67 @@
# Offscreen Rendering
Offscreen rendering lets you obtain the content of a browser window in a bitmap,
so it can be rendered anywhere, for example on a texture in a 3D scene. The
offscreen rendering in Electron uses a similar approach than the [Chromium
Embedded Framework](https://bitbucket.org/chromiumembedded/cef) project.
## Overview
Two modes of rendering can be used and only the dirty area is passed in the
`'paint'` event to be more efficient. The rendering can be stopped, continued
and the frame rate can be set. The specified frame rate is a top limit value,
when there is nothing happening on a webpage, no frames are generated. The
maximum frame rate is 240, because above that there is no benefit, only
performance loss.
Offscreen rendering lets you obtain the content of a `BrowserWindow` in a
bitmap, so it can be rendered anywhere, for example, on texture in a 3D scene.
The offscreen rendering in Electron uses a similar approach to that of the
[Chromium Embedded Framework](https://bitbucket.org/chromiumembedded/cef)
project.
**Note:** An offscreen window is always created as a [Frameless Window](../api/frameless-window.md).
*Notes*:
## Rendering Modes
* There are two rendering modes that can be used (see the section below) and only
the dirty area is passed to the `paint` event to be more efficient.
* You can stop/continue the rendering as well as set the frame rate.
* The maximum frame rate is 240 because greater values bring only performance
losses with no benefits.
* When nothing is happening on a webpage, no frames are generated.
* An offscreen window is always created as a
[Frameless Window](../api/frameless-window.md).
### GPU accelerated
### Rendering Modes
#### GPU accelerated
GPU accelerated rendering means that the GPU is used for composition. Because of
that the frame has to be copied from the GPU which requires more performance,
thus this mode is quite a bit slower than the other one. The benefit of this
that, the frame has to be copied from the GPU which requires more resources,
thus this mode is slower than the Software output device. The benefit of this
mode is that WebGL and 3D CSS animations are supported.
### Software output device
#### Software output device
This mode uses a software output device for rendering in the CPU, so the frame
generation is much faster, thus this mode is preferred over the GPU accelerated
one.
generation is much faster. As a result, this mode is preferred over the GPU
accelerated one.
To enable this mode GPU acceleration has to be disabled by calling the
To enable this mode, GPU acceleration has to be disabled by calling the
[`app.disableHardwareAcceleration()`][disablehardwareacceleration] API.
## Usage
## Example
``` javascript
Starting with a working application from the
[Quick Start Guide](quick-start.md), add the following lines to the
`main.js` file:
```javascript fiddle='docs/fiddles/features/offscreen-rendering'
const { app, BrowserWindow } = require('electron')
const fs = require('fs')
app.disableHardwareAcceleration()
let win
app.whenReady().then(() => {
win = new BrowserWindow({
webPreferences: {
offscreen: true
}
})
win = new BrowserWindow({ webPreferences: { offscreen: true } })
win.loadURL('http://github.com')
win.loadURL('https://github.com')
win.webContents.on('paint', (event, dirty, image) => {
// updateBitmap(dirty, image.getBitmap())
fs.writeFileSync('ex.png', image.toPNG())
})
win.webContents.setFrameRate(30)
win.webContents.setFrameRate(60)
})
```
After launching the Electron application, navigate to your application's
working folder.
[disablehardwareacceleration]: ../api/app.md#appdisablehardwareacceleration

View File

@@ -34,11 +34,11 @@ let onlineStatusWindow
app.whenReady().then(() => {
onlineStatusWindow = new BrowserWindow({ width: 0, height: 0, show: false })
onlineStatusWindow.loadURL(`file://${__dirname}/online-status.html`)
onlineStatusWindow.loadURL(`file://${__dirname}/index.html`)
})
```
create the `online-status.html` file and add the following line before the
in the `index.html` file, add the following line before the
closing `</body>` tag:
```html
@@ -47,7 +47,7 @@ closing `</body>` tag:
and add the `renderer.js` file:
```javascript
```javascript fiddle='docs/fiddles/features/online-detection/renderer'
const alertOnlineStatus = () => { window.alert(navigator.onLine ? 'online' : 'offline') }
window.addEventListener('online', alertOnlineStatus)
@@ -78,7 +78,7 @@ let onlineStatusWindow
app.whenReady().then(() => {
onlineStatusWindow = new BrowserWindow({ width: 0, height: 0, show: false, webPreferences: { nodeIntegration: true } })
onlineStatusWindow.loadURL(`file://${__dirname}/online-status.html`)
onlineStatusWindow.loadURL(`file://${__dirname}/index.html`)
})
ipcMain.on('online-status-changed', (event, status) => {
@@ -86,7 +86,7 @@ ipcMain.on('online-status-changed', (event, status) => {
})
```
create the `online-status.html` file and add the following line before the
in the `index.html` file, add the following line before the
closing `</body>` tag:
```html
@@ -95,7 +95,7 @@ closing `</body>` tag:
and add the `renderer.js` file:
```javascript
```javascript fiddle='docs/fiddles/features/online-detection/main'
const { ipcRenderer } = require('electron')
const updateOnlineStatus = () => { ipcRenderer.send('online-status-changed', navigator.onLine ? 'online' : 'offline') }

View File

@@ -45,7 +45,7 @@ Starting with a working application from the
[Quick Start Guide](quick-start.md), add the following lines to the
`main.js` file:
```javascript
```javascript fiddle='docs/fiddles/features/progress-bar'
const { BrowserWindow } = require('electron')
const win = new BrowserWindow()

View File

@@ -28,10 +28,11 @@ If both commands succeeded, you are ready to install Electron.
From a development perspective, an Electron application is essentially a Node.js application. This means that the starting point of your Electron application will be a `package.json` file like in any other Node.js application. A minimal Electron application has the following structure:
```plain
```plaintext
my-electron-app/
├── package.json
├── main.js
├── preload.js
└── index.html
```
@@ -53,52 +54,55 @@ The main script specifies the entry point of your Electron application (in our c
The main script may look as follows:
```js
```javascript fiddle='docs/fiddles/quick-start'
const { app, BrowserWindow } = require('electron')
const path = require('path')
function createWindow () {
const win = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
nodeIntegration: true
preload: path.join(__dirname, 'preload.js')
}
})
win.loadFile('index.html')
win.webContents.openDevTools()
}
app.whenReady().then(createWindow)
app.whenReady().then(() => {
createWindow()
app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0) {
createWindow()
}
})
})
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit()
}
})
app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0) {
createWindow()
}
})
```
##### What is going on above?
1. Line 1: First, you import the `app` and `BrowserWindow` modules of the `electron` package to be able to manage your application's lifecycle events, as well as create and control browser windows.
2. Line 3: After that, you define a function that creates a [new browser window](../api/browser-window.md#new-browserwindowoptions) with node integration enabled, loads `index.html` file into this window (line 12, we will discuss the file later) and opens Developer Tools (line 13).
3. Line 16: You create a new browser window by invoking the `createWindow` function once the Electron application [is initialized](../api/app.md#appwhenready).
4. Line 18: You add a new listener that tries to quit the application when it no longer has any open windows. This listener is a no-op on macOS due to the operating system's [window management behavior](https://support.apple.com/en-ca/guide/mac-help/mchlp2469/mac).
5. Line 24: You add a new listener that creates a new browser window only if when the application has no visible windows after being activated. For example, after launching the application for the first time, or re-launching the already running application.
2. Line 2: Second, you import the `path` package which provides utility functions for file paths.
3. Line 4: After that, you define a function that creates a [new browser window](../api/browser-window.md#new-browserwindowoptions) with a preload script, loads `index.html` file into this window (line 13, we will discuss the file later).
4. Line 16: You create a new browser window by invoking the `createWindow` function once the Electron application [is initialized](../api/app.md#appwhenready).
5. Line 18: You add a new listener that creates a new browser window only if when the application has no visible windows after being activated. For example, after launching the application for the first time, or re-launching the already running application.
6. Line 25: You add a new listener that tries to quit the application when it no longer has any open windows. This listener is a no-op on macOS due to the operating system's [window management behavior](https://support.apple.com/en-ca/guide/mac-help/mchlp2469/mac).
#### Create a web page
This is the web page you want to display once the application is initialized. This web page represents the Renderer process. You can create multiple browser windows, where each window uses its own independent Renderer. Each window can optionally be granted with full access to Node.js API through the `nodeIntegration` preference.
This is the web page you want to display once the application is initialized. This web page represents the Renderer process. You can create multiple browser windows, where each window uses its own independent Renderer. You can optionally grant access to additional Node.js APIs by exposing them from your preload script.
The `index.html` page looks as follows:
```html
```html fiddle='docs/fiddles/quick-start'
<!DOCTYPE html>
<html>
<head>
@@ -108,13 +112,39 @@ The `index.html` page looks as follows:
</head>
<body style="background: white;">
<h1>Hello World!</h1>
We are using node <script>document.write(process.versions.node)</script>,
Chrome <script>document.write(process.versions.chrome)</script>,
and Electron <script>document.write(process.versions.electron)</script>.
<p>
We are using Node.js <span id="node-version"></span>,
Chromium <span id="chrome-version"></span>,
and Electron <span id="electron-version"></span>.
</p>
</body>
</html>
```
#### Define a preload script
Your preload script (in our case, the `preload.js` file) acts as a bridge between Node.js and your web page. It allows you to expose specific APIs and behaviors to your web page rather than insecurely exposing the entire Node.js API. In this example we will use the preload script to read version information from the `process` object and update the web page with that info.
```javascript fiddle='docs/fiddles/quick-start'
window.addEventListener('DOMContentLoaded', () => {
const replaceText = (selector, text) => {
const element = document.getElementById(selector)
if (element) element.innerText = text
}
for (const type of ['chrome', 'node', 'electron']) {
replaceText(`${type}-version`, process.versions[type])
}
})
```
##### What's going on above?
1. On line 1: First you define an event listener that tells you when the web page has loaded
2. On line 2: Second you define a utility function used to set the text of the placeholders in the `index.html`
3. On line 7: Next you loop through the list of components whose version you want to display
4. On line 8: Finally, you call `replaceText` to look up the version placeholders in `index.html` and set their text value to the values from `process.versions`
#### Modify your package.json file
Your Electron application uses the `package.json` file as the main entry point (as any other Node.js application). The main script of your application is `main.js`, so modify the `package.json` file accordingly:
@@ -123,18 +153,24 @@ Your Electron application uses the `package.json` file as the main entry point (
{
"name": "my-electron-app",
"version": "0.1.0",
"author": "your name",
"description": "My Electron app",
"main": "main.js"
}
```
> NOTE: If the `main` field is omitted, Electron will attempt to load an `index.js` file from the directory containing `package.json`.
> NOTE: The `author` and `description` fields are required for packaging, otherwise error will occur when running `npm run make`.
By default, the `npm start` command will run the main script with Node.js. To run the script with Electron, you need to change it as such:
```json
{
"name": "my-electron-app",
"version": "0.1.0",
"author": "your name",
"description": "My Electron app",
"main": "main.js",
"scripts": {
"start": "electron ."
@@ -160,7 +196,8 @@ The simplest and the fastest way to distribute your newly created app is using
1. Import Electron Forge to your app folder:
```sh
npx @electron-forge/cli import
npm install --save-dev @electron-forge/cli
npx electron-forge import
✔ Checking your system
✔ Initializing Git Repository
@@ -275,7 +312,7 @@ ipcRenderer.invoke('perform-action', ...args)
##### Node.js API
> NOTE: To access the Node.js API from the Renderer process, you need to set the `nodeIntegration` preference to `true`.
> NOTE: To access the Node.js API from the Renderer process, you need to set the `nodeIntegration` preference to `true` and the `contextIsolation` preference to `false`. Please note that access to the Node.js API in any renderer that loads remote content is not recommended for [security reasons](../tutorial/security.md#2-do-not-enable-nodejs-integration-for-remote-content).
Electron exposes full access to Node.js API and its modules both in the Main and the Renderer processes. For example, you can read all the files from the root directory:

View File

@@ -24,7 +24,7 @@ Starting with a working application from the
[Quick Start Guide](quick-start.md), add the following lines to the
`main.js` file:
```javascript
```javascript fiddle='docs/fiddles/features/recent-documents'
const { app } = require('electron')
app.addRecentDocument('/Users/USERNAME/Desktop/work.type')

View File

@@ -24,7 +24,7 @@ Starting with a working application from the
[Quick Start Guide](quick-start.md), add the following lines to the
`main.js` file:
```javascript
```javascript fiddle='docs/fiddles/features/represented-file'
const { app, BrowserWindow } = require('electron')
app.whenReady().then(() => {

View File

@@ -44,7 +44,7 @@ Chromium shared library and Node.js. Vulnerabilities affecting these components
may impact the security of your application. By updating Electron to the latest
version, you ensure that critical vulnerabilities (such as *nodeIntegration bypasses*)
are already patched and cannot be exploited in your application. For more information,
see "[Use a current version of Electron](#17-use-a-current-version-of-electron)".
see "[Use a current version of Electron](#15-use-a-current-version-of-electron)".
* **Evaluate your dependencies.** While NPM provides half a million reusable packages,
it is your responsibility to choose trusted 3rd-party libraries. If you use outdated
@@ -99,9 +99,7 @@ You should at least follow these steps to improve the security of your applicati
12. [Disable or limit navigation](#12-disable-or-limit-navigation)
13. [Disable or limit creation of new windows](#13-disable-or-limit-creation-of-new-windows)
14. [Do not use `openExternal` with untrusted content](#14-do-not-use-openexternal-with-untrusted-content)
15. [Disable the `remote` module](#15-disable-the-remote-module)
16. [Filter the `remote` module](#16-filter-the-remote-module)
17. [Use a current version of Electron](#17-use-a-current-version-of-electron)
15. [Use a current version of Electron](#15-use-a-current-version-of-electron)
To automate the detection of misconfigurations and insecure patterns, it is
possible to use
@@ -665,134 +663,7 @@ const { shell } = require('electron')
shell.openExternal('https://example.com/index.html')
```
## 15) Disable the `remote` module
The `remote` module provides a way for the renderer processes to
access APIs normally only available in the main process. Using it, a
renderer can invoke methods of a main process object without explicitly sending
inter-process messages. If your desktop application does not run untrusted
content, this can be a useful way to have your renderer processes access and
work with modules that are only available to the main process, such as
GUI-related modules (dialogs, menus, etc.).
However, if your app can run untrusted content and even if you
[sandbox][sandbox] your renderer processes accordingly, the `remote` module
makes it easy for malicious code to escape the sandbox and have access to
system resources via the higher privileges of the main process. Therefore,
it should be disabled in such circumstances.
### Why?
`remote` uses an internal IPC channel to communicate with the main process.
"Prototype pollution" attacks can grant malicious code access to the internal
IPC channel, which can then be used to escape the sandbox by mimicking `remote`
IPC messages and getting access to main process modules running with higher
privileges.
Additionally, it's possible for preload scripts to accidentally leak modules to a
sandboxed renderer. Leaking `remote` arms malicious code with a multitude
of main process modules with which to perform an attack.
Disabling the `remote` module eliminates these attack vectors. Enabling
context isolation also prevents the "prototype pollution" attacks from
succeeding.
### How?
```js
// Bad if the renderer can run untrusted content
const mainWindow = new BrowserWindow({
webPreferences: {
enableRemoteModule: true
}
})
```
```js
// Good
const mainWindow = new BrowserWindow({
webPreferences: {
enableRemoteModule: false
}
})
```
```html
<!-- Bad if the renderer can run untrusted content -->
<webview enableremotemodule="true" src="page.html"></webview>
<!-- Good -->
<webview enableremotemodule="false" src="page.html"></webview>
```
> **Note:** The default value of `enableRemoteModule` is `false` starting
> from Electron 10. For prior versions, you need to explicitly disable
> the `remote` module by the means above.
## 16) Filter the `remote` module
If you cannot disable the `remote` module, you should filter the globals,
Node, and Electron modules (so-called built-ins) accessible via `remote`
that your application does not require. This can be done by blocking
certain modules entirely and by replacing others with proxies that
expose only the functionality that your app needs.
### Why?
Due to the system access privileges of the main process, functionality
provided by the main process modules may be dangerous in the hands of
malicious code running in a compromised renderer process. By limiting
the set of accessible modules to the minimum that your app needs and
filtering out the others, you reduce the toolset that malicious code
can use to attack the system.
Note that the safest option is to
[fully disable the remote module](#15-disable-the-remote-module). If
you choose to filter access rather than completely disable the module,
you must be very careful to ensure that no escalation of privilege is
possible through the modules you allow past the filter.
### How?
```js
const readOnlyFsProxy = require(/* ... */) // exposes only file read functionality
const allowedModules = new Set(['crypto'])
const proxiedModules = new Map(['fs', readOnlyFsProxy])
const allowedElectronModules = new Set(['shell'])
const allowedGlobals = new Set()
app.on('remote-require', (event, webContents, moduleName) => {
if (proxiedModules.has(moduleName)) {
event.returnValue = proxiedModules.get(moduleName)
}
if (!allowedModules.has(moduleName)) {
event.preventDefault()
}
})
app.on('remote-get-builtin', (event, webContents, moduleName) => {
if (!allowedElectronModules.has(moduleName)) {
event.preventDefault()
}
})
app.on('remote-get-global', (event, webContents, globalName) => {
if (!allowedGlobals.has(globalName)) {
event.preventDefault()
}
})
app.on('remote-get-current-window', (event, webContents) => {
event.preventDefault()
})
app.on('remote-get-current-web-contents', (event, webContents) => {
event.preventDefault()
})
```
## 17) Use a current version of Electron
## 15) Use a current version of Electron
You should strive for always using the latest available version of Electron.
Whenever a new major version is released, you should attempt to update your

View File

@@ -83,7 +83,7 @@ snap(options)
### Step 1: Create Sample Snapcraft Project
Create your project directory and add add the following to `snap/snapcraft.yaml`:
Create your project directory and add the following to `snap/snapcraft.yaml`:
```yaml
name: electron-packager-hello-world

View File

@@ -71,4 +71,4 @@ Although the spellchecker itself does not send any typings, words or user input
myWindow.session.setSpellCheckerDictionaryDownloadURL('https://example.com/dictionaries/')
```
Check out the docs for [`session.setSpellCheckerDictionaryDownloadURL`](https://www.electronjs.org/docs/api/session#sessetspellcheckerdictionarydownloadurlurl) for more information on where to get the dictionary files from and how you need to host them.
Check out the docs for [`session.setSpellCheckerDictionaryDownloadURL`](../api/session.md#sessetspellcheckerdictionarydownloadurlurl) for more information on where to get the dictionary files from and how you need to host them.

View File

@@ -10,21 +10,21 @@ for answers to questions,
or to join in discussion with other developers who use Electron,
you can interact with the community in these locations:
- [`Electron's Discord`](https://discord.com/invite/electron) has channels for:
- Getting help
- Ecosystem apps like [Electron Forge](https://github.com/electron-userland/electron-forge) and [Electron Fiddle](https://github.com/electron/fiddle)
- Sharing ideas with other Electron app developers
- And more!
- [`electron`](https://discuss.atom.io/c/electron) category on the Atom forums
- `#atom-shell` channel on Freenode
- `#electron` channel on [Atom's Slack](https://discuss.atom.io/t/join-us-on-slack/16638?source_topic_id=25406)
- [`electron-ru`](https://telegram.me/electron_ru) *(Russian)*
- [`electron-br`](https://electron-br.slack.com) *(Brazilian Portuguese)*
- [`electron-kr`](https://electron-kr.github.io/electron-kr) *(Korean)*
- [`electron-jp`](https://electron-jp.slack.com) *(Japanese)*
- [`electron-tr`](https://electron-tr.herokuapp.com) *(Turkish)*
- [`electron-id`](https://electron-id.slack.com) *(Indonesia)*
- [`electron-pl`](https://electronpl.github.io) *(Poland)*
* [`Electron's Discord`](https://discord.com/invite/electron) has channels for:
* Getting help
* Ecosystem apps like [Electron Forge](https://github.com/electron-userland/electron-forge) and [Electron Fiddle](https://github.com/electron/fiddle)
* Sharing ideas with other Electron app developers
* And more!
* [`electron`](https://discuss.atom.io/c/electron) category on the Atom forums
* `#atom-shell` channel on Freenode
* `#electron` channel on [Atom's Slack](https://discuss.atom.io/t/join-us-on-slack/16638?source_topic_id=25406)
* [`electron-ru`](https://telegram.me/electron_ru) *(Russian)*
* [`electron-br`](https://electron-br.slack.com) *(Brazilian Portuguese)*
* [`electron-kr`](https://electron-kr.github.io/electron-kr) *(Korean)*
* [`electron-jp`](https://electron-jp.slack.com) *(Japanese)*
* [`electron-tr`](https://electron-tr.herokuapp.com) *(Turkish)*
* [`electron-id`](https://electron-id.slack.com) *(Indonesia)*
* [`electron-pl`](https://electronpl.github.io) *(Poland)*
If you'd like to contribute to Electron,
see the [contributing document](https://github.com/electron/electron/blob/master/CONTRIBUTING.md).
@@ -64,9 +64,9 @@ until the maintainers feel the maintenance burden is too high to continue doing
### Currently supported versions
- 11.x.y
- 10.x.y
- 9.x.y
* 12.x.y
* 11.x.y
* 10.x.y
### End-of-life
@@ -94,7 +94,9 @@ Following platforms are supported by Electron:
### macOS
Only 64bit binaries are provided for macOS, and the minimum macOS version
supported is macOS 10.10 (Yosemite).
supported is macOS 10.11 (El Capitan).
Native support for Apple Silicon (`arm64`) devices was added in Electron 11.0.0.
### Windows
@@ -102,7 +104,7 @@ Windows 7 and later are supported, older operating systems are not supported
(and do not work).
Both `ia32` (`x86`) and `x64` (`amd64`) binaries are provided for Windows.
[Electron 6.0.8 and later add native support for Windows on Arm (`arm64`) devices](windows-arm.md).
[Native support for Windows on Arm (`arm64`) devices was added in Electron 6.0.8.](windows-arm.md).
Running apps packaged with previous versions is possible using the ia32 binary.
### Linux

View File

@@ -1,8 +1,9 @@
# Using Native Node Modules
Native Node modules are supported by Electron, but since Electron is very
likely to use a different V8 version from the Node binary installed on your
system, the modules you use will need to be recompiled for Electron. Otherwise,
Native Node.js modules are supported by Electron, but since Electron has a different
[application binary interface (ABI)][abi] from a given Node.js binary (due to
differences such as using Chromium's BoringSSL instead of OpenSSL), the native
modules you use will need to be recompiled for Electron. Otherwise,
you will get the following class of error when you try to run your app:
```sh
@@ -23,9 +24,11 @@ You can install modules like other Node projects, and then rebuild the modules
for Electron with the [`electron-rebuild`][electron-rebuild] package. This
module can automatically determine the version of Electron and handle the
manual steps of downloading headers and rebuilding native modules for your app.
If you are using [Electron Forge][electron-forge], this tool is used automatically
in both development mode and when making distributables.
For example, to install `electron-rebuild` and then rebuild modules with it
via the command line:
For example, to install the standalone `electron-rebuild` tool and then rebuild
modules with it via the command line:
```sh
npm install --save-dev electron-rebuild
@@ -33,12 +36,12 @@ npm install --save-dev electron-rebuild
# Every time you run "npm install", run this:
./node_modules/.bin/electron-rebuild
# On Windows if you have trouble, try:
# If you have trouble on Windows, try:
.\node_modules\.bin\electron-rebuild.cmd
```
For more information on usage and integration with other tools, consult the
project's README.
For more information on usage and integration with other tools such as [Electron
Packager][electron-packager], consult the project's README.
### Using `npm`
@@ -129,13 +132,13 @@ should look like this:
In particular, it's important that:
- you link against `node.lib` from _Electron_ and not Node. If you link against
* you link against `node.lib` from _Electron_ and not Node. If you link against
the wrong `node.lib` you will get load-time errors when you require the
module in Electron.
- you include the flag `/DELAYLOAD:node.exe`. If the `node.exe` link is not
* you include the flag `/DELAYLOAD:node.exe`. If the `node.exe` link is not
delayed, then the delay-load hook won't get a chance to fire and the node
symbols won't be correctly resolved.
- `win_delay_load_hook.obj` is linked directly into the final DLL. If the hook
* `win_delay_load_hook.obj` is linked directly into the final DLL. If the hook
is set up in a dependent DLL, it won't fire at the right time.
See [`node-gyp`](https://github.com/nodejs/node-gyp/blob/e2401e1395bef1d3c8acec268b42dc5fb71c4a38/src/win_delay_load_hook.cc)
@@ -147,23 +150,25 @@ for an example delay-load hook if you're implementing your own.
native Node modules with prebuilt binaries for multiple versions of Node
and Electron.
If modules provide binaries for the usage in Electron, make sure to omit
`--build-from-source` and the `npm_config_build_from_source` environment
variable in order to take full advantage of the prebuilt binaries.
If the `prebuild`-powered module provide binaries for the usage in Electron,
make sure to omit `--build-from-source` and the `npm_config_build_from_source`
environment variable in order to take full advantage of the prebuilt binaries.
## Modules that rely on `node-pre-gyp`
The [`node-pre-gyp` tool][node-pre-gyp] provides a way to deploy native Node
modules with prebuilt binaries, and many popular modules are using it.
Usually those modules work fine under Electron, but sometimes when Electron uses
a newer version of V8 than Node and/or there are ABI changes, bad things may
happen. So in general, it is recommended to always build native modules from
source code. `electron-rebuild` handles this for you automatically.
Sometimes those modules work fine under Electron, but when there are no
Electron-specific binaries available, you'll need to build from source.
Because of this, it is recommended to use `electron-rebuild` for these modules.
If you are following the `npm` way of installing modules, then this is done
by default, if not, you have to pass `--build-from-source` to `npm`, or set the
`npm_config_build_from_source` environment variable.
If you are following the `npm` way of installing modules, you'll need to pass
`--build-from-source` to `npm`, or set the `npm_config_build_from_source`
environment variable.
[abi]: https://en.wikipedia.org/wiki/Application_binary_interface
[electron-rebuild]: https://github.com/electron/electron-rebuild
[electron-forge]: https://electronforge.io/
[electron-packager]: https://github.com/electron/electron-packager
[node-pre-gyp]: https://github.com/mapbox/node-pre-gyp

View File

@@ -86,12 +86,12 @@ const driver = new webdriver.Builder()
// The "9515" is the port opened by chrome driver.
.usingServer('http://localhost:9515')
.withCapabilities({
chromeOptions: {
'goog:chromeOptions': {
// Here is the path to your Electron binary.
binary: '/Path-to-Your-App.app/Contents/MacOS/Electron'
}
})
.forBrowser('electron')
.forBrowser('chrome') // note: use .forBrowser('electron') for selenium-webdriver <= 3.6.0
.build()
driver.get('http://www.google.com')

View File

@@ -20,7 +20,7 @@ and only allow the capabilities you want to support.
### WebViews
> Important Note:
[we do not recommend you to use use WebViews](https://www.electronjs.org/docs/api/webview-tag#warning),
[we do not recommend you to use WebViews](../api/webview-tag.md#warning),
as this tag undergoes dramatic architectural changes that may affect stability
of your application. Consider switching to alternatives, like `iframe` and
Electron's `BrowserView`, or an architecture that avoids embedded content

View File

@@ -96,6 +96,10 @@ template("electron_extra_paks") {
"$root_gen_dir/ui/resources/webui_generated_resources.pak",
]
deps += [ "//content/browser/devtools:devtools_resources" ]
if (enable_pdf_viewer) {
sources += [ "$root_gen_dir/chrome/pdf_resources.pak" ]
deps += [ "//chrome/browser/resources/pdf:pdf_resources" ]
}
if (enable_print_preview) {
sources += [ "$root_gen_dir/chrome/print_preview_resources.pak" ]
deps +=

View File

@@ -34,7 +34,6 @@ auto_filenames = {
"docs/api/menu.md",
"docs/api/message-channel-main.md",
"docs/api/message-port-main.md",
"docs/api/modernization",
"docs/api/native-image.md",
"docs/api/native-theme.md",
"docs/api/net-log.md",

View File

@@ -332,6 +332,8 @@ filenames = {
"shell/browser/badging/badge_manager.h",
"shell/browser/badging/badge_manager_factory.cc",
"shell/browser/badging/badge_manager_factory.h",
"shell/browser/bluetooth/electron_bluetooth_delegate.cc",
"shell/browser/bluetooth/electron_bluetooth_delegate.h",
"shell/browser/browser.cc",
"shell/browser/browser.h",
"shell/browser/browser_observer.h",
@@ -400,6 +402,8 @@ filenames = {
"shell/browser/native_window_observer.h",
"shell/browser/net/asar/asar_url_loader.cc",
"shell/browser/net/asar/asar_url_loader.h",
"shell/browser/net/asar/asar_url_loader_factory.cc",
"shell/browser/net/asar/asar_url_loader_factory.h",
"shell/browser/net/cert_verifier_client.cc",
"shell/browser/net/cert_verifier_client.h",
"shell/browser/net/electron_url_loader_factory.cc",

View File

@@ -532,15 +532,17 @@ export const wrapFsWithAsar = (fs: Record<string, any>) => {
return fs.readFile(realPath, options, callback);
}
const buffer = Buffer.alloc(info.size);
const fd = archive.getFd();
if (!(fd >= 0)) {
const error = createError(AsarError.NOT_FOUND, { asarPath, filePath });
nextTick(callback, [error]);
return;
}
logASARAccess(asarPath, filePath, info.offset);
archive.read(info.offset, info.size).then((buf) => {
const buffer = Buffer.from(buf);
callback(null, encoding ? buffer.toString(encoding) : buffer);
}, (err) => {
const error: AsarErrorObject = new Error(`EINVAL, ${err.message} while reading ${filePath} in ${asarPath}`);
error.code = 'EINVAL';
error.errno = -22;
callback(error);
fs.read(fd, buffer, 0, info.size, info.offset, (error: Error) => {
callback(error, encoding ? buffer.toString(encoding) : buffer);
});
};
@@ -573,19 +575,13 @@ export const wrapFsWithAsar = (fs: Record<string, any>) => {
}
const { encoding } = options;
const buffer = Buffer.alloc(info.size);
const fd = archive.getFd();
if (!(fd >= 0)) throw createError(AsarError.NOT_FOUND, { asarPath, filePath });
logASARAccess(asarPath, filePath, info.offset);
let arrayBuffer: ArrayBuffer;
try {
arrayBuffer = archive.readSync(info.offset, info.size);
} catch (err) {
const error: AsarErrorObject = new Error(`EINVAL, ${err.message} while reading ${filePath} in ${asarPath}`);
error.code = 'EINVAL';
error.errno = -22;
throw error;
}
const buffer = Buffer.from(arrayBuffer);
return encoding ? buffer.toString(encoding) : buffer;
fs.readSync(fd, buffer, 0, info.size, info.offset);
return (encoding) ? buffer.toString(encoding) : buffer;
};
const { readdir } = fs;
@@ -695,17 +691,12 @@ export const wrapFsWithAsar = (fs: Record<string, any>) => {
return [str, str.length > 0];
}
const buffer = Buffer.alloc(info.size);
const fd = archive.getFd();
if (!(fd >= 0)) return [];
logASARAccess(asarPath, filePath, info.offset);
let arrayBuffer: ArrayBuffer;
try {
arrayBuffer = archive.readSync(info.offset, info.size);
} catch (err) {
const error: AsarErrorObject = new Error(`EINVAL, ${err.message} while reading ${filePath} in ${asarPath}`);
error.code = 'EINVAL';
error.errno = -22;
throw error;
}
const buffer = Buffer.from(arrayBuffer);
fs.readSync(fd, buffer, 0, info.size, info.offset);
const str = buffer.toString('utf8');
return [str, str.length > 0];
};

View File

@@ -43,7 +43,7 @@ Object.defineProperty(BaseWindow.prototype, 'kiosk', {
});
Object.defineProperty(BaseWindow.prototype, 'documentEdited', {
get: function () { return this.isFullscreen(); },
get: function () { return this.isDocumentEdited(); },
set: function (edited) { this.setDocumentEdited(edited); }
});

View File

@@ -18,7 +18,7 @@ class CrashReporter {
if (submitURL == null) throw new Error('submitURL is a required option to crashReporter.start');
if (!compress) {
if (!compress && uploadToServer) {
deprecate.log('Sending uncompressed crash reports is deprecated and will be removed in a future version of Electron. Set { compress: true } to opt-in to the new behavior. Crash reports will be uploaded gzipped, which most crash reporting servers support.');
}

View File

@@ -119,10 +119,13 @@ class IncomingMessage extends Readable {
this._shouldPush = this.push(chunk);
}
if (this._shouldPush && this._resume) {
this._resume();
// Reset the callback, so that a new one is used for each
// batch of throttled data
// batch of throttled data. Do this before calling resume to avoid a
// potential race-condition
const resume = this._resume;
this._resume = null;
resume();
}
}
@@ -185,6 +188,11 @@ class ChunkedBodyStream extends Writable {
this._downstream = pipe;
if (this._pendingChunk) {
const doneWriting = (maybeError: Error | void) => {
// If the underlying request has been aborted, we honeslty don't care about the error
// all work should cease as soon as we abort anyway, this error is probably a
// "mojo pipe disconnected" error (code=9)
if (this._clientRequest._aborted) return;
const cb = this._pendingCallback!;
delete this._pendingCallback;
delete this._pendingChunk;

View File

@@ -7,8 +7,8 @@ const hiddenProperties = Symbol('hidden touch bar props');
const extendConstructHook = (target: any, hook: Function) => {
const existingHook = target._hook;
target._hook = function () {
hook.call(this);
if (existingHook) existingHook.call(this);
hook.call(this);
};
};
@@ -135,7 +135,7 @@ class TouchBarGroup extends TouchBarItem<Electron.TouchBarGroupConstructorOption
}
}
for (const item of newChild.orderedItems) {
item._addParent(item);
item._addParent(self);
}
})
child!: TouchBar;
@@ -179,7 +179,7 @@ class TouchBarPopover extends TouchBarItem<Electron.TouchBarPopoverConstructorOp
}
}
for (const item of newChild.orderedItems) {
item._addParent(item);
item._addParent(self);
}
})
child!: TouchBar;

View File

@@ -104,6 +104,7 @@ const defaultPrintingSetting = {
pagesPerSheet: 1,
isFirstRequest: false,
previewUIID: 0,
// True, if the document source is modifiable. e.g. HTML and not PDF.
previewModifiable: true,
printToPDF: true,
deviceName: 'Save as PDF',
@@ -131,19 +132,11 @@ WebContents.prototype.postMessage = function (...args) {
};
WebContents.prototype.send = function (channel, ...args) {
if (typeof channel !== 'string') {
throw new Error('Missing required channel argument');
}
return this._send(false /* internal */, channel, args);
return this.mainFrame.send(channel, ...args);
};
WebContents.prototype._sendInternal = function (channel, ...args) {
if (typeof channel !== 'string') {
throw new Error('Missing required channel argument');
}
return this._send(true /* internal */, channel, args);
return this.mainFrame._sendInternal(channel, ...args);
};
function getWebFrame (contents: Electron.WebContents, frame: number | [number, number]) {
@@ -450,7 +443,11 @@ WebContents.prototype._callWindowOpenHandler = function (event: any, url: string
event.preventDefault();
return null;
} else if (response.action === 'allow') {
if (typeof response.overrideBrowserWindowOptions === 'object' && response.overrideBrowserWindowOptions !== null) { return response.overrideBrowserWindowOptions; } else { return {}; }
if (typeof response.overrideBrowserWindowOptions === 'object' && response.overrideBrowserWindowOptions !== null) {
return response.overrideBrowserWindowOptions;
} else {
return {};
}
} else {
event.preventDefault();
console.error('The window open handler response must be an object with an \'action\' property of \'allow\' or \'deny\'.');
@@ -609,20 +606,23 @@ WebContents.prototype._init = function () {
if (this.getType() !== 'remote') {
// Make new windows requested by links behave like "window.open".
this.on('-new-window' as any, (event: any, url: string, frameName: string, disposition: string,
rawFeatures: string, referrer: any, postData: PostData) => {
openGuestWindow({
event,
embedder: event.sender,
disposition,
referrer,
postData,
overrideBrowserWindowOptions: {},
windowOpenArgs: {
url,
frameName,
features: rawFeatures
}
});
rawFeatures: string, referrer: Electron.Referrer, postData: PostData) => {
const options = this._callWindowOpenHandler(event, url, frameName, rawFeatures);
if (!event.defaultPrevented) {
openGuestWindow({
event,
embedder: event.sender,
disposition,
referrer,
postData,
overrideBrowserWindowOptions: options || {},
windowOpenArgs: {
url,
frameName,
features: rawFeatures
}
});
}
});
let windowOpenOverriddenOptions: BrowserWindowConstructorOptions | null = null;
@@ -634,6 +634,7 @@ WebContents.prototype._init = function () {
// it's technically a BrowserWindowConstructorOptions option because
// we need to access it in the renderer at init time.
backgroundColor: windowOpenOverriddenOptions.backgroundColor,
transparent: windowOpenOverriddenOptions.transparent,
...windowOpenOverriddenOptions.webPreferences
} : undefined;
this._setNextChildWebPreferences(

View File

@@ -27,7 +27,7 @@ export const setDefaultApplicationMenu = () => {
{
label: 'Community Discussions',
click: async () => {
await shell.openExternal('https://discuss.atom.io/c/electron');
await shell.openExternal('https://discord.gg/electron');
}
},
{

View File

@@ -59,6 +59,7 @@ export function openGuestWindow ({ event, embedder, guest, referrer, disposition
windowOpenArgs,
additionalFeatures,
disposition,
postData,
referrer
});
if (didCancelEvent) return;
@@ -76,11 +77,14 @@ export function openGuestWindow ({ event, embedder, guest, referrer, disposition
webContents: guest,
...browserWindowOptions
});
if (!isNativeWindowOpen) {
if (!guest) {
// We should only call `loadURL` if the webContents was constructed by us in
// the case of BrowserWindowProxy (non-sandboxed, nativeWindowOpen: false),
// as navigating to the url when creating the window from an existing
// webContents is not necessary (it will navigate there anyway).
// This can also happen if we enter this function from OpenURLFromTab, in
// which case the browser process is responsible for initiating navigation
// in the new window.
window.loadURL(url, {
httpReferrer: referrer,
...(postData && {
@@ -148,7 +152,7 @@ function emitDeprecatedNewWindowEvent ({ event, embedder, guest, windowOpenArgs,
const isWebViewWithPopupsDisabled = embedder.getType() === 'webview' && (embedder as any).getLastWebPreferences().disablePopups;
const postBody = postData ? {
data: postData,
headers: formatPostDataHeaders(postData)
...parseContentTypeFormat(postData)
} : null;
embedder.emit(
@@ -281,22 +285,40 @@ function getDeprecatedInheritedOptions (embedder: WebContents) {
return inheritableOptions;
}
function formatPostDataHeaders (postData: any) {
function formatPostDataHeaders (postData: PostData) {
if (!postData) return;
let extraHeaders = 'content-type: application/x-www-form-urlencoded';
const { contentType, boundary } = parseContentTypeFormat(postData);
if (boundary != null) { return `content-type: ${contentType}; boundary=${boundary}`; }
if (postData.length > 0) {
const postDataFront = postData[0].bytes.toString();
const boundary = /^--.*[^-\r\n]/.exec(
postDataFront
);
if (boundary != null) {
extraHeaders = `content-type: multipart/form-data; boundary=${boundary[0].substr(
2
)}`;
return `content-type: ${contentType}`;
}
const MULTIPART_CONTENT_TYPE = 'multipart/form-data';
const URL_ENCODED_CONTENT_TYPE = 'application/x-www-form-urlencoded';
// Figure out appropriate headers for post data.
const parseContentTypeFormat = function (postData: Exclude<PostData, undefined>) {
if (postData.length) {
if (postData[0].type === 'rawData') {
// For multipart forms, the first element will start with the boundary
// notice, which looks something like `------WebKitFormBoundary12345678`
// Note, this regex would fail when submitting a urlencoded form with an
// input attribute of name="--theKey", but, uhh, don't do that?
const postDataFront = postData[0].bytes.toString();
const boundary = /^--.*[^-\r\n]/.exec(postDataFront);
if (boundary) {
return {
boundary: boundary[0].substr(2),
contentType: MULTIPART_CONTENT_TYPE
};
}
}
}
return extraHeaders;
}
// Either the form submission didn't contain any inputs (the postData array
// was empty), or we couldn't find the boundary and thus we can assume this is
// a key=value style form.
return {
contentType: URL_ENCODED_CONTENT_TYPE
};
};

View File

@@ -82,7 +82,7 @@ const getPreloadScript = async function (preloadPath: string) {
let preloadSrc = null;
let preloadError = null;
try {
preloadSrc = (await fs.promises.readFile(preloadPath)).toString();
preloadSrc = await fs.promises.readFile(preloadPath, 'utf8');
} catch (error) {
preloadError = error;
}

View File

@@ -62,7 +62,7 @@ export function parseCommaSeparatedKeyValue (source: string, useSoonToBeDeprecat
for (const keyValuePair of source.split(',')) {
const [key, value] = keyValuePair.split('=').map(str => str.trim());
if (useSoonToBeDeprecatedBehaviorForBareKeys && value === undefined) {
bareKeys.push(key);
if (key) { bareKeys.push(key); }
continue;
}
parsed[key] = coerce(key, value);

View File

@@ -48,8 +48,10 @@ class WebFrame extends EventEmitter {
}
}
const { hasSwitch } = process._linkedBinding('electron_common_command_line');
const worldSafeJS = hasSwitch('world-safe-execute-javascript') && hasSwitch('context-isolation');
const contextIsolation = binding.getWebPreference(window, 'contextIsolation');
const worldSafeExecuteJavaScript = binding.getWebPreference(window, 'worldSafeExecuteJavaScript');
const worldSafeJS = worldSafeExecuteJavaScript || !contextIsolation;
// Populate the methods.
for (const name in binding) {

View File

@@ -225,7 +225,7 @@ const warnAboutExperimentalFeatures = function (webPreferences?: Electron.WebPre
const warnAboutEnableBlinkFeatures = function (webPreferences?: Electron.WebPreferences) {
if (!webPreferences ||
!Object.prototype.hasOwnProperty.call(webPreferences, 'enableBlinkFeatures') ||
(webPreferences.enableBlinkFeatures && webPreferences.enableBlinkFeatures.length === 0)) {
(webPreferences.enableBlinkFeatures != null && webPreferences.enableBlinkFeatures.length === 0)) {
return;
}

View File

@@ -1,6 +1,6 @@
{
"name": "electron",
"version": "12.0.0-beta.24",
"version": "12.0.5",
"repository": "https://github.com/electron/electron",
"description": "Build cross platform desktop apps with JavaScript, HTML, and CSS",
"devDependencies": {

View File

@@ -1,2 +1,3 @@
expose_ripemd160.patch
expose_aes-cfb.patch
expose_des-ede3.patch

View File

@@ -57,7 +57,7 @@ index 53cb9d2dc8f1962a70dc12b648d27c32be8aca4b..84af06fc56e4aa72d4d48801d7c037ad
callback(EVP_aes_192_ctr(), "aes-192-ctr", NULL, arg);
callback(EVP_aes_256_ctr(), "aes-256-ctr", NULL, arg);
diff --git a/include/openssl/cipher.h b/include/openssl/cipher.h
index 31390a3f63a1e88d50c22fa8c0d3b53610ebda68..792ae8feaa53229e3f6f9130269b268f43ded8d6 100644
index c6bec489b51ca2e71b7f81e64a8e59b534e2e91a..512a9003164e65bd4ab896ef75b173dab3a8d1db 100644
--- a/include/openssl/cipher.h
+++ b/include/openssl/cipher.h
@@ -430,6 +430,7 @@ OPENSSL_EXPORT const EVP_CIPHER *EVP_des_ede3_ecb(void);
@@ -66,5 +66,5 @@ index 31390a3f63a1e88d50c22fa8c0d3b53610ebda68..792ae8feaa53229e3f6f9130269b268f
OPENSSL_EXPORT const EVP_CIPHER *EVP_aes_128_cfb128(void);
+OPENSSL_EXPORT const EVP_CIPHER *EVP_aes_256_cfb128(void);
// EVP_aes_256_cfb128 is only available in decrepit.
OPENSSL_EXPORT const EVP_CIPHER *EVP_aes_256_cfb128(void);
// EVP_aes_128_cfb is an alias for |EVP_aes_128_cfb128| and is only available in
// decrepit.

View File

@@ -0,0 +1,40 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jeremy Rose <nornagon@nornagon.net>
Date: Wed, 24 Feb 2021 11:08:34 -0800
Subject: expose des-ede3
This should be upstreamed.
diff --git a/crypto/cipher_extra/cipher_extra.c b/crypto/cipher_extra/cipher_extra.c
index 588a4773437c311877f275bf3679f9688cda3c46..e771ed6589b4579cc35300d5b2a1b68d92e444f5 100644
--- a/crypto/cipher_extra/cipher_extra.c
+++ b/crypto/cipher_extra/cipher_extra.c
@@ -93,6 +93,8 @@ const EVP_CIPHER *EVP_get_cipherbyname(const char *name) {
return EVP_rc4();
} else if (OPENSSL_strcasecmp(name, "des-cbc") == 0) {
return EVP_des_cbc();
+ } else if (OPENSSL_strcasecmp(name, "des-ede3") == 0) {
+ return EVP_des_ede3();
} else if (OPENSSL_strcasecmp(name, "des-ede3-cbc") == 0 ||
// This is not a name used by OpenSSL, but tcpdump registers it
// with |EVP_add_cipher_alias|. Our |EVP_add_cipher_alias| is a
diff --git a/decrepit/evp/evp_do_all.c b/decrepit/evp/evp_do_all.c
index 84af06fc56e4aa72d4d48801d7c037add0221747..fe412e350f43ad20758025da6b9754952d164938 100644
--- a/decrepit/evp/evp_do_all.c
+++ b/decrepit/evp/evp_do_all.c
@@ -39,6 +39,7 @@ void EVP_CIPHER_do_all_sorted(void (*callback)(const EVP_CIPHER *cipher,
callback(EVP_des_cbc(), "DES-CBC", NULL, arg);
callback(EVP_des_ecb(), "DES-ECB", NULL, arg);
callback(EVP_des_ede(), "DES-EDE", NULL, arg);
+ callback(EVP_des_ede3(), "DES-EDE3", NULL, arg);
callback(EVP_des_ede_cbc(), "DES-EDE-CBC", NULL, arg);
callback(EVP_des_ede3_cbc(), "DES-EDE3-CBC", NULL, arg);
callback(EVP_rc2_cbc(), "RC2-CBC", NULL, arg);
@@ -65,6 +66,7 @@ void EVP_CIPHER_do_all_sorted(void (*callback)(const EVP_CIPHER *cipher,
callback(EVP_des_cbc(), "des-cbc", NULL, arg);
callback(EVP_des_ecb(), "des-ecb", NULL, arg);
callback(EVP_des_ede(), "des-ede", NULL, arg);
+ callback(EVP_des_ede3(), "des-ede3", NULL, arg);
callback(EVP_des_ede_cbc(), "des-ede-cbc", NULL, arg);
callback(EVP_des_ede3_cbc(), "des-ede3-cbc", NULL, arg);
callback(EVP_rc2_cbc(), "rc2-cbc", NULL, arg);

View File

@@ -108,3 +108,8 @@ fix_setparentacessibile_crash_win.patch
fix_export_zlib_symbols.patch
don_t_use_potentially_null_getwebframe_-_view_when_get_blink.patch
cherry-pick-5902d1aa722a.patch
cherry-pick-5c7ad5393f74.patch
word_break_between_space_and_alphanumeric.patch
moves_background_color_setter_of_webview_to_blinks_webprefs_logic.patch
blink_wasm_eval_csp.patch
cherry-pick-162efe98330e.patch

View File

@@ -10,10 +10,10 @@ DidCreateScriptContext is called, not all JS APIs are available in the
context, which can cause some preload scripts to trip.
diff --git a/content/public/renderer/render_frame_observer.h b/content/public/renderer/render_frame_observer.h
index b6b4e0b27ae971f45ab6d50b2eaede6c4d5b7a8d..b785e23bb7e9bb61cb4434ab0bd2b8df9d83caaf 100644
index 0b25680f2998e14ff2b974b373e39439cbb716a9..a7fabf210215d7b1bed3e95d1878a3543796462f 100644
--- a/content/public/renderer/render_frame_observer.h
+++ b/content/public/renderer/render_frame_observer.h
@@ -119,6 +119,8 @@ class CONTENT_EXPORT RenderFrameObserver : public IPC::Listener,
@@ -123,6 +123,8 @@ class CONTENT_EXPORT RenderFrameObserver : public IPC::Listener,
virtual void DidHandleOnloadEvents() {}
virtual void DidCreateScriptContext(v8::Local<v8::Context> context,
int32_t world_id) {}
@@ -23,10 +23,10 @@ index b6b4e0b27ae971f45ab6d50b2eaede6c4d5b7a8d..b785e23bb7e9bb61cb4434ab0bd2b8df
int32_t world_id) {}
virtual void DidClearWindowObject() {}
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc
index 37ea5f46e0f200bcf1229eed3fb17a7de6033c51..cf6ee0109c71123ee8f765b12474b51b109a0c09 100644
index d59a55cc4ec2341e6a12e59a515589aa634f4de5..2dc0c1e0d5bfc32e0d6506d75a0353a2f5c140a6 100644
--- a/content/renderer/render_frame_impl.cc
+++ b/content/renderer/render_frame_impl.cc
@@ -4672,6 +4672,12 @@ void RenderFrameImpl::DidCreateScriptContext(v8::Local<v8::Context> context,
@@ -4691,6 +4691,12 @@ void RenderFrameImpl::DidCreateScriptContext(v8::Local<v8::Context> context,
observer.DidCreateScriptContext(context, world_id);
}
@@ -40,7 +40,7 @@ index 37ea5f46e0f200bcf1229eed3fb17a7de6033c51..cf6ee0109c71123ee8f765b12474b51b
int world_id) {
for (auto& observer : observers_)
diff --git a/content/renderer/render_frame_impl.h b/content/renderer/render_frame_impl.h
index e003c6eec0f629e0ebf0ace81ce0e2534ead3bf2..ae95dd154336c290c9dfe8f7dc0bc5de1467c034 100644
index 1a01e4f9f527fb9c6c63b8a1206f594ec6e3e4f2..b3d91c25ddda2c14a1e5b088acd4d19f828f7bd8 100644
--- a/content/renderer/render_frame_impl.h
+++ b/content/renderer/render_frame_impl.h
@@ -617,6 +617,8 @@ class CONTENT_EXPORT RenderFrameImpl
@@ -53,10 +53,10 @@ index e003c6eec0f629e0ebf0ace81ce0e2534ead3bf2..ae95dd154336c290c9dfe8f7dc0bc5de
int world_id) override;
void DidChangeScrollOffset() override;
diff --git a/third_party/blink/public/web/web_local_frame_client.h b/third_party/blink/public/web/web_local_frame_client.h
index d20c4427399a15a3626c7debfa691950f39ba740..f84d889c7c605d2ce55a20418c37a4337017043f 100644
index 7d32ed800d136b8ae449b4bae302b5bdaf11f13a..84ee1c78f0fbacfe20f69284d79d297dccd7d170 100644
--- a/third_party/blink/public/web/web_local_frame_client.h
+++ b/third_party/blink/public/web/web_local_frame_client.h
@@ -568,6 +568,9 @@ class BLINK_EXPORT WebLocalFrameClient {
@@ -572,6 +572,9 @@ class BLINK_EXPORT WebLocalFrameClient {
virtual void DidCreateScriptContext(v8::Local<v8::Context>,
int32_t world_id) {}
@@ -92,10 +92,10 @@ index 5c171f837c93fa3df33f5230e999a76fbf8d17c8..97f55d0c95f462384fd112a2a16a5170
int32_t world_id) = 0;
virtual bool AllowScriptExtensions() = 0;
diff --git a/third_party/blink/renderer/core/frame/local_frame_client_impl.cc b/third_party/blink/renderer/core/frame/local_frame_client_impl.cc
index 63076a78c9dc145a573cad55cc0d880636fdd972..5f7c14a425d2892affa0c872567be922f05ac096 100644
index fba008f3477648a5abdd0909b89d8d908b9dafac..504ab7bac6623253bbd3e7be756a34af57f368e4 100644
--- a/third_party/blink/renderer/core/frame/local_frame_client_impl.cc
+++ b/third_party/blink/renderer/core/frame/local_frame_client_impl.cc
@@ -415,6 +415,13 @@ void LocalFrameClientImpl::DidCreateScriptContext(
@@ -347,6 +347,13 @@ void LocalFrameClientImpl::DidCreateScriptContext(
web_frame_->Client()->DidCreateScriptContext(context, world_id);
}

View File

@@ -10,7 +10,7 @@ WebContents, and cancels the authentication if there's no WebContents
available, which there isn't in the case of the 'net' module.
diff --git a/services/network/public/mojom/network_context.mojom b/services/network/public/mojom/network_context.mojom
index ac70e294f915f326095675d222f44519e2683ed0..c46465e5596eab620e10faff172f37d71833869f 100644
index 737fc3c70ed0962fa1123c5665706762d7a8238b..9e894008fe949b756d3ee7d28a168c815e5dbcf2 100644
--- a/services/network/public/mojom/network_context.mojom
+++ b/services/network/public/mojom/network_context.mojom
@@ -228,6 +228,25 @@ struct CTPolicy {

View File

@@ -48,10 +48,10 @@ index 9305b576b06a8020583939f357cd42902302b543..d772a31a436bf8f0617d87b5fcf5bd96
// its owning reference back to our owning LocalFrame.
client_->Detached(type);
diff --git a/third_party/blink/renderer/core/frame/local_frame.cc b/third_party/blink/renderer/core/frame/local_frame.cc
index c4d167eff1b6311b834089fccaa636ecad07d680..afce9452ae07f18dd5655c73d3ce548bb7742af4 100644
index 4ceaa30497d240acee5899262f4a119a5a883275..6b70d19009844b074f432ac7566a47aba6aa8882 100644
--- a/third_party/blink/renderer/core/frame/local_frame.cc
+++ b/third_party/blink/renderer/core/frame/local_frame.cc
@@ -621,10 +621,6 @@ bool LocalFrame::DetachImpl(FrameDetachType type) {
@@ -672,10 +672,6 @@ bool LocalFrame::DetachImpl(FrameDetachType type) {
}
DCHECK(!view_ || !view_->IsAttached());
@@ -62,7 +62,7 @@ index c4d167eff1b6311b834089fccaa636ecad07d680..afce9452ae07f18dd5655c73d3ce548b
if (!Client())
return false;
@@ -661,6 +657,10 @@ bool LocalFrame::DetachImpl(FrameDetachType type) {
@@ -716,6 +712,10 @@ bool LocalFrame::DetachImpl(FrameDetachType type) {
DCHECK(!view_->IsAttached());
Client()->WillBeDetached();

View File

@@ -0,0 +1,101 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Cheng Zhao <zcbenz@gmail.com>
Date: Thu, 4 Oct 2018 14:57:02 -0700
Subject: feat: support wasm-eval csp behind WebAssemblyCSP flag
This is a minimal backport of
https://chromium.googlesource.com/chromium/src/+/83913676803db53648b6a47d159102a7cf1dac36
The tracking issue in Chromium is
https://bugs.chromium.org/p/chromium/issues/detail?id=948834
diff --git a/third_party/blink/renderer/core/frame/csp/content_security_policy.cc b/third_party/blink/renderer/core/frame/csp/content_security_policy.cc
index 5e9aef4ef6398035c7a4704667d250d3fd54b25e..f8cf4b30c6ca02883b1c792bdb562c8550e8e17c 100644
--- a/third_party/blink/renderer/core/frame/csp/content_security_policy.cc
+++ b/third_party/blink/renderer/core/frame/csp/content_security_policy.cc
@@ -313,7 +313,8 @@ void ContentSecurityPolicy::CopyPluginTypesFrom(
void ContentSecurityPolicy::DidReceiveHeaders(
const ContentSecurityPolicyResponseHeaders& headers) {
- if (headers.ShouldParseWasmEval())
+ if (RuntimeEnabledFeatures::WebAssemblyCSPEnabled() ||
+ headers.ShouldParseWasmEval())
supports_wasm_eval_ = true;
if (!headers.ContentSecurityPolicy().IsEmpty()) {
AddAndReportPolicyFromHeaderValue(headers.ContentSecurityPolicy(),
diff --git a/third_party/blink/renderer/core/frame/csp/csp_directive_list.cc b/third_party/blink/renderer/core/frame/csp/csp_directive_list.cc
index 0411a75ca40371e1a309efba7b89e32f0edc917e..07b01fc682a172f5ed59c22285f9c968a9992307 100644
--- a/third_party/blink/renderer/core/frame/csp/csp_directive_list.cc
+++ b/third_party/blink/renderer/core/frame/csp/csp_directive_list.cc
@@ -314,9 +314,14 @@ bool CSPDirectiveList::CheckEval(
return !directive || directive->allow_eval;
}
+bool SupportsWasmEval(const ContentSecurityPolicy* policy) {
+ return RuntimeEnabledFeatures::WebAssemblyCSPEnabled() ||
+ policy->SupportsWasmEval();
+}
+
bool CSPDirectiveList::CheckWasmEval(
const network::mojom::blink::CSPSourceList* directive) const {
- return !directive || directive->allow_wasm_eval;
+ return !directive || (SupportsWasmEval(policy_.Get()) && directive->allow_wasm_eval);
}
bool CSPDirectiveList::IsMatchingNoncePresent(
@@ -736,10 +741,14 @@ bool CSPDirectiveList::AllowWasmEval(
ContentSecurityPolicy::ExceptionStatus exception_status,
const String& content) const {
if (reporting_disposition == ReportingDisposition::kReport) {
+ String infix = SupportsWasmEval(policy_.Get())
+ ? "neither 'wasm-eval' nor 'unsafe-eval' is"
+ : "'unsafe-eval' is not";
return CheckWasmEvalAndReportViolation(
- "Refused to compile or instantiate WebAssembly module because "
- "'wasm-eval' is not an allowed source of script in the following "
- "Content Security Policy directive: ",
+ "Refused to compile or instantiate WebAssembly module because " +
+ infix +
+ " an allowed source of script in the following "
+ "Content Security Policy directive: ",
exception_status, content);
}
return IsReportOnly() ||
diff --git a/third_party/blink/renderer/core/frame/csp/source_list_directive.cc b/third_party/blink/renderer/core/frame/csp/source_list_directive.cc
index d28ab719440cde74e82d7d0f557987e50ef7f531..5b44cb7f0203e4cbe8898d1e25cd5c4c080ef5f6 100644
--- a/third_party/blink/renderer/core/frame/csp/source_list_directive.cc
+++ b/third_party/blink/renderer/core/frame/csp/source_list_directive.cc
@@ -403,10 +403,15 @@ bool ParseSource(const UChar* begin,
return true;
}
- if (policy->SupportsWasmEval() &&
- EqualIgnoringASCIICase("'wasm-eval'", token)) {
- source_list.allow_wasm_eval = true;
- return true;
+ // Temporarily behind a runtime feature
+ if (EqualIgnoringASCIICase("'wasm-eval'", token)) {
+ if (RuntimeEnabledFeatures::WebAssemblyCSPEnabled() ||
+ policy->SupportsWasmEval()) {
+ source_list.allow_wasm_eval = true;
+ return true;
+ } else {
+ return false;
+ }
}
if (EqualIgnoringASCIICase("'strict-dynamic'", token)) {
diff --git a/third_party/blink/renderer/platform/runtime_enabled_features.json5 b/third_party/blink/renderer/platform/runtime_enabled_features.json5
index c81216f07beb0fc363b0eb0d6b104031ca2c1992..2aba9f6528569c19461e0084f4a0495dfd6b59ea 100644
--- a/third_party/blink/renderer/platform/runtime_enabled_features.json5
+++ b/third_party/blink/renderer/platform/runtime_enabled_features.json5
@@ -2099,6 +2099,9 @@
{
name: "WebAppWindowControlsOverlay",
},
+ {
+ name: "WebAssemblyCSP",
+ },
{
name: "WebAssemblySimd",
origin_trial_feature_name: "WebAssemblySimd",

View File

@@ -20,7 +20,7 @@ index e397b71732828ffdce2a1a2d006e5f6b0ef531c1..a56deb181dce34de6f9bec459f9745ec
// Executes script in the context of the current page and returns the value
// that the script evaluated to with callback. Script execution can be
diff --git a/third_party/blink/renderer/core/frame/web_local_frame_impl.cc b/third_party/blink/renderer/core/frame/web_local_frame_impl.cc
index 6928b23759b3038ca30988c03531712272b9d4af..64a5c9de299b7aea1e07662078a99acbece397ae 100644
index b4dd040e6e74b1791454c01ef45f6cae780056de..8f8196932b8a13849d092c0b5bffc277b4775785 100644
--- a/third_party/blink/renderer/core/frame/web_local_frame_impl.cc
+++ b/third_party/blink/renderer/core/frame/web_local_frame_impl.cc
@@ -1034,6 +1034,13 @@ v8::Local<v8::Object> WebLocalFrameImpl::GlobalProxy() const {

View File

@@ -9,10 +9,10 @@ potentially prevent a window from being created.
TODO(loc): this patch is currently broken.
diff --git a/content/browser/renderer_host/render_frame_host_impl.cc b/content/browser/renderer_host/render_frame_host_impl.cc
index 13a3539a10c6049a80176b4b96ce0db9ed5bfa0a..993d51d13f7fb7f76cb95aeadfa82c290e916c34 100644
index 0e1a439de32f166818c59cb7aa010544360c9112..2e222a1bf9cb50efa990f875b102001998691f06 100644
--- a/content/browser/renderer_host/render_frame_host_impl.cc
+++ b/content/browser/renderer_host/render_frame_host_impl.cc
@@ -5265,6 +5265,7 @@ void RenderFrameHostImpl::CreateNewWindow(
@@ -5213,6 +5213,7 @@ void RenderFrameHostImpl::CreateNewWindow(
last_committed_origin_, params->window_container_type,
params->target_url, params->referrer.To<Referrer>(),
params->frame_name, params->disposition, *params->features,
@@ -21,10 +21,10 @@ index 13a3539a10c6049a80176b4b96ce0db9ed5bfa0a..993d51d13f7fb7f76cb95aeadfa82c29
&no_javascript_access);
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc
index 0515258d37d3257997945a0d122514ee9fd826ba..cafcbcf04292aa96f5d798e4a3949d8f11ab57b4 100644
index f4751d821d34a998407b37ca4b8221cd8a2ad135..762d4d6164df6f097c3dd77c695a3270a225ec68 100644
--- a/content/browser/web_contents/web_contents_impl.cc
+++ b/content/browser/web_contents/web_contents_impl.cc
@@ -3551,6 +3551,14 @@ RenderFrameHostDelegate* WebContentsImpl::CreateNewWindow(
@@ -3560,6 +3560,14 @@ RenderFrameHostDelegate* WebContentsImpl::CreateNewWindow(
}
auto* new_contents_impl = new_contents.get();
@@ -39,7 +39,7 @@ index 0515258d37d3257997945a0d122514ee9fd826ba..cafcbcf04292aa96f5d798e4a3949d8f
new_contents_impl->GetController().SetSessionStorageNamespace(
partition_id, session_storage_namespace);
@@ -3592,12 +3600,6 @@ RenderFrameHostDelegate* WebContentsImpl::CreateNewWindow(
@@ -3601,12 +3609,6 @@ RenderFrameHostDelegate* WebContentsImpl::CreateNewWindow(
AddDestructionObserver(new_contents_impl);
}
@@ -53,10 +53,10 @@ index 0515258d37d3257997945a0d122514ee9fd826ba..cafcbcf04292aa96f5d798e4a3949d8f
observer->DidOpenRequestedURL(new_contents_impl, opener, params.target_url,
params.referrer.To<Referrer>(),
diff --git a/content/common/frame.mojom b/content/common/frame.mojom
index 99db7bea2f2e15ceae8644c8c655ed5ca3de31a2..1f667422812b91553a5a387b08bbff718668e263 100644
index 182c6bf04e9937080efcedfc617fb9e072f10500..6fb3a1ee4a31e9a228e8ab04b1ce21c8af50ae74 100644
--- a/content/common/frame.mojom
+++ b/content/common/frame.mojom
@@ -310,6 +310,10 @@ struct CreateNewWindowParams {
@@ -330,6 +330,10 @@ struct CreateNewWindowParams {
// The impression associated with the navigation in the new window, if
// one is specified.
Impression? impression;
@@ -68,10 +68,10 @@ index 99db7bea2f2e15ceae8644c8c655ed5ca3de31a2..1f667422812b91553a5a387b08bbff71
// Operation result when the renderer asks the browser to create a new window.
diff --git a/content/public/browser/content_browser_client.cc b/content/public/browser/content_browser_client.cc
index 4438e0417b3cc11fad98ce792eaaf12710539fae..e9e45bacdcc5ad09ac933ccaaa663e0d05a0ad33 100644
index c84ae68f2f271185e6021fcd0b41fe68c42a17e7..b84afa745f7a2b378f7cda18b7cdbb5357e2234c 100644
--- a/content/public/browser/content_browser_client.cc
+++ b/content/public/browser/content_browser_client.cc
@@ -544,6 +544,8 @@ bool ContentBrowserClient::CanCreateWindow(
@@ -554,6 +554,8 @@ bool ContentBrowserClient::CanCreateWindow(
const std::string& frame_name,
WindowOpenDisposition disposition,
const blink::mojom::WindowFeatures& features,
@@ -81,10 +81,10 @@ index 4438e0417b3cc11fad98ce792eaaf12710539fae..e9e45bacdcc5ad09ac933ccaaa663e0d
bool opener_suppressed,
bool* no_javascript_access) {
diff --git a/content/public/browser/content_browser_client.h b/content/public/browser/content_browser_client.h
index df6e463d1518b453aae79dffdda559a93eba1f9d..133aef45c3187fac0e47e1538df3252de1fdfb8c 100644
index c4fc708ab2789d2cf873bb8a5cff64259ab1d184..a9b4f7770a04d713de363c80c3a0f2b107b6d426 100644
--- a/content/public/browser/content_browser_client.h
+++ b/content/public/browser/content_browser_client.h
@@ -154,6 +154,7 @@ class NetworkService;
@@ -155,6 +155,7 @@ class NetworkService;
class TrustedURLLoaderHeaderClient;
} // namespace mojom
struct ResourceRequest;
@@ -92,7 +92,7 @@ index df6e463d1518b453aae79dffdda559a93eba1f9d..133aef45c3187fac0e47e1538df3252d
} // namespace network
namespace sandbox {
@@ -881,6 +882,8 @@ class CONTENT_EXPORT ContentBrowserClient {
@@ -905,6 +906,8 @@ class CONTENT_EXPORT ContentBrowserClient {
const std::string& frame_name,
WindowOpenDisposition disposition,
const blink::mojom::WindowFeatures& features,
@@ -150,11 +150,11 @@ index 21d30d1b60ba870a35be87f8d1823ef5e3902a01..73b85693d59f25160df21c3b535869b3
// typically happens when popups are created.
virtual void WebContentsCreated(WebContents* source_contents,
diff --git a/content/renderer/render_view_impl.cc b/content/renderer/render_view_impl.cc
index 3128b21c95c7b4535787142b6250b77f2c58b269..087b9891b2f79b54cd22cf8dc3591fa6dde79579 100644
index 7fc0a7edbfe1f274ed685277d3a5d4b560dd87d2..5efeed6fdf1e9f707db658a0da3408e16a6a66e0 100644
--- a/content/renderer/render_view_impl.cc
+++ b/content/renderer/render_view_impl.cc
@@ -28,6 +28,7 @@
#include "third_party/blink/public/common/features.h"
#include "third_party/blink/public/platform/impression_conversions.h"
#include "third_party/blink/public/platform/modules/video_capture/web_video_capture_impl_manager.h"
#include "third_party/blink/public/platform/url_conversion.h"
+#include "third_party/blink/public/platform/web_url_request_util.h"
@@ -163,7 +163,7 @@ index 3128b21c95c7b4535787142b6250b77f2c58b269..087b9891b2f79b54cd22cf8dc3591fa6
#include "third_party/blink/public/web/web_local_frame.h"
@@ -385,6 +386,9 @@ WebView* RenderViewImpl::CreateView(
if (impression) {
params->impression = ConvertWebImpressionToImpression(*impression);
params->impression = blink::ConvertWebImpressionToImpression(*impression);
}
+ params->raw_features = features.raw_features.Utf8(
+ WTF::UTF8ConversionMode::kStrictUTF8ConversionReplacingUnpairedSurrogatesWithFFFD);
@@ -220,10 +220,10 @@ index 4f735ad0d97eaac9a57dad137e479f8a7ec33a36..0a3c5821962c85609b64b3625fa6b8d6
} // namespace blink
diff --git a/third_party/blink/renderer/core/frame/local_dom_window.cc b/third_party/blink/renderer/core/frame/local_dom_window.cc
index a20d3082ed631ff7c7066ce2f20ed687469b17ce..84b8fb235826c9a5de4dbbd79aa3b6af0ed786cf 100644
index 74539b9e48b034355e67e43eb528e8597d4cefdd..1cd316f90a037d8736e89bbfb28fb26523ccd97b 100644
--- a/third_party/blink/renderer/core/frame/local_dom_window.cc
+++ b/third_party/blink/renderer/core/frame/local_dom_window.cc
@@ -2001,6 +2001,7 @@ DOMWindow* LocalDOMWindow::open(v8::Isolate* isolate,
@@ -2019,6 +2019,7 @@ DOMWindow* LocalDOMWindow::open(v8::Isolate* isolate,
}
WebWindowFeatures window_features = GetWindowFeaturesFromString(features);

View File

@@ -0,0 +1,204 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Sigurdur Asgeirsson <siggi@chromium.org>
Date: Thu, 11 Mar 2021 21:18:42 +0000
Subject: Reland "Use a timer instead of a sleep loop."
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This is a reland of ec21b4b42aa7ccebe79bfbee7db87c9cba20979a
Original change's description:
> Use a timer instead of a sleep loop.
>
> This paves the way for implementing timer slack on the kqueue
> message pump.
>
> Bug: 1181297
> Change-Id: I74fdb63e85cf726000ee94b5851f84b06de314ae
> Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2713848
> Auto-Submit: Sigurður Ásgeirsson <siggi@chromium.org>
> Reviewed-by: Mark Mentovai <mark@chromium.org>
> Reviewed-by: Etienne Pierre-Doray <etiennep@chromium.org>
> Reviewed-by: Robert Sesek <rsesek@chromium.org>
> Commit-Queue: Sigurður Ásgeirsson <siggi@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#857894}
Bug: 1181297
Change-Id: I63287f8d53f0aee9833d090ef6d32aa94698c692
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2753412
Reviewed-by: Robert Sesek <rsesek@chromium.org>
Reviewed-by: Mark Mentovai <mark@chromium.org>
Reviewed-by: Etienne Pierre-Doray <etiennep@chromium.org>
Commit-Queue: Sigurður Ásgeirsson <siggi@chromium.org>
Cr-Commit-Position: refs/heads/master@{#862125}
diff --git a/base/message_loop/message_pump_kqueue.cc b/base/message_loop/message_pump_kqueue.cc
index 9a0be64d50a8460bd80615f83e6d41d71c65e586..4a01b36db138a43c39196206b8dd015c9700c8c3 100644
--- a/base/message_loop/message_pump_kqueue.cc
+++ b/base/message_loop/message_pump_kqueue.cc
@@ -12,6 +12,7 @@
#include "base/mac/mach_logging.h"
#include "base/mac/scoped_nsautorelease_pool.h"
#include "base/posix/eintr_wrapper.h"
+#include "base/time/time_override.h"
namespace base {
@@ -21,10 +22,22 @@ namespace {
// port sets. MessagePumpKqueue will directly use Mach ports in the kqueue if
// it is possible.
bool KqueueNeedsPortSet() {
- static bool kqueue_needs_port_set = mac::IsAtMostOS10_11();
+ static const bool kqueue_needs_port_set = mac::IsAtMostOS10_11();
return kqueue_needs_port_set;
}
+#if DCHECK_IS_ON()
+// Prior to macOS 10.14, kqueue timers may spuriously wake up, because earlier
+// wake ups race with timer resets in the kernel. As of macOS 10.14, updating a
+// timer from the thread that reads the kqueue does not cause spurious wakeups.
+// Note that updating a kqueue timer from one thread while another thread is
+// waiting in a kevent64 invocation is still (inherently) racy.
+bool KqueueTimersSpuriouslyWakeUp() {
+ static const bool kqueue_timers_spuriously_wakeup = mac::IsAtMostOS10_13();
+ return kqueue_timers_spuriously_wakeup;
+}
+#endif
+
int ChangeOneEvent(const ScopedFD& kqueue, kevent64_s* event) {
return HANDLE_EINTR(kevent64(kqueue.get(), event, 1, nullptr, 0, 0, nullptr));
}
@@ -364,25 +377,13 @@ bool MessagePumpKqueue::DoInternalWork(Delegate::NextWorkInfo* next_work_info) {
bool poll = next_work_info == nullptr;
int flags = poll ? KEVENT_FLAG_IMMEDIATE : 0;
- bool indefinite =
- next_work_info != nullptr && next_work_info->delayed_run_time.is_max();
-
- int rv = 0;
- do {
- timespec timeout{};
- if (!indefinite && !poll) {
- if (rv != 0) {
- // The wait was interrupted and made |next_work_info|'s view of
- // TimeTicks::Now() stale. Refresh it before doing another wait.
- next_work_info->recent_now = TimeTicks::Now();
- }
- timeout = next_work_info->remaining_delay().ToTimeSpec();
- }
- // This does not use HANDLE_EINTR, since retrying the syscall requires
- // adjusting the timeout to account for time already waited.
- rv = kevent64(kqueue_.get(), nullptr, 0, events_.data(), events_.size(),
- flags, indefinite ? nullptr : &timeout);
- } while (rv < 0 && errno == EINTR);
+ if (!poll && scheduled_wakeup_time_ != next_work_info->delayed_run_time) {
+ UpdateWakeupTimer(next_work_info->delayed_run_time);
+ DCHECK_EQ(scheduled_wakeup_time_, next_work_info->delayed_run_time);
+ }
+
+ int rv = HANDLE_EINTR(kevent64(kqueue_.get(), nullptr, 0, events_.data(),
+ events_.size(), flags, nullptr));
PCHECK(rv >= 0) << "kevent64";
return ProcessEvents(rv);
@@ -445,6 +446,25 @@ bool MessagePumpKqueue::ProcessEvents(int count) {
if (controller) {
controller->watcher()->OnMachMessageReceived(port);
}
+ } else if (event->filter == EVFILT_TIMER) {
+ // The wakeup timer fired.
+#if DCHECK_IS_ON()
+ // On macOS 10.13 and earlier, kqueue timers may spuriously wake up.
+ // When this happens, the timer will be re-scheduled the next time
+ // DoInternalWork is entered, which means this doesn't lead to a
+ // spinning wait.
+ // When clock overrides are active, TimeTicks::Now may be decoupled from
+ // wall-clock time, and can therefore not be used to validate whether the
+ // expected wall-clock time has passed.
+ if (!KqueueTimersSpuriouslyWakeUp() &&
+ !subtle::ScopedTimeClockOverrides::overrides_active()) {
+ // Given the caveats above, assert that the timer didn't fire early.
+ DCHECK_LE(scheduled_wakeup_time_, base::TimeTicks::Now());
+ }
+#endif
+ DCHECK_NE(scheduled_wakeup_time_, base::TimeTicks::Max());
+ scheduled_wakeup_time_ = base::TimeTicks::Max();
+ --event_count_;
} else {
NOTREACHED() << "Unexpected event for filter " << event->filter;
}
@@ -453,4 +473,47 @@ bool MessagePumpKqueue::ProcessEvents(int count) {
return did_work;
}
+void MessagePumpKqueue::UpdateWakeupTimer(const base::TimeTicks& wakeup_time) {
+ DCHECK_NE(wakeup_time, scheduled_wakeup_time_);
+
+ // The ident of the wakeup timer. There's only the one timer as the pair
+ // (ident, filter) is the identity of the event.
+ constexpr uint64_t kWakeupTimerIdent = 0x0;
+ if (wakeup_time == base::TimeTicks::Max()) {
+ // Clear the timer.
+ kevent64_s timer{};
+ timer.ident = kWakeupTimerIdent;
+ timer.filter = EVFILT_TIMER;
+ timer.flags = EV_DELETE;
+
+ int rv = ChangeOneEvent(kqueue_, &timer);
+ PCHECK(rv == 0) << "kevent64, delete timer";
+ --event_count_;
+ } else {
+ // Set/reset the timer.
+ kevent64_s timer{};
+ timer.ident = kWakeupTimerIdent;
+ timer.filter = EVFILT_TIMER;
+ // This updates the timer if it already exists in |kqueue_|.
+ timer.flags = EV_ADD | EV_ONESHOT;
+ // Specify the sleep in microseconds to avoid undersleeping due to
+ // numeric problems. The sleep is computed from TimeTicks::Now rather than
+ // NextWorkInfo::recent_now because recent_now is strictly earlier than
+ // current wall-clock. Using an earlier wall clock time to compute the
+ // delta to the next wakeup wall-clock time would guarantee oversleep.
+ // If wakeup_time is in the past, the delta below will be negative and the
+ // timer is set immediately.
+ timer.fflags = NOTE_USECONDS;
+ timer.data = (wakeup_time - base::TimeTicks::Now()).InMicroseconds();
+ int rv = ChangeOneEvent(kqueue_, &timer);
+ PCHECK(rv == 0) << "kevent64, set timer";
+
+ // Bump the event count if we just added the timer.
+ if (scheduled_wakeup_time_ == base::TimeTicks::Max())
+ ++event_count_;
+ }
+
+ scheduled_wakeup_time_ = wakeup_time;
+}
+
} // namespace base
diff --git a/base/message_loop/message_pump_kqueue.h b/base/message_loop/message_pump_kqueue.h
index 9acfcf22c3e0643000938ae1804eaeb4bbf7bd69..824d90fe2ab3083b094bb1a3ab1a0840f98b89f1 100644
--- a/base/message_loop/message_pump_kqueue.h
+++ b/base/message_loop/message_pump_kqueue.h
@@ -136,6 +136,10 @@ class BASE_EXPORT MessagePumpKqueue : public MessagePump,
// true if work was done, or false if no work was done.
bool ProcessEvents(int count);
+ // Sets the wakeup timer to |wakeup_time|, or clears it if |wakeup_time| is
+ // base::TimeTicks::Max(). Updates |scheduled_wakeup_time_| to follow.
+ void UpdateWakeupTimer(const base::TimeTicks& wakeup_time);
+
// Receive right to which an empty Mach message is sent to wake up the pump
// in response to ScheduleWork().
mac::ScopedMachReceiveRight wakeup_;
@@ -159,6 +163,10 @@ class BASE_EXPORT MessagePumpKqueue : public MessagePump,
// Whether the pump has been Quit() or not.
bool keep_running_ = true;
+ // The currently scheduled wakeup, if any. If no wakeup is scheduled,
+ // contains base::TimeTicks::Max().
+ base::TimeTicks scheduled_wakeup_time_{base::TimeTicks::Max()};
+
// The number of events scheduled on the |kqueue_|. There is always at least
// 1, for the |wakeup_| port (or |port_set_|).
size_t event_count_ = 1;

View File

@@ -0,0 +1,298 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Martin Robinson <mrobinson@igalia.com>
Date: Mon, 25 Jan 2021 14:27:23 +0000
Subject: Mac a11y: Use the keyboard focusable element for
NSAccessibilityTextChangeElement
When setting the NSAccessibilityTextChangeElement property for
NSAccessibilitySelectedTextChangedNotifications, use the keyboard
focusable element instead of the element that has the focus side of the
text selection. Using the latter, when the element is an empty group,
VoiceOver will focus the containing Web View (when using the VO
cursor follows keyboard focus setting). This makes it impossible to use
the down keyboard key to move past these empty nodes.
VoiceOver cursor" setting in contenteditable nodes.
AX-Relnotes: Fix a bug with the "Synchronize keyboard focus and
Bug: 952922
Change-Id: I3627936726f89b01132c32bd5d83758fc7c3dac4
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2642686
Auto-Submit: Martin Robinson <mrobinson@igalia.com>
Commit-Queue: Nektarios Paisios <nektar@chromium.org>
Reviewed-by: Nektarios Paisios <nektar@chromium.org>
Cr-Commit-Position: refs/heads/master@{#846707}
diff --git a/content/browser/accessibility/browser_accessibility_cocoa_browsertest.mm b/content/browser/accessibility/browser_accessibility_cocoa_browsertest.mm
index 03b84fa0963df86c699c4c0a56ca527d5b50a46c..9d042a004217ec5c182bf562207c86cb967df2d2 100644
--- a/content/browser/accessibility/browser_accessibility_cocoa_browsertest.mm
+++ b/content/browser/accessibility/browser_accessibility_cocoa_browsertest.mm
@@ -20,12 +20,11 @@
#include "net/base/data_url.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "testing/gtest_mac.h"
+#include "ui/accessibility/platform/ax_private_webkit_constants_mac.h"
#include "url/gurl.h"
namespace content {
-namespace {
-
class BrowserAccessibilityCocoaBrowserTest : public ContentBrowserTest {
public:
BrowserAccessibilityCocoaBrowserTest() {}
@@ -73,6 +72,11 @@ void FocusAccessibilityElementAndWaitForFocusChange(
WaitForAccessibilityFocusChange();
}
+ NSDictionary* GetUserInfoForSelectedTextChangedNotification() {
+ auto* manager = static_cast<BrowserAccessibilityManagerMac*>(GetManager());
+ return manager->GetUserInfoForSelectedTextChangedNotification();
+ }
+
private:
BrowserAccessibility* FindNodeInSubtree(BrowserAccessibility& node,
ax::mojom::Role role) {
@@ -89,8 +93,6 @@ void FocusAccessibilityElementAndWaitForFocusChange(
}
};
-} // namespace
-
IN_PROC_BROWSER_TEST_F(BrowserAccessibilityCocoaBrowserTest,
AXTextMarkerForTextEdit) {
EXPECT_TRUE(NavigateToURL(shell(), GURL(url::kAboutBlankURL)));
@@ -106,12 +108,11 @@ GURL url(R"HTML(data:text/html,
BrowserAccessibility* text_field = FindNode(ax::mojom::Role::kTextField);
ASSERT_NE(nullptr, text_field);
- EXPECT_TRUE(content::ExecuteScript(
- shell()->web_contents(), "document.querySelector('input').focus()"));
+ EXPECT_TRUE(ExecuteScript(shell()->web_contents(),
+ "document.querySelector('input').focus()"));
- content::SimulateKeyPress(shell()->web_contents(),
- ui::DomKey::FromCharacter('B'), ui::DomCode::US_B,
- ui::VKEY_B, false, false, false, false);
+ SimulateKeyPress(shell()->web_contents(), ui::DomKey::FromCharacter('B'),
+ ui::DomCode::US_B, ui::VKEY_B, false, false, false, false);
base::scoped_nsobject<BrowserAccessibilityCocoa> cocoa_text_field(
[ToBrowserAccessibilityCocoa(text_field) retain]);
@@ -122,10 +123,9 @@ AccessibilityNotificationWaiter value_waiter(shell()->web_contents(),
AXTextEdit text_edit = [cocoa_text_field computeTextEdit];
EXPECT_NE(text_edit.edit_text_marker, nil);
- EXPECT_EQ(
- content::AXTextMarkerToPosition(text_edit.edit_text_marker)->ToString(),
- "TextPosition anchor_id=4 text_offset=1 affinity=downstream "
- "annotated_text=B<>");
+ EXPECT_EQ(AXTextMarkerToPosition(text_edit.edit_text_marker)->ToString(),
+ "TextPosition anchor_id=4 text_offset=1 affinity=downstream "
+ "annotated_text=B<>");
}
IN_PROC_BROWSER_TEST_F(BrowserAccessibilityCocoaBrowserTest,
@@ -604,7 +604,7 @@ GURL url(R"HTML(data:text/html,
ASSERT_NSEQ(@"AXRow", [tree_children[0] role]);
ASSERT_NSEQ(@"AXRow", [tree_children[1] role]);
- content::RenderProcessHost* render_process_host =
+ RenderProcessHost* render_process_host =
shell()->web_contents()->GetMainFrame()->GetProcess();
auto menu_filter = base::MakeRefCounted<ContextMenuFilter>(
ContextMenuFilter::ShowBehavior::kPreventShow);
@@ -619,9 +619,8 @@ GURL url(R"HTML(data:text/html,
EXPECT_NE(tree_point, item_2_point);
// Now focus the second child and trigger a context menu on the tree.
- ASSERT_TRUE(
- content::ExecuteScript(shell()->web_contents(),
- "document.body.children[0].children[1].focus();"));
+ ASSERT_TRUE(ExecuteScript(shell()->web_contents(),
+ "document.body.children[0].children[1].focus();"));
WaitForAccessibilityFocusChange();
// Triggering a context menu on the tree should now trigger the menu
@@ -741,4 +740,63 @@ GURL url(R"HTML(data:text/html,
}
}
+IN_PROC_BROWSER_TEST_F(BrowserAccessibilityCocoaBrowserTest,
+ TestNSAccessibilityTextChangeElement) {
+ AccessibilityNotificationWaiter waiter(shell()->web_contents(),
+ ui::kAXModeComplete,
+ ax::mojom::Event::kLoadComplete);
+
+ GURL url(R"HTML(data:text/html,
+ <div id="editable" contenteditable="true" dir="auto">
+ <p>One</p>
+ <p>Two</p>
+ <p><br></p>
+ <p>Three</p>
+ <p>Four</p>
+ </div>)HTML");
+
+ ASSERT_TRUE(NavigateToURL(shell(), url));
+ waiter.WaitForNotification();
+
+ base::scoped_nsobject<BrowserAccessibilityCocoa> content_editable(
+ [ToBrowserAccessibilityCocoa(GetManager()->GetRoot()->PlatformGetChild(0))
+ retain]);
+ EXPECT_EQ([[content_editable children] count], 5ul);
+
+ WebContents* web_contents = shell()->web_contents();
+ auto run_script_and_wait_for_selection_change =
+ [web_contents](const char* script) {
+ AccessibilityNotificationWaiter waiter(
+ web_contents, ui::kAXModeComplete,
+ ax::mojom::Event::kTextSelectionChanged);
+ ASSERT_TRUE(ExecuteScript(web_contents, script));
+ waiter.WaitForNotification();
+ };
+
+ FocusAccessibilityElementAndWaitForFocusChange(content_editable);
+
+ run_script_and_wait_for_selection_change(R"script(
+ let editable = document.getElementById('editable');
+ const selection = window.getSelection();
+ selection.collapse(editable.children[0].childNodes[0], 1);)script");
+
+ // The focused node in the user info should be the keyboard focusable
+ // ancestor.
+ NSDictionary* info = GetUserInfoForSelectedTextChangedNotification();
+ EXPECT_EQ(id{content_editable},
+ [info objectForKey:ui::NSAccessibilityTextChangeElement]);
+
+ AccessibilityNotificationWaiter waiter2(
+ web_contents, ui::kAXModeComplete,
+ ax::mojom::Event::kTextSelectionChanged);
+ run_script_and_wait_for_selection_change(
+ "selection.collapse(editable.children[2].childNodes[0], 0);");
+
+ // Even when the cursor is in the empty paragraph text node, the focused
+ // object should be the keyboard focusable ancestor.
+ info = GetUserInfoForSelectedTextChangedNotification();
+ EXPECT_EQ(id{content_editable},
+ [info objectForKey:ui::NSAccessibilityTextChangeElement]);
+}
+
} // namespace content
diff --git a/content/browser/accessibility/browser_accessibility_manager_mac.h b/content/browser/accessibility/browser_accessibility_manager_mac.h
index 925bfe1ea191ab846805fdbff1b0314e779b1c9e..5488245e22b883105dbe1e225156ab18e1a64534 100644
--- a/content/browser/accessibility/browser_accessibility_manager_mac.h
+++ b/content/browser/accessibility/browser_accessibility_manager_mac.h
@@ -19,6 +19,8 @@
namespace content {
+class BrowserAccessibilityCocoaBrowserTest;
+
class CONTENT_EXPORT BrowserAccessibilityManagerMac
: public BrowserAccessibilityManager {
public:
@@ -54,8 +56,7 @@ class CONTENT_EXPORT BrowserAccessibilityManagerMac
const std::vector<Change>& changes) override;
// Returns an autoreleased object.
- NSDictionary* GetUserInfoForSelectedTextChangedNotification(
- bool focus_changed);
+ NSDictionary* GetUserInfoForSelectedTextChangedNotification();
// Returns an autoreleased object.
NSDictionary* GetUserInfoForValueChangedNotification(
@@ -80,6 +81,8 @@ class CONTENT_EXPORT BrowserAccessibilityManagerMac
// constructor.
friend class BrowserAccessibilityManager;
+ friend class BrowserAccessibilityCocoaBrowserTest;
+
DISALLOW_COPY_AND_ASSIGN(BrowserAccessibilityManagerMac);
};
diff --git a/content/browser/accessibility/browser_accessibility_manager_mac.mm b/content/browser/accessibility/browser_accessibility_manager_mac.mm
index 93bcc87244d41c6b72908ed31f83cdd629f6e69f..bbffc89e4f6f2f7b85d285de24120ade082a0090 100644
--- a/content/browser/accessibility/browser_accessibility_manager_mac.mm
+++ b/content/browser/accessibility/browser_accessibility_manager_mac.mm
@@ -131,8 +131,6 @@ void PostAnnouncementNotification(NSString* announcement) {
auto native_node = ToBrowserAccessibilityCocoa(node);
DCHECK(native_node);
- bool focus_changed = GetFocus() != GetLastFocusedNode();
-
// Refer to |AXObjectCache::postPlatformNotification| in WebKit source code.
NSString* mac_notification = nullptr;
switch (event_type) {
@@ -183,8 +181,7 @@ void PostAnnouncementNotification(NSString* announcement) {
if (!focus)
break; // Just fire a notification on the root.
- NSDictionary* user_info =
- GetUserInfoForSelectedTextChangedNotification(focus_changed);
+ NSDictionary* user_info = GetUserInfoForSelectedTextChangedNotification();
BrowserAccessibilityManager* root_manager = GetRootManager();
if (!root_manager)
@@ -452,9 +449,8 @@ void PostAnnouncementNotification(NSString* announcement) {
}
}
-NSDictionary*
-BrowserAccessibilityManagerMac::GetUserInfoForSelectedTextChangedNotification(
- bool focus_changed) {
+NSDictionary* BrowserAccessibilityManagerMac::
+ GetUserInfoForSelectedTextChangedNotification() {
NSMutableDictionary* user_info =
[[[NSMutableDictionary alloc] init] autorelease];
[user_info setObject:@YES forKey:ui::NSAccessibilityTextStateSyncKey];
@@ -471,7 +467,10 @@ void PostAnnouncementNotification(NSString* announcement) {
// TODO(mrobinson): Determine definitively what the type of this text
// selection change is. This requires passing this information here from
// blink.
- if (focus_changed) {
+ BrowserAccessibility* focused_accessibility = GetFocus();
+ DCHECK(focused_accessibility);
+
+ if (focused_accessibility != GetLastFocusedNode()) {
[user_info setObject:@(ui::AXTextStateChangeTypeSelectionMove)
forKey:ui::NSAccessibilityTextStateChangeTypeKey];
} else {
@@ -479,25 +478,22 @@ void PostAnnouncementNotification(NSString* announcement) {
forKey:ui::NSAccessibilityTextStateChangeTypeKey];
}
- int32_t focus_id = ax_tree()->GetUnignoredSelection().focus_object_id;
- BrowserAccessibility* focus_object = GetFromID(focus_id);
- if (focus_object) {
- focus_object = focus_object->PlatformGetClosestPlatformObject();
- auto native_focus_object = ToBrowserAccessibilityCocoa(focus_object);
- if (native_focus_object && [native_focus_object instanceActive]) {
- [user_info setObject:native_focus_object
- forKey:ui::NSAccessibilityTextChangeElement];
+ focused_accessibility =
+ focused_accessibility->PlatformGetClosestPlatformObject();
+ auto native_focus_object = ToBrowserAccessibilityCocoa(focused_accessibility);
+ if (native_focus_object && [native_focus_object instanceActive]) {
+ [user_info setObject:native_focus_object
+ forKey:ui::NSAccessibilityTextChangeElement];
#ifndef MAS_BUILD
- id selected_text = [native_focus_object selectedTextMarkerRange];
- if (selected_text) {
- NSString* const NSAccessibilitySelectedTextMarkerRangeAttribute =
- @"AXSelectedTextMarkerRange";
- [user_info setObject:selected_text
- forKey:NSAccessibilitySelectedTextMarkerRangeAttribute];
- }
-#endif
+ id selected_text = [native_focus_object selectedTextMarkerRange];
+ if (selected_text) {
+ NSString* const NSAccessibilitySelectedTextMarkerRangeAttribute =
+ @"AXSelectedTextMarkerRange";
+ [user_info setObject:selected_text
+ forKey:NSAccessibilitySelectedTextMarkerRangeAttribute];
}
+#endif
}
return user_info;

View File

@@ -140,10 +140,10 @@ index dc7f3bc886e7130c66d98ae6de73c17db746cbe5..6197db3570c860f39f381370e1af37f8
}
diff --git a/chrome/browser/ui/browser.cc b/chrome/browser/ui/browser.cc
index 1dc23535c42aec292e94a09e9fd2d1c7f37e82cd..01cea80d1fe0effeaf200fb6988df7f89787441a 100644
index 409f908148b3d2885216a12048fc3f2e3ea47c89..d43be2439324753f504109f3a3fc0a4f3799bee5 100644
--- a/chrome/browser/ui/browser.cc
+++ b/chrome/browser/ui/browser.cc
@@ -1802,12 +1802,11 @@ bool Browser::IsWebContentsCreationOverridden(
@@ -1804,12 +1804,11 @@ bool Browser::IsWebContentsCreationOverridden(
content::SiteInstance* source_site_instance,
content::mojom::WindowContainerType window_container_type,
const GURL& opener_url,
@@ -159,10 +159,10 @@ index 1dc23535c42aec292e94a09e9fd2d1c7f37e82cd..01cea80d1fe0effeaf200fb6988df7f8
WebContents* Browser::CreateCustomWebContents(
diff --git a/chrome/browser/ui/browser.h b/chrome/browser/ui/browser.h
index 7287ec00c3f57a8e10c4329f181bcdccaed7177d..81b7395aec797c201465164437441cbca6e99e0d 100644
index 1ccab44183bf3d47762cff2198231e3fda9c53fc..7fc6a35ddee24340913f03c23fe7b8f80a102398 100644
--- a/chrome/browser/ui/browser.h
+++ b/chrome/browser/ui/browser.h
@@ -784,8 +784,7 @@ class Browser : public TabStripModelObserver,
@@ -791,8 +791,7 @@ class Browser : public TabStripModelObserver,
content::SiteInstance* source_site_instance,
content::mojom::WindowContainerType window_container_type,
const GURL& opener_url,
@@ -264,10 +264,10 @@ index c5c5a7b63b5b3b62a9517cbef3ae23ce57a3c89c..4f1b7e88d6d2ae89a60311c8aeb1fcee
void AddNewContents(content::WebContents* source,
std::unique_ptr<content::WebContents> new_contents,
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc
index 677eb591272146afc61af934f29ca34b170bfb04..037896b77aa26dbae2001cc7ad39457d31db924e 100644
index a2bce274bdd70c0481a1bc75d449bfadf7b91618..af8196ef8a368b6e91703a8b91db58b94417a182 100644
--- a/content/browser/web_contents/web_contents_impl.cc
+++ b/content/browser/web_contents/web_contents_impl.cc
@@ -3512,8 +3512,7 @@ RenderFrameHostDelegate* WebContentsImpl::CreateNewWindow(
@@ -3521,8 +3521,7 @@ RenderFrameHostDelegate* WebContentsImpl::CreateNewWindow(
if (delegate_ && delegate_->IsWebContentsCreationOverridden(
source_site_instance, params.window_container_type,
@@ -362,7 +362,7 @@ index a7f0b19a8ab9bac6f1315ebd715d8e1b134edfe1..cbe2912d4ab2d9015396bbddf7836e10
content::RenderFrameHost* opener,
content::SiteInstance* source_site_instance,
diff --git a/fuchsia/engine/browser/frame_impl.cc b/fuchsia/engine/browser/frame_impl.cc
index a83c2dd71ef35358e55234200cc1a67f04ac84a9..de02460d4d390950330b07c97f9791388474ee2c 100644
index cadebbfd37738ae7df9486a4240d9bdda4197f47..79ae6d8672b7435fbe5daa22986327cb07aef557 100644
--- a/fuchsia/engine/browser/frame_impl.cc
+++ b/fuchsia/engine/browser/frame_impl.cc
@@ -372,8 +372,7 @@ bool FrameImpl::IsWebContentsCreationOverridden(

View File

@@ -7,10 +7,10 @@ spellchecker uses a few IDS_ resources. We need to load these from
Electrons grit header instead of Chromes
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn
index 602e7363b4f3d9a1196cb3312b7664d00c205e36..558d12696dd00669096057543b52897a716d2f51 100644
index 2ace902f57a7a91124d316c1ad5df0e977e0a6d5..cf06039565541ebada001acfe3b6eb2ac0a42b44 100644
--- a/chrome/browser/BUILD.gn
+++ b/chrome/browser/BUILD.gn
@@ -6205,6 +6205,7 @@ static_library("browser") {
@@ -6206,6 +6206,7 @@ static_library("browser") {
deps += [
"//components/spellcheck/browser",
"//components/spellcheck/common",

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