Compare commits

..

189 Commits

Author SHA1 Message Date
trop[bot]
f7e22ed743 fix: child window may have opener removed (#38932)
* fix: child window may have opener removed

Co-authored-by: Cheng Zhao <zcbenz@gmail.com>

* Update chromium-spec.ts

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Cheng Zhao <zcbenz@gmail.com>
2023-06-27 11:34:12 -04:00
Charles Kerr
437bf7d1fd refactor: api web contents ownership (#38894)
refactor: api web contents ownership (#38695)

* refactor: aggregate api::WebContents::exclusive_access_manager_ directly

* refactor: make WebContents::devtools_file_system_indexer_ scoped_refptr const

* refactor: make WebContents::file_task_runner_ scoped_refptr const

* refactor: make WebContents::print_task_runner_ scoped_refptr const
2023-06-22 13:01:27 -05:00
trop[bot]
d0b2a4e48f refactor: prefer base::Contains() over find() + end() (#38890)
refactor: prefer base::Contains() over find() + end() (#38443)

* refactor: use base::Contains() in KeyWeakMap::Has()

* refactor: use base::Contains() in WebRequest::RequestFilter::MatchesType()

* refactor: use base::Contains() in BaseWindow::AddBrowserView()

* refactor: use base::Contains() in DeepFreeze()

* refactor: use base::Contains() in Clipboard::Read()

* Revert "refactor: use base::Contains() in BaseWindow::AddBrowserView()"
This reverts commit 60152359d3978451ebdd7c8eed602c2fb8a9cafa.

* refactor: use base::Contains() in BaseWindow::AddBrowserView()

* refactor: use base::Contains() in IsDevToolsFileSystemAdded()

* refactor: use base::Contains() in MessagePort::DisentanglePorts()

* refactor: use base::Contains() in PowerSaveBlocker::IsStarted()

* refactor: use base::Contains() in SpellCheckClient::OnSpellCheckDone()

* refactor: use base::Contains() in ShowTaskDialogWstr()

* refactor: use base::Contains() in PrintViewManagerElectron::ScriptedPrint()

* refactor: use base::Contains() in PrintViewManagerElectron::DidGetPrintedPagesCount()

* refactor: use base::Contains() in NativeWindow::AddDraggableRegionProvider()

* refactor: use base::Contains() in ElectronBindings::ActivateUVLoop()

* refactor: use base::Contains() in NativeWindowViews::IsVisibleOnAllWorkspaces()

* refactor: use base::Contains() in HidChooserController::OnDeviceAdded()

* refactor: use base::Contains() in ElectronSandboxedRendererClient::WillReleaseScriptContext()

* refactor: use base::Contains() in ElectronRendererClient::WillDestroyWorkerContextOnWorkerThread()

* refactor: use base::Contains() in GlobalShortcut::OnKeyPressed()

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Charles Kerr <charles@charleskerr.com>
2023-06-22 13:06:35 +02:00
trop[bot]
192295697e fix: crash calling BrowserWindow.removeBrowserView() with destroyed webContents (#38884)
fix: crash calling removeBrowserView() with destroyed webContents

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

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2023-06-22 11:22:30 +02:00
trop[bot]
e47bdb67f8 fix: set minimize visibility true with enable (#38881)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: mlaurencin <mlaurencin@electronjs.org>
2023-06-22 10:31:06 +02:00
trop[bot]
25dee92c57 refactor: remove unused InspectableWebContentsView::GetWebView() (#38819)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Charles Kerr <charles@charleskerr.com>
2023-06-16 12:43:47 -05:00
trop[bot]
053031e96c refactor: constexpr lookup tables (#38807)
* refactor: constexpr lookup tables (#38771)

* refactor: use a constexpr lookup table in GetPathConstant()

* refactor: use a constexpr lookup table in SystemPreferences::GetColor()

* refactor: use a constexpr lookup table in SimpleURLLoaderWrapper::Create()

Co-authored-by: Charles Kerr <charles@charleskerr.com>

* fix: use MakeFixedFlatMap() instead of MakeFixedFlatMapSorted()

The latter compiles faster but does not exist in 24-x-y

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

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Charles Kerr <charles@charleskerr.com>
2023-06-16 10:03:09 +02:00
trop[bot]
1e64527ec3 feat: support node: prefixed requires in sandboxed renderer preloads (#38727)
feat: support node: prefixed requires in sandboxed renderer preloads

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Milan Burda <milan.burda@gmail.com>
2023-06-15 12:00:01 +02:00
trop[bot]
1645aece38 fix: preferCSSPageSize error type (#38792)
fix: preferCSSPageSize error type

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2023-06-14 11:03:13 -07:00
Pedro Pontes
1f66b20392 chore: cherry-pick 3 changes from Release-2-M114 (#38787)
* chore: [24-x-y] cherry-pick 1 changes from Release-2-M114

* 2e76270cf65e from v8

* chore: update patches

---------

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2023-06-14 11:02:59 -07:00
trop[bot]
8df8cad3a0 refactor: use compile-time cli arg sets. (#38770)
We're currently building these on the heap with `std::set<std::string>`
but this can be a very small compile-time container instead.

Marking as 'refactor' rather than 'perf' since this isn't called often,
but moving from heap to compile-time is good and using this container
makes the code more readable.
2023-06-13 16:28:30 -05:00
trop[bot]
6d111ddbe3 fix: reparenting UAF crash on macOS (#38677)
* fix: reparenting UAF crash on macOS

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

* Update api-browser-window-spec.ts

* Update api-browser-window-spec.ts

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2023-06-13 15:54:09 -04:00
trop[bot]
2c9f2e81e8 perf: prefer base::StringPiece over std::string for build-time strings (#38736)
* perf: use base::StringPiece in InclusionStatusToString()

The strings are all build-time constants and this is a private function

Co-authored-by: Charles Kerr <charles@charleskerr.com>

* perf: use base::StringPiece in ErrorCodeToString()

The strings are all build-time constants and this is a private function

Co-authored-by: Charles Kerr <charles@charleskerr.com>

* perf: use base::StringPiece in MessageSourceToString()

The strings are all build-time constants and this is a private function

Co-authored-by: Charles Kerr <charles@charleskerr.com>

* perf: use base::StringPiece in CursorTypeToString()

The strings are all build-time constants and this is a private function

Co-authored-by: Charles Kerr <charles@charleskerr.com>

* perf: use base::StringPiece in MediaStreamTypeToString()

The strings are all build-time constants and this is a private function

Co-authored-by: Charles Kerr <charles@charleskerr.com>

* perf: use base::StringPiece in ModifiersToArray()

The strings are all build-time constants and this is a private function

Co-authored-by: Charles Kerr <charles@charleskerr.com>

* perf: use base::StringPiece in WebFrameRenderer::MaybeGetRenderFrame()

The strings are all build-time constants and this is a private function

Co-authored-by: Charles Kerr <charles@charleskerr.com>

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Charles Kerr <charles@charleskerr.com>
2023-06-12 16:22:15 -05:00
trop[bot]
14c6c397d0 fix: menu bar visibility when exiting full screen (#38681)
* fix:visibility of menu bar when exiting full screen

Co-authored-by: wugaosheng <wugaosheng@kylinos.cn>

* format code

Co-authored-by: wugaosheng <wugaosheng@kylinos.cn>

* format code

Co-authored-by: wugaosheng <wugaosheng@kylinos.cn>

* Modify comments

Co-authored-by: wugaosheng <wugaosheng@kylinos.cn>

* add menu bar visibility test

Co-authored-by: wugaosheng <wugaosheng@kylinos.cn>

* format code

Co-authored-by: wugaosheng <wugaosheng@kylinos.cn>

* change code

Co-authored-by: wugaosheng <wugaosheng@kylinos.cn>

* platform related in test

Co-authored-by: wugaosheng <wugaosheng@kylinos.cn>

* Update api-browser-window-spec.ts

* Update api-browser-window-spec.ts

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: wugaosheng <wugaosheng@kylinos.cn>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2023-06-12 15:50:07 +02:00
Keeley Hammond
3ce4c24c4b chore: cherry-pick 8 changes from Release-0-M114 (#38536)
* chore: [24-x-y] cherry-pick 4 changes from Release-0-M114

* e6b75a8b4900 from chromium
* 3b0607d14060 from v8
* 9c6dfc733fce from v8
* ea1cd76358e0 from chromium

* chore: remove one invalid patch, fix another

* chore: add missing backports.

* chore: update patches

---------

Co-authored-by: Pedro Pontes <pepontes@microsoft.com>
Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
Co-authored-by: Samuel Attard <sam@electronjs.org>
2023-06-09 17:29:30 -07:00
trop[bot]
97018c7be1 build: use upstream's presubmit cpplint filters. (#38687)
* build: use upstream's presubmit cpplint filters.

Our list of filters has fallen out-of-sync with upstream tests and so
our checks don't match those in the Google + Chromium guides.

The checks in this PR come from depot_tools and are copied manually
since the depot_tools code is python but our linter is js. 🤷
Perhaps we should rewrite in python?

Co-authored-by: Charles Kerr <charles@charleskerr.com>

* fixup! build: use upstream's presubmit cpplint filters.

chore: make linter happy with my linter changes

Co-authored-by: Charles Kerr <charles@charleskerr.com>

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Charles Kerr <charles@charleskerr.com>
2023-06-09 12:27:00 -07:00
trop[bot]
42c90f3eeb build: move uploadIndexJson to just before publishRelease (#38701)
* build: move uploadIndexJson to just before publishRelease

Co-authored-by: David Sanders <dsanders11@ucsbalum.com>

* chore: move uploadNodeShasums as well

Co-authored-by: David Sanders <dsanders11@ucsbalum.com>

* build: upload node checksums before validating them

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: David Sanders <dsanders11@ucsbalum.com>
Co-authored-by: Samuel Attard <marshallofsound@electronjs.org>
2023-06-09 12:22:22 -07:00
trop[bot]
bb2f62f95f refactor: add SessionPreferences::CreateForBrowserContext() (#38712)
Copy the NativeWindowRelay::CreateForWebContents() idiom
to simplify SessionPreferences's constructor and lifecycle.

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Charles Kerr <charles@charleskerr.com>
2023-06-09 12:21:02 -07:00
Samuel Attard
b60166eddc chore: cherry-pick 94af9d13a14b from chromium (#38711)
* chore: cherry-pick 94af9d13a14b from chromium

* chore: update patches

---------

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2023-06-09 12:08:56 -05:00
trop[bot]
1b762ef8a1 fix: dangling pointer warning when updating menus (#38689)
fix: dangling raw_ptr warning when updating menus

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Charles Kerr <charles@charleskerr.com>
2023-06-08 13:28:23 -04:00
trop[bot]
3815e90434 fix: bad error passing webContents.print(null) (#38640)
fix: bad error passing webContents.print(null)

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2023-06-07 23:53:05 -07:00
trop[bot]
65fba6f51b refactor: remove unused OffScreenRenderWidgetHostView fields (#38651)
* refactor: remove unused field OffScreenRenderWidgetHostView::last_time_

Co-authored-by: Charles Kerr <charles@charleskerr.com>

* refactor: remove unused field OffScreenRenderWidgetHostView::last_scroll_offset_

Unused since 1a9e253

Co-authored-by: Charles Kerr <charles@charleskerr.com>

* refactor: remove unused field OffScreenRenderWidgetHostView::paint_callback_running_

assigned to, but unread, since 81bf158

Co-authored-by: Charles Kerr <charles@charleskerr.com>

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Charles Kerr <charles@charleskerr.com>
2023-06-07 23:50:38 -07:00
Pedro Pontes
5e6d99a6af chore: cherry-pick 2 changes from Release-1-M114 (#38654)
* chore: [24-x-y] cherry-pick 2 changes from Release-1-M114

* 73af1a19a901 from v8
* 0035a4a8dac2 from v8

* chore: update patches

---------

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2023-06-07 23:49:37 -07:00
trop[bot]
bfb3b6d9a4 build: improve error output in release.js (#38664)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: David Sanders <dsanders11@ucsbalum.com>
2023-06-07 23:48:17 -07:00
Keeley Hammond
45caec231c build: uuaw @octokit/request to 6.2.5 (#38644)
build: uuaw occtokit/rest to 6.2.5
2023-06-07 14:26:15 -07:00
trop[bot]
7254da337b fix: sync api::Screen wrapper method sigs to upstream (#38631)
refactor: sync api::Screen getter sigs to upstream

ui::Display GetAllDisplays(), GetPrimaryDisplay(), GetDisplayMatching(),
and GetDisplayNearestPoint() methods are all const, so make our wrappers
const too.

ui::Display GetAllDisplays() returns a const reference, so make our
wrapper return a const reference too. This avoids creating a new
std::vector<display::Display> each time it's called.

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Charles Kerr <charles@charleskerr.com>
2023-06-07 10:45:17 -05:00
trop[bot]
612775dad5 refactor: remove redundant resizing strategy equality check (#38618)
* refactor: remove redundant resizing strategy equality check

Upstream already checks this.

Co-authored-by: Charles Kerr <charles@charleskerr.com>

* refactor: remove devtools_settings.h from iwc header

Co-authored-by: Charles Kerr <charles@charleskerr.com>

* refactor: remove unused <vectro> from iwc header

Co-authored-by: Charles Kerr <charles@charleskerr.com>

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Charles Kerr <charles@charleskerr.com>
2023-06-07 09:28:39 +02:00
trop[bot]
66845e7aa3 docs: removed outdated Appveyor doc (#38628)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
2023-06-06 23:11:49 -07:00
trop[bot]
31380eeb87 fix: account for BrowserView bounds in setting autofill popup bounds (#38608)
fix: account for BrowserView bounds in setting autofill popup bounds

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2023-06-06 21:50:43 +02:00
trop[bot]
0f4fce9448 refactor: in NativeWindowViews, aggregate fields directly (#38602)
Manual backport of #38559

Manual backport needed due to very minor code shear

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Charles Kerr <charles@charleskerr.com>
2023-06-06 11:26:33 -05:00
trop[bot]
f933ce3755 refactor: use process_util.h helpers (#38604)
refactor: use process_util.h helpers

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Milan Burda <milan.burda@gmail.com>
2023-06-06 14:29:42 +02:00
David Sanders
4845dd7a71 chore: type check JS in docs (#38600) 2023-06-06 17:14:07 +09:00
trop[bot]
bd0e65292f chore: remove unused electron::api::View code (#38586)
chore: remove unused electron::api::View code (#38561)

chore: remove unused electron::api::View methods

Remove code that was added in 2c8dc9e but never used.

Manually backport #38561 .

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Charles Kerr <charles@charleskerr.com>
2023-06-05 16:45:38 +02:00
trop[bot]
22bd19ddc1 docs: clarify which electron modules are exposed in sandboxed renderers (#38578)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Milan Burda <milan.burda@gmail.com>
2023-06-05 11:34:21 +02:00
trop[bot]
580c04e69f docs: fix SerialPort typing (#38582)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: David Sanders <dsanders11@ucsbalum.com>
2023-06-05 10:19:16 +02:00
trop[bot]
99a78dc37c build: fix doc-only early exit on Appveyor (#38550)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2023-06-01 15:09:16 -04:00
John Kleinschmidt
18b2a4e957 feat: add USB protected classes handler (#38498)
feat: add USB protected classes handler (#38263)

* feat: add USB protected classes handler

* chore: apply review suggestions

Co-authored-by: Charles Kerr <charles@charleskerr.com>

* chore: update docs

* chore: apply review suggestions

* update doc per suggestion

---------

Co-authored-by: Charles Kerr <charles@charleskerr.com>
(cherry picked from commit b4ec363b3d)
2023-06-01 10:12:48 -04:00
trop[bot]
a21fa57cae refactor: remove unused switches (#38531)
* refactor: remove unused declaration of electron::kSHA1Certificate

usage removed in 13a1d79

Co-authored-by: Charles Kerr <charles@charleskerr.com>

* refactor: remove unused declaration of electron::kSHA1MajorDescription

usage removed in 13a1d79

Co-authored-by: Charles Kerr <charles@charleskerr.com>

* refactor: remove unused declaration of electron::kSHA1MinorDescription

usage removed in 13a1d79

Co-authored-by: Charles Kerr <charles@charleskerr.com>

* refactor: remove unused declaration of electron::kCertificateError

usage removed in 13a1d79

Co-authored-by: Charles Kerr <charles@charleskerr.com>

* refactor: remove unused declaration of electron::kValidCertificate

usage removed in 13a1d79

Co-authored-by: Charles Kerr <charles@charleskerr.com>

* refactor: remove unused declaration of electron::kValidCertificateDescription

usage removed in 13a1d79

Co-authored-by: Charles Kerr <charles@charleskerr.com>

* refactor: remove unused declaration of electron::kSecureProtocol, kSecureProtocolDescription

usage removed in 497f5a1

Co-authored-by: Charles Kerr <charles@charleskerr.com>

* refactor: remove electron::options::kPreloadScripts

removed in bad8d5e0

Co-authored-by: Charles Kerr <charles@charleskerr.com>

* refactor: remove electron::options::kImageAnimationPolicy

removed in 385d0f5

Co-authored-by: Charles Kerr <charles@charleskerr.com>

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Charles Kerr <charles@charleskerr.com>
2023-05-31 16:52:24 -05:00
trop[bot]
54fe508125 build: combine and elaborate on exposed BoringSSL ciphers (#38522)
build: combine and elaborate on exposed BoringSSL ciphers

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2023-05-31 14:31:12 -04:00
trop[bot]
a662023207 docs: add <webview> new-window event removal to breaking-changes.md (#38525)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Milan Burda <miburda@microsoft.com>
2023-05-31 14:30:51 -04:00
trop[bot]
017fd30e89 chore: make contentTracing.stopRecording() failure clearer (#38520)
chore: make contentTracing.stopRecording() failure clearer

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2023-05-31 11:28:22 -04:00
trop[bot]
2281fbbe6c fix: DCHECK minimizing parent window with non-modal child (#38508)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2023-05-31 10:28:44 -04:00
trop[bot]
eece0dcbe1 ci: clean up docs only change logic (#38494)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2023-05-31 09:52:49 -04:00
trop[bot]
5a8243fe32 chore: process.mainModule -> require.main (#38478)
chore: process.mainModule -> require.main

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2023-05-30 10:52:57 +02:00
trop[bot]
2fc0c83cd6 build: make ReactiveObjC/Mantle deps format consistent (#38479)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2023-05-30 10:52:45 +02:00
trop[bot]
100bea3b37 docs: ensure app.md examples are runnable (#38439)
docs: ensure app.md examples are runnable

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2023-05-25 09:58:24 +02:00
trop[bot]
6e30bf2ce9 fix: linker error missing uv__strtok (#38394)
fix: linker error missing uv__strtok

This symbol is referenced inside what seems to be dead code
in `uv__search_path` in third_party/electron_node/deps/uv/src/unix/core.c
When compiling in LTO mode, the reference is removed,
but not during a non-LTO build.

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Bruno Pitrus <brunopitrus@hotmail.com>
2023-05-24 15:05:27 -04:00
David Sanders
2ef49a5333 chore: fix lint:js-in-markdown script (#38334) 2023-05-24 20:00:47 +02:00
trop[bot]
01f4b2c915 fix: MediaDevices missing DisplayMediaInformation (#38434)
fix: MediaDevices missing DisplayMediaInformation

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2023-05-24 19:15:29 +02:00
trop[bot]
e8c05bccd1 docs: disablewebsecurity on webview-tag can not be changed for an active session (#38399)
disablewebsecurity on webview-tag can not be changed for an active session

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Kilian Valkhof <kilian@kilianvalkhof.com>
2023-05-22 15:19:22 -04:00
trop[bot]
61daccb001 fix: getNormalBounds() for transparent windows on Windows (#38349)
fix: getNormalBounds for transparent windows on Windows

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2023-05-22 13:21:08 +02:00
Shelley Vohr
4cfd732908 feat: support Mica/Acrylic on Windows (#38361) 2023-05-18 16:57:41 -04:00
trop[bot]
2594d94760 feat: add missing 'cursor-changed' type values (#38364)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2023-05-18 16:55:06 -04:00
David Sanders
c9ff49c827 docs: fix typing of message box type value (#38375) 2023-05-18 20:53:32 +02:00
electron-roller[bot]
31f5e3c356 chore: bump chromium to 112.0.5615.204 (24-x-y) (#38350)
* chore: bump chromium in DEPS to 112.0.5615.204

* chore: update patches

* refactor: add WebViewGuestDelegate::GetGuestDelegateWeakPtr()

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

This approach copied from GuestViewBase::GetGuestDelegateWeakPtr() approach in that same commit.

(cherry picked from commit 3f3ab39e3a1077f71aa90319d7a81d53cfb3c55e)

---------

Co-authored-by: electron-roller[bot] <84116207+electron-roller[bot]@users.noreply.github.com>
Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
Co-authored-by: Charles Kerr <charles@charleskerr.com>
2023-05-18 12:15:10 -04:00
trop[bot]
0c3e4e8dd7 build: modify gclient.py with unified patch (#38360)
* build: modify gclient.py with unified patch

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

* ci: ensure depot_tools does not update

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

* ci: move auto-update disable outside if

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

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2023-05-17 16:37:42 -04:00
trop[bot]
37b227d427 docs: fix devtools-open-url ts definition (#38354)
docs: fix devtools-open-url ts definition

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2023-05-17 16:20:57 -04:00
trop[bot]
d8e7457ab0 fix: win.isMaximized() for transparent windows on Windows (#38343)
* fix: win.isMaximized() for transparent windows

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

* chore: update patches

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2023-05-17 13:09:55 +02:00
Pedro Pontes
4c46a940fc chore: cherry-pick 81d7b3e6138c from chromium (#38271)
* chore: cherry-pick 81d7b3e6138c from chromium

* chore: update patches

---------

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2023-05-16 16:32:42 -04:00
electron-roller[bot]
94c6d89579 chore: bump chromium to 112.0.5615.183 (24-x-y) (#38319)
* chore: bump chromium in DEPS to 112.0.5615.183

* chore: update patches

---------

Co-authored-by: electron-roller[bot] <84116207+electron-roller[bot]@users.noreply.github.com>
Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2023-05-16 16:24:51 -04:00
David Sanders
ff2dfe67c5 chore: migrate to @electron/lint-roller for Markdown linting (#38282)
chore: migrate to @electron/lint-roller for Markdown linting (#38191)
2023-05-16 11:19:49 -07:00
trop[bot]
9cf44a0229 fix: unify BrowserWindow.isVisible() logic cross-platform (#38313)
fix: unify BrowserWindow.isVisible() logic cross-platform

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2023-05-16 11:16:14 -04:00
trop[bot]
696f9894e6 fix: isMaximized after minimize/fullscreen on macOS (#38308)
fix: isMaximized after isMinimized on macOS

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2023-05-16 14:28:37 +02:00
trop[bot]
814dc6e16d fix: enable BrowserWindow.id access post-destruction (#38310)
fix: enable BrowserWindow id access post-destruction

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2023-05-16 12:52:05 +02:00
David Sanders
ad800081ce test: prewarm Node headers cache if specifying Electron version (#38298)
test: prewarm Node headers cache if specifying Electron version (#38287)
2023-05-16 11:47:43 +02:00
trop[bot]
a22e2a778e build: drop python2 from CI (#38303) 2023-05-16 09:21:54 +02:00
Shelley Vohr
34f181db5d docs: fix typing of session.setDevicePermissionHandler (#38228)
docs: fix typing of session.setDevicePermissionHandler

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: David Sanders <dsanders11@ucsbalum.com>
2023-05-09 12:07:54 -04:00
Shelley Vohr
9aa49570a1 docs: update dead link to Apple Human Interface notification guidelines (#38227)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: astone123 <adams@cypress.io>
2023-05-09 12:07:19 -04:00
Shelley Vohr
ea68961d50 fix: handle AXManualAccessibility attribute cross-protocol (#38224)
fix: handle `AXManualAccessibility` attribute cross-protocol (#38142)

* fix: handle AXManualAccessibility attribute cross-protocol

* Update shell/browser/mac/electron_application.mm



---------

Co-authored-by: Robo <hop2deep@gmail.com>
2023-05-09 12:04:31 -04:00
Shelley Vohr
7ddcd7eaba refactor: remove IPC from mouse_util (#38221)
refactor: remove IPC from mouse_util (#38183)
2023-05-09 12:02:22 -04:00
Shelley Vohr
00de69508e feat: net.resolveHost (#38153)
feat: net.resolveHost
2023-05-04 15:45:15 -04:00
Alexey Kuzmin
7302832dbe test: use await to call "closeWindow" (#38173) 2023-05-04 14:27:00 +02:00
David Sanders
549c6dd0ec fix: falsy transparent shouldn't affect webContents background (#38158) 2023-05-03 15:27:52 +02:00
Shelley Vohr
1df9dbad51 chore: correct extra qualification causing build error with gcc (#38145)
* chore: correct extra qualification causing build error with GCC

Co-authored-by: Bruno Pitrus <brunopitrus@hotmail.com>

* fixup for lint

Co-authored-by: John Kleinschmidt <kleinschmidtorama@gmail.com>

* chore: fix lint

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

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Bruno Pitrus <brunopitrus@hotmail.com>
Co-authored-by: John Kleinschmidt <kleinschmidtorama@gmail.com>
2023-05-02 20:44:29 -04:00
Shelley Vohr
a051ee5d41 fix: AXManualAccessibility showing failure (#38147)
fix: AXManualAccessibility showing failure

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
2023-05-02 20:44:08 -04:00
trop[bot]
912aa52b9b feat: add thermal states to powerMonitor (#38027)
* feat: add thermal states to powerMonitor

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

* update docs

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

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Jeremy Rose <jeremya@chromium.org>
2023-05-01 09:26:23 -04:00
Felix Rieseberg
6b2a63fd53 fix: crash on missing RenderWidgetHostView (#38136)
fix: crash on missing `RenderWidgetHostView` (#38100)

chore: fix crash on missing RenderWidgetHostView

Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2023-05-01 09:23:02 -04:00
trop[bot]
8b7a54d9ec docs: fix start highlight tutorial-2-first-app.md (#38113)
doc: fix start highlight tutorial-2-first-app.md

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Francis Chartrand <chartrandf@users.noreply.github.com>
2023-04-25 13:16:51 +02:00
Black-Hole️
b30f8e13d8 fix: webContents return type incorrect (#38111)
fix: webContents return type incorrect (#38026)

* fix: webContents type incorrect

* fix: ci failed

* fix: ci failed 2
2023-04-25 13:16:30 +02:00
trop[bot]
9f028cc45c chore: always lint JS in docs/fiddles (#38108)
* chore: always lint JS in docs/fiddles

Co-authored-by: David Sanders <dsanders11@ucsbalum.com>

* chore: update patches

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: David Sanders <dsanders11@ucsbalum.com>
Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2023-04-24 19:45:40 +02:00
Keeley Hammond
00163df35d chore: cherry-pick 1 changes from Release-2-M112 (#38082)
* chore: [24-x-y] cherry-pick 1 changes from Release-2-M112

* [ec53103cc72d](https://chromium-review.googlesource.com/) from chromium

* chore: update patch
2023-04-24 10:17:44 +02:00
trop[bot]
8761af5cbb fix: crash in utilityProcess when generating code from strings (#38041)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: deepak1556 <hop2deep@gmail.com>
2023-04-24 13:23:04 +09:00
electron-roller[bot]
4e06c64d23 chore: bump chromium to 112.0.5615.165 (24-x-y) (#38047)
chore: bump chromium in DEPS to 112.0.5615.165

Co-authored-by: electron-roller[bot] <84116207+electron-roller[bot]@users.noreply.github.com>
2023-04-23 22:17:14 +02:00
trop[bot]
fb55fc46b0 fix: defaults broken in shell.openExternal() options (#38072)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Milan Burda <miburda@microsoft.com>
2023-04-21 12:43:52 -07:00
electron-roller[bot]
c91dc20429 chore: bump chromium to 112.0.5615.138 (24-x-y) (#38031)
chore: bump chromium in DEPS to 112.0.5615.138

Co-authored-by: electron-roller[bot] <84116207+electron-roller[bot]@users.noreply.github.com>
2023-04-20 14:20:06 +02:00
trop[bot]
6bb78d7fff build: fix building with no PDF support (#38007)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Alexey Kuzmin <alex.s.kuzmin@gmail.com>
2023-04-17 20:19:20 -04:00
trop[bot]
4a9f347c20 chore: initial linting fixes for JS in docs/fiddles (#37838)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: David Sanders <dsanders11@ucsbalum.com>
2023-04-17 11:55:06 -04:00
trop[bot]
85ad7844dd docs: add note to win.setFullScreen(flag) (#37996)
docs: add note to win.setFullScreen(flag)

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2023-04-17 12:11:02 +02:00
trop[bot]
b345ffd2f3 chore: replace uses of ComPtr::GetAddressOf() with ComPtr::operator& (#37992)
chore: replace uses of ComPtr::GetAddressOf() with ComPtr::operator&

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2023-04-17 10:38:30 +02:00
trop[bot]
35056392a8 docs: update github.com links (#37989)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: David Sanders <dsanders11@ucsbalum.com>
2023-04-16 17:06:31 -07:00
electron-roller[bot]
0a69431dda chore: bump chromium to 112.0.5615.121 (24-x-y) (#37985)
chore: bump chromium in DEPS to 112.0.5615.121

Co-authored-by: electron-roller[bot] <84116207+electron-roller[bot]@users.noreply.github.com>
2023-04-15 21:19:12 -07:00
trop[bot]
56122f1491 fix: swipe event emission on macOS (#37965)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2023-04-14 09:19:15 -07:00
trop[bot]
31500cc485 fix: defaultFontFamily in webPreferences (#37968)
* fix: defaultFontFamily in webPreferences

Co-authored-by: David Sanders <dsanders11@ucsbalum.com>

* chore: check if default_font_family_ is empty

Co-authored-by: David Sanders <dsanders11@ucsbalum.com>

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: David Sanders <dsanders11@ucsbalum.com>
2023-04-13 21:09:16 -04:00
electron-roller[bot]
a0987ae0de chore: bump chromium to 112.0.5615.87 (24-x-y) (#37974)
chore: bump chromium in DEPS to 112.0.5615.87

Co-authored-by: electron-roller[bot] <84116207+electron-roller[bot]@users.noreply.github.com>
2023-04-13 13:07:08 -04:00
trop[bot]
f9faad71d5 docs: Fix the syntax error for code fragment (#37960)
By using `app.on('ready').then(xxx)`, application will throw a TypeError

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Zenkie Bear <62818957+ZenkieBear@users.noreply.github.com>
2023-04-13 13:28:19 +02:00
trop[bot]
3a027a743b fix: menus on Linux after window modification (#37906)
* fix: menus on Linux after window modification

Co-authored-by: David Sanders <dsanders11@ucsbalum.com>

* test: don't run on CI

Co-authored-by: David Sanders <dsanders11@ucsbalum.com>

* chore: fix .patches

* test: refactor since types are off

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: David Sanders <dsanders11@ucsbalum.com>
Co-authored-by: electron-patch-conflict-fixer[bot] <83340002+electron-patch-conflict-fixer[bot]@users.noreply.github.com>
2023-04-13 11:26:51 +02:00
John Kleinschmidt
63388b3616 build: revert clang revert (#37934)
* build: revert clang revert

* ci: use newer clang for 32-bit Linux ARM

Fixes crash on compiling skia/skia/SkPatchUtils.cpp
2023-04-13 15:05:45 +09:00
trop[bot]
2e7bfb4e0d fix: recommended node-gyp version in node.h error (#37927)
fix: recommended node-gyp version in node.h error

In
https://github.com/electron/electron/blob/main/docs/tutorial/using-native-node-modules.md#using-npm,
we recommend setting the `npm_config_disturl` variable but doing that
does not work on node-gyp v8.4.0 because after
https://github.com/nodejs/node-gyp/pull/2497
landed, the dist URL was read only from `gyp.opts['dist-url']`. The fix
for reading the value from `npm_config_disturl` by parsing
`gyp.opts.disturl` was landed in
https://github.com/nodejs/node-gyp/pull/2547 and that change was
released in node-gyp v9.0.0, so this change updates the error macro to
recommend node-gyp v9.0.0 as the minimum required version.

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Darshan Sen <raisinten@gmail.com>
2023-04-11 10:04:51 -07:00
trop[bot]
95729e64e4 fix: exceptions during function/promise result conversions live in calling world (#37925)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Samuel Attard <marshallofsound@electronjs.org>
2023-04-11 09:23:26 -07:00
trop[bot]
6f9cc3ce32 chore: use nested namespaces (#37915)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: David Sanders <dsanders11@ucsbalum.com>
2023-04-11 12:39:14 +02:00
trop[bot]
55df7a369e fix: broken buttons in PDF viewer (#37918)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2023-04-11 12:00:17 +02:00
trop[bot]
a6d934f2a2 chore: use emplace when possible (#37910)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: David Sanders <dsanders11@ucsbalum.com>
2023-04-11 11:53:18 +02:00
trop[bot]
78404eb23f chore: change some for loops to range-based (#37913)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: David Sanders <dsanders11@ucsbalum.com>
2023-04-11 11:49:30 +02:00
David Sanders
59fe35388d chore: enforce consistent Markdown style for strong and emphasis (#37845) 2023-04-11 16:22:57 +09:00
trop[bot]
81e3cef294 fix: showAboutPanel also on linux (#37872)
showAboutPanel also on linux

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Mikael Finstad <finstaden@gmail.com>
2023-04-11 16:20:47 +09:00
trop[bot]
ae54e3768c test: support 'latest'/'latest@X' Electron version strings (#37867)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: David Sanders <dsanders11@ucsbalum.com>
2023-04-11 15:21:55 +09:00
trop[bot]
4de542d524 fix: exceptions in nested conversions live in the target world (#37897)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Samuel Attard <marshallofsound@electronjs.org>
2023-04-10 18:00:58 -07:00
Keeley Hammond
9f1bb29528 docs: update 24-x-y breaking changes (#37880) 2023-04-06 21:23:54 -07:00
trop[bot]
309cd19d19 docs: update 21-x-y EOL dates (#37870)
* docs: update 21-x-y EOL dates

Co-authored-by: Keeley Hammond <vertedinde@electronjs.org>

* doc: update node versions

Co-authored-by: Keeley Hammond <vertedinde@electronjs.org>

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Keeley Hammond <vertedinde@electronjs.org>
2023-04-06 13:01:36 -07:00
Fedor Indutny
14985e29e0 feat: session.resolveHost (#37847)
feat: session.resolveHost (#37690)

* feat: session.resolveHost

Expose Chromium's host resolution API through the Session object.

* Update shell/browser/api/electron_api_session.cc



* address feedback

* fix tests

* address feedback

* Add options

* Update shell/browser/api/electron_api_session.cc



* Update shell/browser/net/resolve_host_function.cc



* lint

* return object

* add missing file

* fix crash

* handle scope

* links

---------

Co-authored-by: Fedor Indutny <indutny@signal.org>
Co-authored-by: Fedor Indutny <79877362+indutny-signal@users.noreply.github.com>
Co-authored-by: Jeremy Rose <nornagon@nornagon.net>
Co-authored-by: Cheng Zhao <github@zcbenz.com>
2023-04-06 10:23:44 -04:00
David Sanders
4fc59bcbef test: remove workaround for fixed Menu.closePopup issue (#37846)
test: remove workaround for fixed Menu.closePopup issue (#37802)
2023-04-06 18:52:18 +09:00
electron-roller[bot]
0a153e7dca chore: bump chromium to 112.0.5615.50 (24-x-y) (#37833)
chore: bump chromium in DEPS to 112.0.5615.50

Co-authored-by: electron-roller[bot] <84116207+electron-roller[bot]@users.noreply.github.com>
2023-04-05 15:50:00 -04:00
Jeremy Rose
5517655962 fix: apply csp correctly when contextIsolation: false (#37839) 2023-04-05 12:11:40 -07:00
trop[bot]
663b741d3f docs: fix app.getPreferredSystemLanguages() return type (#37835)
docs: fix app.getPreferredSystemLanguages() return type

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2023-04-05 11:08:38 -04:00
trop[bot]
ba6ac2a087 fix: Fn+F fullscreen transitioning on macOS (#37823)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2023-04-05 16:37:59 +09:00
trop[bot]
3c131923f3 chore: combine parallel/test-v8-stats v8 patches (#37818)
* chore: combine parallel/test-v8-stats v8 patches

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

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2023-04-04 15:16:28 +02:00
trop[bot]
0c2cb44976 fix: record helper error messages in electron_main_mac (#37810)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Jeremy Rose <jeremya@chromium.org>
2023-04-03 15:25:21 -07:00
Keeley Hammond
a2d0af4bc3 build: strip warnings from stdout in get_release (#37795)
build: strip warnings from stdout in `get_release` (#37277)

build: strip warnings from stdout in get_release

Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2023-04-03 12:40:35 +02:00
Keeley Hammond
82869b88f1 refactor: createThumbnailFromPath takes size not maxSize (#37796)
refactor: `createThumbnailFromPath` takes `size` not `maxSize` (#37362)

refactor: createThumbnailFromPath takes size not maxSize
2023-04-03 12:39:50 +02:00
trop[bot]
ff01742f8e fix: set background color for menu bar on Windows (#37785)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: David Sanders <dsanders11@ucsbalum.com>
2023-04-01 10:44:26 +02:00
trop[bot]
0fc69fcaf4 build: fix build-tools schema in config (#37777)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2023-03-31 17:59:34 +02:00
trop[bot]
505e98e694 docs: update references to @electron/rebuild (#37776)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Erick Zhao <erick@hotmail.ca>
2023-03-31 17:46:26 +02:00
electron-roller[bot]
5c6dd3fdef chore: bump chromium to 112.0.5615.49 (24-x-y) (#37767)
* chore: bump chromium in DEPS to 112.0.5615.49

* fix: Store the thread stack start in TLS.

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

Fixes #37454

---------

Co-authored-by: electron-roller[bot] <84116207+electron-roller[bot]@users.noreply.github.com>
Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
2023-03-30 20:06:12 -04:00
trop[bot]
5f68f374d8 docs: remove save-to-disk disposition (#37769)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Jeremy Rose <jeremya@chromium.org>
2023-03-30 20:38:36 +02:00
trop[bot]
0af7d3c99b docs: add links to IPC event structures (#37770)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: David Sanders <dsanders11@ucsbalum.com>
2023-03-30 20:38:13 +02:00
trop[bot]
b6070c34d4 docs: update docs.microsoft.com links to learn.microsoft.com (#37751)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: David Sanders <dsanders11@ucsbalum.com>
2023-03-30 09:41:35 -04:00
trop[bot]
6101b9cd29 fix: draggable regions shouldn't capture clicks on frames windows (#37741)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2023-03-28 13:34:14 -04:00
trop[bot]
363fb370ac docs: updated package.json content and electron version in build first app guide (#37743)
* Docs: updated package.json content and electron version in build first app guide

Co-authored-by: Mikołaj <32898551+dufipl@users.noreply.github.com>

* docs: removed caret from electron version

Co-authored-by: Mikołaj Sawicki <32898551+dufipl@users.noreply.github.com>

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Mikołaj <32898551+dufipl@users.noreply.github.com>
2023-03-28 12:31:45 -04:00
trop[bot]
58d0564825 chore: generator objects can't be sent over the context bridge (#37730)
chore: generator objects can't be sent over the context bridge (#37593)

* chore: generator objects can't be sent over the context bridge

* Trigger Build

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2023-03-28 11:15:28 -04:00
trop[bot]
f38c3d91a2 fix: crash in MessagePortMain with some postMessage params (#37726)
* fix: crash in MessagePortMain postMessage

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

* Update shell/browser/api/message_port.cc

Co-authored-by: Charles Kerr <charles@charleskerr.com>

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

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2023-03-28 10:29:02 -04:00
trop[bot]
7682c2d950 docs: fixup incorrect value for disabling sandbox (#37723)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Peter Xu <sysu.peter.hsu@gmail.com>
2023-03-27 18:28:14 -04:00
electron-roller[bot]
7588eb5a72 chore: bump chromium to 112.0.5615.39 (24-x-y) (#37700)
* chore: bump chromium in DEPS to 112.0.5615.39

* chore: update patches

* chore: update chromium/add_maximized_parameter_to_linuxui_getwindowframeprovider.patch

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

Our patch changes the signature of `LinuxUiTheme::GetWindowFrameProvider()`.
Upstream 4295455 added a new subclass (FallbackLinuxUi) so sync its version
of GetWindowFrameProvider() to match our changes.

(cherry picked from commit 79408b5fb8)

---------

Co-authored-by: electron-roller[bot] <84116207+electron-roller[bot]@users.noreply.github.com>
Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
Co-authored-by: Charles Kerr <charles@charleskerr.com>
2023-03-27 13:22:01 -04:00
trop[bot]
ce82646f5c fix: allow cancelling of bluetooth requests (#37717)
* fix: allow cancelling of bluetooth requests

allows cancelling of bluetooth requests when no devices present

Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>

* docs: update docs to reflect how bluetooth works.

Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
2023-03-27 12:54:36 -04:00
Erick Zhao
1cd40681a9 docs: delete synopsis.md (#37687)
docs: delete synopsis.md (#37580)

* docs: delete synopsis.md

* remove code references to doc
2023-03-27 12:24:06 -04:00
trop[bot]
7892de74ee docs: change MSDN links to new Microsoft docs (#37703)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Erick Zhao <erick@hotmail.ca>
2023-03-27 09:38:14 -04:00
John Kleinschmidt
d4798f64e7 ci: update appveyor image to e-112.0.5615.29 (#37683) 2023-03-23 19:33:13 -04:00
trop[bot]
c77eb753e5 ci: fixup gn check to actually run gn check (#37679)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
2023-03-23 18:26:26 -04:00
trop[bot]
da3d5967aa docs: update notifications tutorial (#37640)
* docs: update notifications tutorial

Co-authored-by: Erick Zhao <erick@hotmail.ca>

* delete unused assets

Co-authored-by: Erick Zhao <erick@hotmail.ca>

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Erick Zhao <erick@hotmail.ca>
2023-03-22 10:17:51 -04:00
electron-roller[bot]
8d9e23cf88 chore: bump chromium to 112.0.5615.29 (24-x-y) (#37598)
* chore: bump chromium in DEPS to 112.0.5615.29

* chore: update patches

* ci: make sure that strip_binary.gni is properly preserved

(cherry picked from commit afb446c328)

* fixup: ci: make sure that strip_binary.gni is properly preserved

---------

Co-authored-by: electron-roller[bot] <84116207+electron-roller[bot]@users.noreply.github.com>
Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
2023-03-20 22:20:17 -04:00
trop[bot]
080fb8e648 fix: don't set delegate for QLPreviewPanel (#37578)
fix: don't set delegate for QLPreviewPanel

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Jeremy Spiegel <jeremy.spiegel@frontapp.com>
2023-03-20 20:17:30 -04:00
trop[bot]
7da962fb82 fix: invoke app.dock.{hide|show} instead of duplicating logic (#37625)
fix: invoke app.dock.{hide|show} instead of duplicating logic

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2023-03-20 13:37:13 -04:00
trop[bot]
73f4440d0c docs: update broken links (#37621)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: David Sanders <dsanders11@ucsbalum.com>
2023-03-20 12:28:00 -04:00
trop[bot]
3c5cd4c2eb fix: properly bubble up cookie creation failure message (#37597)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2023-03-16 17:52:43 +01:00
trop[bot]
62aad2481f feat: add enableLocalEcho flag to setDisplayMediaRequestHandler() callback (#37528)
* feat: add enableLocalEcho flag to setDisplayMediaRequestHandler() callback

Co-authored-by: Theo Gravity <theo@switchboard.app>

* Fix lint

Co-authored-by: Theo Gravity <theo@switchboard.app>

* Update doc

Co-authored-by: Theo Gravity <theo@switchboard.app>

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Theo Gravity <theo@switchboard.app>
2023-03-16 09:47:15 +01:00
trop[bot]
b32786afc5 docs: clarify open-url not preventable (#37575)
docs: clarify open-url not preventable

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2023-03-14 18:53:33 -04:00
electron-roller[bot]
238dfbaa0f chore: bump chromium to 112.0.5615.20 (24-x-y) (#37546)
* chore: bump chromium in DEPS to 112.0.5615.20

* chore: update patches

---------

Co-authored-by: electron-roller[bot] <84116207+electron-roller[bot]@users.noreply.github.com>
Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2023-03-13 15:39:53 +01:00
John Kleinschmidt
ddb4a16eb2 chore: bump chromium to 112.0.5615.10 (24-x-y) (#37510)
* chore: bump chromium to 112.0.5615.10

* 4240798: Get rid of ShowInvalidPrinterSettingsError() in PrintManagerHost.

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

* chore: fixup patch

* 4173660: Remove unused argument in BeforeUnloadCompleted

Ref: https://chromium-review.googlesource.com/c/chromium/src/+/4173660
(cherry picked from commit 6d3934f743)

* refactor: base value type DICTIONARY replaced with DICT

Ref: https://chromium-review.googlesource.com/c/chromium/src/+/4198081
(cherry picked from commit b7acb5c9a4)

* 4251237: [StorageKey Cleanup] (2) Rename CreateFirstParty constructors

Ref: https://chromium-review.googlesource.com/c/chromium/src/+/4251237
(cherry picked from commit 31bdd549d0)

* refactor: rename latency metrics

Refs: https://chromium-review.googlesource.com/c/chromium/src/+/4048262
(cherry picked from commit 1e1b97d387)

* refactor: base::span explicit conversion checks

Ref: https://chromium-review.googlesource.com/c/chromium/src/+/4219636
(cherry picked from commit 020e8c6aae)

* chore: iwyu net/cert/cert_verify_result.h

(cherry picked from commit 24583f5583)

* 4258446: Move network::mojom::ClearDataFilter to its own mojom file

https://chromium-review.googlesource.com/c/chromium/src/+/4258446
(cherry picked from commit 5ff47109cd)

* refactor: refactoring geolocation manager

Ref: https://chromium-review.googlesource.com/c/chromium/src/+/4161603
(cherry picked from commit 1eeaafb45c)

* refactor: use modern base values in tracing

Ref: https://chromium-review.googlesource.com/c/chromium/src/+/4210912
(cherry picked from commit 192c988c1e)

* refactor: add sanitized context to clipboard write

Ref: https://chromium-review.googlesource.com/c/chromium/src/+/4178264
(cherry picked from commit 3ef020b5e5)

* 4256866: [Extensions] Replace GetHooksForAPI with a RegisterHooksDelegate

Ref: https://chromium-review.googlesource.com/c/chromium/src/+/4256866
(cherry picked from commit b9d905216a)

* refactor: s/Rect/WindowFeatures

Ref: https://chromium-review.googlesource.com/c/chromium/src/+/4167001
(cherry picked from commit 12d121265b)

* 4226656: Add response url to SimpleURLLoader::OnRedirectCallback

Ref: https://chromium-review.googlesource.com/c/chromium/src/+/4226656
(cherry picked from commit 9f66c47930)

* Better approach for ShowInvalidPrinterSettingsError() removal

* build: use xcode 14

(cherry picked from commit 06bd2c0442)

* build: update appveyor image

4072083: New toolchain for Windows 11 10.0.22621.755 SDK | https://chromium-review.googlesource.com/c/chromium/src/+/4072083
(cherry picked from commit 437c49898f)

* 4261434: Remove browser_watcher (1/3): Move ExitCodeWatcher to chrome/app

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

* 4128591: Enable large pdbs by default

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

* move dbgcore/dbghelp to extensions_to_skip

(cherry picked from commit 8eeb555145)

* 4273450: dpwas: Send announcement when live regions changed

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

* 4277708: win7dep: Remove ResolveCoreWinRTStringDelayload

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

* Roll clang+rust llvmorg-17-init-3170-g6e30dffe-1 : llvmorg-17-init-3874-g93a2fecc-1 / [skipping Rust]

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

* 4285717: Copy d3dcompiler_47.dll on ARM64 Windows builds

https://chromium-review.googlesource.com/c/angle/angle/+/4285717

* Revert "Roll clang+rust llvmorg-17-init-3170-g6e30dffe-1 : llvmorg-17-init-3874-g93a2fecc-1 / [skipping Rust]"

This reverts commit 71080f4f2d.

* Revert Roll clang+rust llvmorg-16-init-17653-g39da55e8-3

This clang roll breaks Linux arm 32-bit

---------

Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
Co-authored-by: Keeley Hammond <vertedinde@electronjs.org>
Co-authored-by: Samuel Attard <marshallofsound@electronjs.org>
Co-authored-by: Jeremy Rose <jeremya@chromium.org>
Co-authored-by: electron-patch-conflict-fixer[bot] <83340002+electron-patch-conflict-fixer[bot]@users.noreply.github.com>
2023-03-09 14:05:20 -05:00
trop[bot]
6c8aeb4c0d docs: remove outdated ipc example (#37538)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Erick Zhao <erick@hotmail.ca>
2023-03-09 10:01:42 -05:00
trop[bot]
44f8d11fd8 fix: fallback to X11 capturer if pipewire fails on Wayland (#37527)
* fix: fallback to x11 desktop capturer on Wayland

Co-authored-by: VerteDinde <keeleymhammond@gmail.com>

* fix: sanitize window/screen capturer inputs

Co-authored-by: Keeley Hammond <vertedinde@electronjs.org>

* chore: clean up patch description

Co-authored-by: Keeley Hammond <vertedinde@electronjs.org>

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: VerteDinde <keeleymhammond@gmail.com>
Co-authored-by: Keeley Hammond <vertedinde@electronjs.org>
2023-03-08 15:13:23 -08:00
trop[bot]
077a7cd2f5 docs: fixup WebUSB fiddle (#37525)
docs: fixup webusb fiddle

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
2023-03-07 21:16:01 -05:00
trop[bot]
dea0e6e259 fix: WebUSB on ARM64 macs (#37522)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
2023-03-07 21:15:33 -05:00
trop[bot]
51b1ef4190 docs: remove misleading info from will-finish-launching docs (#37516)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Jeremy Rose <jeremya@chromium.org>
2023-03-07 10:26:50 +01:00
trop[bot]
5abfb3a6bc fix: Showing the about panel is async on all platforms (#37508)
fix: Showing the about panel is async on all platforms (#37440)

* fix: about panel is a base::Value::Dict

* nix this test for a diff PR

* what if the about dialog was not blocking

* add this test back in

* document synchronicity

* github editor is a fan of spaces

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Calvin <clavin@users.noreply.github.com>
2023-03-06 13:31:45 -08:00
trop[bot]
33a34af2fb fix: don't double-log unhandled rejections (#37500)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2023-03-06 08:21:00 -08:00
trop[bot]
2be0bd9729 refactor: leverage Skia helpers for NSColor ANSI logic (#37489)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2023-03-06 11:43:04 +01:00
trop[bot]
2e3d9a4f6d fix: draggable regions on MAS (#37474)
* fix: draggable regions on MAS

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

* lint

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

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Jeremy Rose <jeremya@chromium.org>
2023-03-03 09:46:03 +01:00
electron-roller[bot]
29ced1215a chore: bump chromium to 111.0.5563.50 (24-x-y) (#37223)
* chore: bump chromium in DEPS to 111.0.5563.19

* chore: bump chromium in DEPS to 111.0.5563.33

* chore: bump chromium in DEPS to 111.0.5563.41

* chore: update patches

* refactor: remove GetFontLookupTableCacheDir

Ref: https://chromium-review.googlesource.com/c/chromium/src/+/4191820
(cherry picked from commit 52740f127f)

* chore: remove dead DecodeToken code

(cherry picked from commit e7ac425771)

* chore: add stub impls for WCO routing

Refs: https://chromium-review.googlesource.com/c/chromium/src/+/4182690
(cherry picked from commit 911e353b07)

* refacotr: switch mojom::NetworkHintsHandler to use SchemeHostPair instead of URL

Ref: https://chromium-review.googlesource.com/c/chromium/src/+/4185417
(cherry picked from commit a8b3befdd7)

* chore: bump chromium in DEPS to 111.0.5563.50

* chore: update patches

* 4240360: [intl] Revert date formatting behavior change from ICU 72

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

* chore: update patches

---------

Co-authored-by: electron-roller[bot] <84116207+electron-roller[bot]@users.noreply.github.com>
Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
Co-authored-by: Samuel Attard <marshallofsound@electronjs.org>
Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2023-03-02 20:22:57 -05:00
trop[bot]
03285c8faf chore: improve contents.takeHeapSnapshot error messages (#37461)
* chore: improve contents.takeHeapSnapshot error messages

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

* fix wstring conversion issue

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

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2023-03-02 12:48:18 +01:00
trop[bot]
f02d262d32 fix: min/max width/height enforcement when aspectRatio is set (#37456)
fix: min/max width/height with aspect ratio

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2023-03-02 12:23:04 +01:00
trop[bot]
1ff589976c feat: add types to webRequest filter (#37427)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Milan Burda <milan.burda@gmail.com>
2023-03-02 10:05:29 +01:00
trop[bot]
9e3a44edf7 fix: handle closing webContents in BrowserViews (#37450)
* fix: handle closing webContents in BrowserViews

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

* test: add window.close() test

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

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2023-03-02 10:04:11 +01:00
trop[bot]
71803a5dd4 fix: Notification with reply obscuring first action on macOS (#37449)
fix: Notification with reply obscuring first action

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2023-03-01 14:25:01 +01:00
trop[bot]
f72a812db6 fix: about panel crash (#37442)
* fix: about panel is a base::Value::Dict

Co-authored-by: clavin <clavin@electronjs.org>

* nix this test for a diff PR

Co-authored-by: clavin <clavin@electronjs.org>

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: clavin <clavin@electronjs.org>
2023-03-01 13:56:01 +01:00
trop[bot]
4c368be0a9 fix: BroadcastChannel initialization location (#37443)
* fix: BroadcastChannel initialization location

* chore: update patches

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2023-03-01 12:24:23 +01:00
trop[bot]
a6a8622257 feat: add logUsage to shell.openExternal() options (#37291)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Milan Burda <miburda@microsoft.com>
2023-02-27 10:02:49 +01:00
trop[bot]
9be3acd24c feat: add httpOnly cookies.get filter (#37365)
feat: add httpOnly cookies filter

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Black-Hole1 <158blackhole@gmail.com>
2023-02-27 10:02:19 +01:00
trop[bot]
886a5032cf fix: allow contextmenu event in draggable regions (#37395)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Jeremy Rose <jeremya@chromium.org>
2023-02-26 20:42:08 -08:00
Samuel Attard
b05d385f4a build: set base rev 24-x-y (#37409) 2023-02-26 20:18:19 -08:00
trop[bot]
8edfa03ac7 docs: document change in draggable region behavior on macOS (#37407)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Jeremy Rose <nornagon@nornagon.net>
2023-02-26 16:52:42 -08:00
trop[bot]
b156ffb25a ci: rename Electron build step to include type of build being built (#37397)
ci: rename Electron build step to describe what is being built

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
2023-02-24 12:26:38 -08:00
trop[bot]
a1255ae20f fix: guard more private API usage on MAS builds (#37364)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2023-02-21 17:54:48 +01:00
trop[bot]
de5ee7e60e fix: html fullscreen when window not fullscreenable (#37368)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2023-02-21 17:54:25 +01:00
trop[bot]
85802682b5 fix: restoring X11 window should not remove previous maximize state (#37358)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Cheng Zhao <zcbenz@gmail.com>
2023-02-21 12:50:40 +01:00
trop[bot]
f04ad15b65 build: remove unused python code (#37357)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2023-02-21 12:10:38 +01:00
trop[bot]
38ca7c0860 test: fix "crash cases" tests not failing properly (#37325)
* test: fix "crash cases" tests not failing properly

Co-authored-by: Alexey Kuzmin <alex.s.kuzmin@gmail.com>

* fixup! test: fix "crash cases" tests not failing properly

Co-authored-by: Alexey Kuzmin <alex.s.kuzmin@gmail.com>

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Alexey Kuzmin <alex.s.kuzmin@gmail.com>
2023-02-20 12:53:09 +01:00
trop[bot]
309349a020 test: use render-process-gone event in tests (#37302)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Milan Burda <miburda@microsoft.com>
2023-02-19 01:29:53 -08:00
trop[bot]
f3d50c674c test: rename & split internal module tests (#37328)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Milan Burda <miburda@microsoft.com>
2023-02-19 01:26:08 -08:00
trop[bot]
8e74a37505 docs: only macOS 10.13+ is supported now (#37288)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Milan Burda <miburda@microsoft.com>
2023-02-16 15:56:01 -08:00
trop[bot]
426c23446c chore: remove redundant Node.js patch (#37307)
* chore: fix patch for other patch

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

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2023-02-16 15:49:05 -08:00
trop[bot]
52adfe2137 test: use webContents.create() in type-safe way (#37308)
test: use (webContents as typeof ElectronInternal.WebContents).create()

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Milan Burda <miburda@microsoft.com>
2023-02-16 15:48:38 -08:00
Keeley Hammond
4911476787 build: use node18.12 appveyor image (24-x-y) (#37283)
build: use node18.12 appveyor image
2023-02-15 14:22:45 -08:00
trop[bot]
7a62411ad1 feat: include all standard paper sizes for webContents.print() (#37265)
feat: include standard paper sizes for webContents.print()

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2023-02-15 19:58:49 +01:00
trop[bot]
99d648faaa fix: cookies filter secure invalid (#37246)
* fix: cookies filter secure and session invalid

Co-authored-by: Black-Hole1 <158blackhole@gmail.com>

* test: add test

Co-authored-by: Black-Hole1 <158blackhole@gmail.com>

* test: fix test failed

Co-authored-by: Black-Hole1 <158blackhole@gmail.com>

* test: fix test failed again

Co-authored-by: Black-Hole1 <158blackhole@gmail.com>

* fix: session check logic incorrect

Co-authored-by: Black-Hole1 <158blackhole@gmail.com>

* refactor: reset cookies filter session logic

Co-authored-by: Black-Hole1 <158blackhole@gmail.com>

* Update shell/browser/api/electron_api_cookies.cc

Co-authored-by: Robo <hop2deep@gmail.com>

Co-authored-by: Black-Hole <158blackhole@gmail.com>

* chore: re-enable worker spec failures (#37015)

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

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Black-Hole1 <158blackhole@gmail.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2023-02-15 12:38:01 +01:00
trop[bot]
91776c5484 docs: add win.isFocusable() return type (#37260)
docs: fix `win.isFocusable()` return type

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Andrew Ferreira <andrew.shien2@gmail.com>
2023-02-15 11:52:11 +01:00
trop[bot]
1a48e36313 fix: BrowserView crash when 'beforeunload' prevented (#37268)
fix: crash when beforeunload prevented

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2023-02-14 20:54:52 +01:00
trop[bot]
97c66e5985 refactor: simplify Node.js event loop with SpinEventLoop (#37258)
refactor: simplify Node.js event loop with SpinEventLoop

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2023-02-14 18:42:05 +01:00
trop[bot]
4ce69207b0 build: set make_latest correctly on published releases (#37242)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Samuel Attard <marshallofsound@electronjs.org>
2023-02-13 14:47:26 +01:00
trop[bot]
cf4f6285c8 chore: update https://cs.chromium.org/ links to https://source.chromium.org/ (#37234)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Milan Burda <miburda@microsoft.com>
2023-02-13 16:32:32 +09:00
trop[bot]
253a60f8ae ci: update appveyor build agent (#37229)
ci update appveyor image

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
2023-02-11 19:20:22 -05:00
512 changed files with 10063 additions and 16461 deletions

View File

@@ -51,7 +51,7 @@ jobs:
steps:
- checkout
- path-filtering/set-parameters:
base-revision: main
base-revision: origin/24-x-y
mapping: |
^((?!docs/).)*$ run-build-mac true
^((?!docs/).)*$ run-build-linux true

View File

@@ -52,14 +52,9 @@ executors:
size:
description: "macOS executor size"
type: enum
enum: ["macos.x86.medium.gen2"]
version:
description: "xcode version"
type: enum
enum: ["14.3.0", "14.0.0"]
default: 14.3.0
enum: ["macos.x86.medium.gen2", "large"]
macos:
xcode: << parameters.version >>
xcode: 14.0.0
resource_class: << parameters.size >>
# Electron Runners
@@ -113,7 +108,7 @@ env-unittests: &env-unittests
TESTS_CONFIG: src/electron/spec/configs/unittests.yml
env-arm: &env-arm
GN_EXTRA_ARGS: 'target_cpu = "arm"'
GN_EXTRA_ARGS: 'target_cpu = "arm" clang_use_chrome_plugins = false'
MKSNAPSHOT_TOOLCHAIN: //build/toolchain/linux:clang_arm
BUILD_NATIVE_MKSNAPSHOT: 1
TARGET_ARCH: arm
@@ -346,8 +341,8 @@ step-setup-goma-for-build: &step-setup-goma-for-build
mkdir third_party
node -e "require('./src/utils/goma.js').downloadAndPrepare({ gomaOneForAll: true })"
export GOMA_FALLBACK_ON_AUTH_FAILURE=true
third_party/goma/goma_ctl.py ensure_start
if [ ! -z "$RAW_GOMA_AUTH" ] && [ "`third_party/goma/goma_auth.py info`" != "Login as Fermi Planck" ]; then
python3 third_party/goma/goma_ctl.py ensure_start
if [ ! -z "$RAW_GOMA_AUTH" ] && [ "`python3 third_party/goma/goma_auth.py info`" != "Login as Fermi Planck" ]; then
echo "WARNING!!!!!! Goma authentication is incorrect; please update Goma auth token."
exit 1
fi
@@ -375,14 +370,14 @@ step-restore-brew-cache: &step-restore-brew-cache
- /usr/local/Cellar/gnu-tar
- /usr/local/bin/gtar
keys:
- v6-brew-cache-{{ arch }}
- v7-brew-cache-{{ arch }}
step-save-brew-cache: &step-save-brew-cache
save_cache:
paths:
- /usr/local/Cellar/gnu-tar
- /usr/local/bin/gtar
key: v6-brew-cache-{{ arch }}
key: v7-brew-cache-{{ arch }}
name: Persisting brew cache
step-get-more-space-on-mac: &step-get-more-space-on-mac
@@ -542,6 +537,18 @@ step-fix-sync: &step-fix-sync
mv .git/config.backup .git/config
git fetch
step-fix-clang: &step-fix-clang
run:
name: Fix Clang on 32-bit Linux ARM
command: |
if [ "$TARGET_ARCH" == "arm" ]; then
# The following custom clang needed on 32-bit Linux ARM due to https://crbug.com/1431201.
# Once https://crbug.com/1425409 has been resolved this workaround can be remove
cd src/third_party/llvm-build/Release+Asserts
curl -O https://dev-cdn.electronjs.org/clang/clang-llvmorg-17-init-4759-g547e3456-2.tar.xz
tar xvf clang-llvmorg-17-init-4759-g547e3456-2.tar.xz
fi
step-install-signing-cert-on-mac: &step-install-signing-cert-on-mac
run:
name: Import and trust self-signed codesigning cert on MacOS
@@ -1048,6 +1055,7 @@ commands:
default: true
steps:
- *step-gn-gen-default
- *step-fix-clang
- ninja_build_electron:
clean-prebuilt-snapshot: false
build-type: << parameters.build-type >>
@@ -1587,6 +1595,7 @@ commands:
- *step-setup-goma-for-build
- *step-wait-for-goma
- *step-gn-gen-default
- *step-fix-clang
# Electron app
- ninja_build_electron:
@@ -2131,7 +2140,6 @@ jobs:
executor:
name: macos
size: macos.x86.medium.gen2
version: 14.0.0
environment:
<<: *env-mac-large
<<: *env-stack-dumping
@@ -2155,7 +2163,6 @@ jobs:
executor:
name: macos
size: macos.x86.medium.gen2
version: 14.0.0
environment:
<<: *env-mac-large
<<: *env-stack-dumping

View File

@@ -4,6 +4,37 @@
"onCreateCommand": ".devcontainer/on-create-command.sh",
"updateContentCommand": ".devcontainer/update-content-command.sh",
"workspaceFolder": "/workspaces/gclient/src/electron",
"extensions": [
"joeleinbinder.mojom-language",
"rafaelmaiolla.diff",
"surajbarkale.ninja",
"ms-vscode.cpptools",
"mutantdino.resourcemonitor",
"dbaeumer.vscode-eslint",
"shakram02.bash-beautify",
"marshallofsound.gnls-electron",
"CircleCI.circleci"
],
"settings": {
"editor.tabSize": 2,
"bashBeautify.tabSize": 2,
"typescript.tsdk": "node_modules/typescript/lib",
"[gn]": {
"editor.formatOnSave": true
},
"[javascript]": {
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true
}
},
"[typescript]": {
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true
}
},
"javascript.preferences.quoteStyle": "single",
"typescript.preferences.quoteStyle": "single"
},
"forwardPorts": [8088, 6080, 5901],
"portsAttributes": {
"8088": {
@@ -29,38 +60,6 @@
"openFiles": [
".devcontainer/README.md"
]
},
"vscode": {
"extensions": ["joeleinbinder.mojom-language",
"rafaelmaiolla.diff",
"surajbarkale.ninja",
"ms-vscode.cpptools",
"mutantdino.resourcemonitor",
"dbaeumer.vscode-eslint",
"shakram02.bash-beautify",
"marshallofsound.gnls-electron",
"CircleCI.circleci"
],
"settings": {
"editor.tabSize": 2,
"bashBeautify.tabSize": 2,
"typescript.tsdk": "node_modules/typescript/lib",
"[gn]": {
"editor.formatOnSave": true
},
"[javascript]": {
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true
}
},
"[typescript]": {
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true
}
},
"javascript.preferences.quoteStyle": "single",
"typescript.preferences.quoteStyle": "single"
}
}
}
}

View File

@@ -16,8 +16,6 @@ ln -s $buildtools_configs $buildtools/configs
# Write the gclient config if it does not already exist
if [ ! -f $gclient_root/.gclient ]; then
echo "Creating gclient config"
echo "solutions = [
{ \"name\" : \"src/electron\",
\"url\" : \"https://github.com/electron/electron\",
@@ -34,8 +32,6 @@ fi
# Write the default buildtools config file if it does
# not already exist
if [ ! -f $buildtools/configs/evm.testing.json ]; then
echo "Creating build-tools testing config"
write_config() {
echo "
{
@@ -57,7 +53,7 @@ if [ ! -f $buildtools/configs/evm.testing.json ]; then
\"CHROMIUM_BUILDTOOLS_PATH\": \"/workspaces/gclient/src/buildtools\",
\"GIT_CACHE_PATH\": \"/workspaces/gclient/.git-cache\"
},
\"\$schema\": \"file:///home/builduser/.electron_build_tools/evm-config.schema.json\"
\"$schema\": \"file:///home/builduser/.electron_build_tools/evm-config.schema.json\"
}
" >$buildtools/configs/evm.testing.json
}
@@ -71,12 +67,10 @@ if [ ! -f $buildtools/configs/evm.testing.json ]; then
# if it works we can use the goma cluster
export NOTGOMA_CODESPACES_TOKEN=$GITHUB_TOKEN
if e d goma_auth login; then
echo "$GITHUB_USER has GOMA access - switching to cluster mode"
write_config cluster
fi
else
echo "build-tools testing config already exists"
# Re-auth with the goma cluster regardless.
# Even if the config file existed we still need to re-auth with the goma
# cluster
NOTGOMA_CODESPACES_TOKEN=$GITHUB_TOKEN e d goma_auth login || true
fi

1
.gitattributes vendored
View File

@@ -11,5 +11,4 @@ patches/**/.patches merge=union
*.ts text eol=lf
*.py text eol=lf
*.ps1 text eol=lf
*.html text eol=lf
*.md text eol=lf

1
.github/CODEOWNERS vendored
View File

@@ -8,7 +8,6 @@
DEPS @electron/wg-upgrades
# Releases WG
/docs/breaking-changes.md @electron/wg-releases
/npm/ @electron/wg-releases
/script/release @electron/wg-releases

14
.github/config.yml vendored
View File

@@ -25,3 +25,17 @@ newPRWelcomeComment: |
# Comment to be posted to on pull requests merged by a first time user
firstPRMergeComment: >
Congrats on merging your first pull request! 🎉🎉🎉
# Users authorized to run manual trop backports
authorizedUsers:
- alexeykuzmin
- ckerr
- codebytere
- deepak1556
- jkleinsc
- loc
- MarshallOfSound
- miniak
- mlaurencin
- nornagon
- zcbenz

View File

@@ -1,7 +1,7 @@
name: "Check Semantic Commit"
on:
pull_request:
pull_request_target:
types:
- opened
- edited

View File

@@ -40,21 +40,13 @@ jobs:
if: ${{ env.APPVEYOR_IMAGE_VERSION }}
uses: mikefarah/yq@1c7dc0e88aad311c89889bc5ce5d8f96931a1bd0 # v4.27.2
with:
cmd: |
yq '.image = "${{ env.APPVEYOR_IMAGE_VERSION }}"' "appveyor.yml" > "appveyor2.yml"
yq '.image = "${{ env.APPVEYOR_IMAGE_VERSION }}"' "appveyor-woa.yml" > "appveyor-woa2.yml"
cmd: yq '.image = "${{ env.APPVEYOR_IMAGE_VERSION }}"' "appveyor.yml" > "appveyor2.yml"
- name: (Optionally) Generate Commit Diff
if: ${{ env.APPVEYOR_IMAGE_VERSION }}
run: |
diff -w -B appveyor.yml appveyor2.yml > appveyor.diff || true
patch -f appveyor.yml < appveyor.diff
rm appveyor2.yml appveyor.diff
- name: (Optionally) Generate Commit Diff for WOA
if: ${{ env.APPVEYOR_IMAGE_VERSION }}
run: |
diff -w -B appveyor-woa.yml appveyor-woa2.yml > appveyor-woa.diff || true
patch -f appveyor-woa.yml < appveyor-woa.diff
rm appveyor-woa2.yml appveyor-woa.diff
- name: (Optionally) Commit and Pull Request
if: ${{ env.APPVEYOR_IMAGE_VERSION }}
uses: peter-evans/create-pull-request@2b011faafdcbc9ceb11414d64d0573f37c774b04 # v4.2.3
@@ -68,5 +60,4 @@ jobs:
delete-branch: true
title: 'build: update appveyor image to latest version'
body: |
This PR updates appveyor.yml to the latest baked image, ${{ env.APPVEYOR_IMAGE_VERSION }}.
Notes: none
This PR updates appveyor.yml to the latest baked image, ${{ env.APPVEYOR_IMAGE_VERSION }}.

View File

@@ -1,7 +1,7 @@
import("//build/config/locales.gni")
import("//build/config/ui.gni")
import("//build/config/win/manifest.gni")
import("//components/os_crypt/sync/features.gni")
import("//components/os_crypt/features.gni")
import("//components/spellcheck/spellcheck_build_features.gni")
import("//content/public/app/mac_helpers.gni")
import("//extensions/buildflags/buildflags.gni")
@@ -433,7 +433,7 @@ source_set("electron_lib") {
"//components/network_hints/renderer",
"//components/network_session_configurator/common",
"//components/omnibox/browser:buildflags",
"//components/os_crypt/sync",
"//components/os_crypt",
"//components/pref_registry",
"//components/prefs",
"//components/security_state/content",
@@ -772,8 +772,6 @@ source_set("electron_lib") {
sources += [
"shell/browser/electron_pdf_web_contents_helper_client.cc",
"shell/browser/electron_pdf_web_contents_helper_client.h",
"shell/browser/extensions/api/pdf_viewer_private/pdf_viewer_private_api.cc",
"shell/browser/extensions/api/pdf_viewer_private/pdf_viewer_private_api.h",
]
}

5
DEPS
View File

@@ -2,9 +2,9 @@ gclient_gn_args_from = 'src'
vars = {
'chromium_version':
'114.0.5735.289',
'112.0.5615.204',
'node_version':
'v18.15.0',
'v18.14.0',
'nan_version':
'16fa32231e2ccd89d2804b3f765319128b20c4ac',
'squirrel.mac_version':
@@ -155,4 +155,5 @@ hooks = [
recursedeps = [
'src',
'src/third_party/squirrel.mac',
]

View File

@@ -6,7 +6,7 @@
version: 1.0.{build}
build_cloud: electronhq-16-core
image: e-112.0.5607.0-vs2022
image: e-112.0.5615.29
environment:
GIT_CACHE_PATH: C:\Users\appveyor\libcc_cache
ELECTRON_OUT_DIR: Default

View File

@@ -6,7 +6,7 @@
# - "GN_CONFIG" Build type. One of {'testing', 'release'}.
# - "GN_EXTRA_ARGS" Additional gn arguments for a build config,
# e.g. 'target_cpu="x86"' to build for a 32bit platform.
# https://gn.googlesource.com/gn/+/main/docs/reference.md#var_target_cpu
# https://gn.googlesource.com/gn/+/master/docs/reference.md#target_cpu
# Don't forget to set up "NPM_CONFIG_ARCH" and "TARGET_ARCH" accordingly
# if you pass a custom value for 'target_cpu'.
# - "ELECTRON_RELEASE" Set it to '1' upload binaries on success.
@@ -29,14 +29,14 @@
version: 1.0.{build}
build_cloud: electronhq-16-core
image: e-114.0.5735.16-bust-cache
image: e-112.0.5615.29
environment:
GIT_CACHE_PATH: C:\Users\appveyor\libcc_cache
ELECTRON_OUT_DIR: Default
ELECTRON_ENABLE_STACK_DUMPING: 1
ELECTRON_ALSO_LOG_TO_STDERR: 1
MOCHA_REPORTER: mocha-multi-reporters
MOCHA_MULTI_REPORTERS: "@marshallofsound/mocha-appveyor-reporter, tap"
MOCHA_MULTI_REPORTERS: mocha-appveyor-reporter, tap
GOMA_FALLBACK_ON_AUTH_FAILURE: true
DEPOT_TOOLS_WIN_TOOLCHAIN: 0
PYTHONIOENCODING: UTF-8
@@ -49,11 +49,6 @@ environment:
APPVEYOR_BUILD_WORKER_IMAGE: base-woa
APPVEYOR_BUILD_WORKER_CLOUD: electronhq-woa
clone_script:
- ps: git clone -q $("--branch=" + $Env:APPVEYOR_REPO_BRANCH) $("https://github.com/" + $Env:APPVEYOR_REPO_NAME + ".git") $Env:APPVEYOR_BUILD_FOLDER
- ps: if (!$Env:APPVEYOR_PULL_REQUEST_NUMBER) {$("git checkout -qf " + $Env:APPVEYOR_REPO_COMMIT)}
- ps: if ($Env:APPVEYOR_PULL_REQUEST_NUMBER) {git fetch -q origin +refs/pull/$($Env:APPVEYOR_PULL_REQUEST_NUMBER)/head; git checkout -qf FETCH_HEAD}
clone_folder: C:\projects\src\electron
skip_branch_with_pr: true
@@ -72,10 +67,8 @@ for:
- ps: |
node script/yarn.js install --frozen-lockfile
node script/doc-only-change.js --prNumber=$env:APPVEYOR_PULL_REQUEST_NUMBER
$env:SHOULD_SKIP_ARTIFACT_VALIDATION = "false"
if ($LASTEXITCODE -eq 0) {
Write-warning "Skipping build for doc-only change"
$env:SHOULD_SKIP_ARTIFACT_VALIDATION = "true"
Write-warning "Skipping build for doc only change"
Exit-AppveyorBuild
} else {
$global:LASTEXITCODE = 0
@@ -92,8 +85,6 @@ for:
Remove-Item -Recurse -Force $pwd\build-tools
}
- git clone --depth=1 https://chromium.googlesource.com/chromium/tools/depot_tools.git
- ps: New-Item -Name depot_tools\.disable_auto_update -ItemType File
- depot_tools\bootstrap\win_tools.bat
- ps: $env:PATH="$pwd\depot_tools;$env:PATH"
- ps: >-
if (Test-Path -Path "$pwd\src\electron") {
@@ -116,7 +107,7 @@ for:
- ps: .\src\electron\script\start-goma.ps1 -gomaDir $env:LOCAL_GOMA_DIR
- ps: >-
if (Test-Path 'env:RAW_GOMA_AUTH') {
$goma_login = python3 $env:LOCAL_GOMA_DIR\goma_auth.py info
$goma_login = python $env:LOCAL_GOMA_DIR\goma_auth.py info
if ($goma_login -eq 'Login as Fermi Planck') {
Write-warning "Goma authentication is correct";
} else {
@@ -166,7 +157,7 @@ for:
- ninja -C out/Default electron:hunspell_dictionaries_zip
- ninja -C out/Default electron:electron_chromedriver_zip
- ninja -C out/Default third_party/electron_node:headers
- python3 %LOCAL_GOMA_DIR%\goma_ctl.py stat
- python %LOCAL_GOMA_DIR%\goma_ctl.py stat
- ps: >-
Get-CimInstance -Namespace root\cimv2 -Class Win32_product | Select vendor, description, @{l='install_location';e='InstallLocation'}, @{l='install_date';e='InstallDate'}, @{l='install_date_2';e='InstallDate2'}, caption, version, name, @{l='sku_number';e='SKUNumber'} | ConvertTo-Json | Out-File -Encoding utf8 -FilePath .\installed_software.json
- python3 electron/build/profile_toolchain.py --output-json=out/Default/windows_toolchain_profile.json
@@ -187,30 +178,6 @@ for:
7z a pdb.zip out\Default\*.pdb
}
- python3 electron/script/zip_manifests/check-zip-manifest.py out/Default/dist.zip electron/script/zip_manifests/dist_zip.win.%TARGET_ARCH%.manifest
- ps: |
cd C:\projects\src
$missing_artifacts = $false
if ($env:SHOULD_SKIP_ARTIFACT_VALIDATION -eq 'true') {
Write-warning "Skipping artifact validation for doc-only PR"
} else {
$artifacts_to_validate = 'dist.zip','windows_toolchain_profile.json','shell_browser_ui_unittests.exe','chromedriver.zip','ffmpeg.zip','node_headers.zip','mksnapshot.zip','electron.lib','hunspell_dictionaries.zip'
foreach($artifact_name in $artifacts_to_validate) {
if ($artifact_name -eq 'ffmpeg.zip') {
$artifact_file = "out\ffmpeg\ffmpeg.zip"
} elseif ($artifact_name -eq 'node_headers.zip') {
$artifact_file = $artifact_name
} else {
$artifact_file = "out\Default\$artifact_name"
}
if (-not(Test-Path $artifact_file)) {
Write-warning "$artifact_name is missing and cannot be added to artifacts"
$missing_artifacts = $true
}
}
}
if ($missing_artifacts) {
throw "Build failed due to missing artifacts"
}
deploy_script:
- cd electron
@@ -236,7 +203,7 @@ for:
- if exist node_headers.zip (appveyor-retry appveyor PushArtifact node_headers.zip)
- if exist out\Default\mksnapshot.zip (appveyor-retry appveyor PushArtifact out\Default\mksnapshot.zip)
- if exist out\Default\hunspell_dictionaries.zip (appveyor-retry appveyor PushArtifact out\Default\hunspell_dictionaries.zip)
- if exist out\Default\electron.lib (appveyor-retry appveyor PushArtifact out\Default\electron.lib)
- if exist out\Default\electron.lib (appveyor-retry appveyor PushArtifact out\Default\electron.lib)
- ps: >-
if ((Test-Path "pdb.zip") -And ($env:GN_CONFIG -ne 'release')) {
appveyor-retry appveyor PushArtifact pdb.zip
@@ -269,7 +236,7 @@ for:
# Download build artifacts
$apiUrl = 'https://ci.appveyor.com/api'
$build_info = Invoke-RestMethod -Method Get -Uri "$apiUrl/projects/$env:APPVEYOR_ACCOUNT_NAME/$env:APPVEYOR_PROJECT_SLUG/builds/$env:APPVEYOR_BUILD_ID"
$artifacts_to_download = @('dist.zip','ffmpeg.zip','node_headers.zip','electron.lib')
$artifacts_to_download = @('dist.zip','ffmpeg.zip','node_headers.zip','pdb.zip','electron.lib')
foreach ($job in $build_info.build.jobs) {
if ($job.name -eq "Build Arm on X64 Windows") {
$jobId = $job.jobId
@@ -281,13 +248,10 @@ for:
}
Invoke-RestMethod -Method Get -Uri "$apiUrl/buildjobs/$jobId/artifacts/$artifact_name" -OutFile $outfile
}
# Uncomment the following lines to download the pdb.zip to show real stacktraces when crashes happen during testing
# Invoke-RestMethod -Method Get -Uri "$apiUrl/buildjobs/$jobId/artifacts/pdb.zip" -OutFile pdb.zip
# 7z x -y -osrc pdb.zip
}
}
- ps: |
$out_default_zips = @('dist.zip')
$out_default_zips = @('dist.zip','pdb.zip')
foreach($zip_name in $out_default_zips) {
7z x -y -osrc\out\Default $zip_name
}

View File

@@ -6,7 +6,7 @@
# - "GN_CONFIG" Build type. One of {'testing', 'release'}.
# - "GN_EXTRA_ARGS" Additional gn arguments for a build config,
# e.g. 'target_cpu="x86"' to build for a 32bit platform.
# https://gn.googlesource.com/gn/+/main/docs/reference.md#var_target_cpu
# https://gn.googlesource.com/gn/+/master/docs/reference.md#target_cpu
# Don't forget to set up "NPM_CONFIG_ARCH" and "TARGET_ARCH" accordingly
# if you pass a custom value for 'target_cpu'.
# - "ELECTRON_RELEASE" Set it to '1' upload binaries on success.
@@ -29,14 +29,14 @@
version: 1.0.{build}
build_cloud: electronhq-16-core
image: e-114.0.5735.16-bust-cache
image: e-112.0.5615.29
environment:
GIT_CACHE_PATH: C:\Users\appveyor\libcc_cache
ELECTRON_OUT_DIR: Default
ELECTRON_ENABLE_STACK_DUMPING: 1
ELECTRON_ALSO_LOG_TO_STDERR: 1
MOCHA_REPORTER: mocha-multi-reporters
MOCHA_MULTI_REPORTERS: "@marshallofsound/mocha-appveyor-reporter, tap"
MOCHA_MULTI_REPORTERS: mocha-appveyor-reporter, tap
GOMA_FALLBACK_ON_AUTH_FAILURE: true
DEPOT_TOOLS_WIN_TOOLCHAIN: 0
PYTHONIOENCODING: UTF-8
@@ -47,11 +47,6 @@ environment:
- job_name: Test
job_depends_on: Build
clone_script:
- ps: git clone -q $("--branch=" + $Env:APPVEYOR_REPO_BRANCH) $("https://github.com/" + $Env:APPVEYOR_REPO_NAME + ".git") $Env:APPVEYOR_BUILD_FOLDER
- ps: if (!$Env:APPVEYOR_PULL_REQUEST_NUMBER) {$("git checkout -qf " + $Env:APPVEYOR_REPO_COMMIT)}
- ps: if ($Env:APPVEYOR_PULL_REQUEST_NUMBER) {git fetch -q origin +refs/pull/$($Env:APPVEYOR_PULL_REQUEST_NUMBER)/head; git checkout -qf FETCH_HEAD}
clone_folder: C:\projects\src\electron
skip_branch_with_pr: true
@@ -70,10 +65,8 @@ for:
- ps: |
node script/yarn.js install --frozen-lockfile
node script/doc-only-change.js --prNumber=$env:APPVEYOR_PULL_REQUEST_NUMBER
$env:SHOULD_SKIP_ARTIFACT_VALIDATION = "false"
if ($LASTEXITCODE -eq 0) {
Write-warning "Skipping build for doc-only change"
$env:SHOULD_SKIP_ARTIFACT_VALIDATION = "true"
Write-warning "Skipping build for doc only change"
Exit-AppveyorBuild
} else {
$global:LASTEXITCODE = 0
@@ -90,8 +83,6 @@ for:
Remove-Item -Recurse -Force $pwd\build-tools
}
- git clone --depth=1 https://chromium.googlesource.com/chromium/tools/depot_tools.git
- ps: New-Item -Name depot_tools\.disable_auto_update -ItemType File
- depot_tools\bootstrap\win_tools.bat
- ps: $env:PATH="$pwd\depot_tools;$env:PATH"
- ps: >-
if (Test-Path -Path "$pwd\src\electron") {
@@ -114,7 +105,7 @@ for:
- ps: .\src\electron\script\start-goma.ps1 -gomaDir $env:LOCAL_GOMA_DIR
- ps: >-
if (Test-Path 'env:RAW_GOMA_AUTH') {
$goma_login = python3 $env:LOCAL_GOMA_DIR\goma_auth.py info
$goma_login = python $env:LOCAL_GOMA_DIR\goma_auth.py info
if ($goma_login -eq 'Login as Fermi Planck') {
Write-warning "Goma authentication is correct";
} else {
@@ -164,7 +155,7 @@ for:
- ninja -C out/Default electron:hunspell_dictionaries_zip
- ninja -C out/Default electron:electron_chromedriver_zip
- ninja -C out/Default third_party/electron_node:headers
- python3 %LOCAL_GOMA_DIR%\goma_ctl.py stat
- python %LOCAL_GOMA_DIR%\goma_ctl.py stat
- ps: >-
Get-CimInstance -Namespace root\cimv2 -Class Win32_product | Select vendor, description, @{l='install_location';e='InstallLocation'}, @{l='install_date';e='InstallDate'}, @{l='install_date_2';e='InstallDate2'}, caption, version, name, @{l='sku_number';e='SKUNumber'} | ConvertTo-Json | Out-File -Encoding utf8 -FilePath .\installed_software.json
- python3 electron/build/profile_toolchain.py --output-json=out/Default/windows_toolchain_profile.json
@@ -185,30 +176,6 @@ for:
7z a pdb.zip out\Default\*.pdb
}
- python3 electron/script/zip_manifests/check-zip-manifest.py out/Default/dist.zip electron/script/zip_manifests/dist_zip.win.%TARGET_ARCH%.manifest
- ps: |
cd C:\projects\src
$missing_artifacts = $false
if ($env:SHOULD_SKIP_ARTIFACT_VALIDATION -eq 'true') {
Write-warning "Skipping artifact validation for doc-only PR"
} else {
$artifacts_to_validate = 'dist.zip','windows_toolchain_profile.json','shell_browser_ui_unittests.exe','chromedriver.zip','ffmpeg.zip','node_headers.zip','mksnapshot.zip','electron.lib','hunspell_dictionaries.zip'
foreach($artifact_name in $artifacts_to_validate) {
if ($artifact_name -eq 'ffmpeg.zip') {
$artifact_file = "out\ffmpeg\ffmpeg.zip"
} elseif ($artifact_name -eq 'node_headers.zip') {
$artifact_file = $artifact_name
} else {
$artifact_file = "out\Default\$artifact_name"
}
if (-not(Test-Path $artifact_file)) {
Write-warning "$artifact_name is missing and cannot be added to artifacts"
$missing_artifacts = $true
}
}
}
if ($missing_artifacts) {
throw "Build failed due to missing artifacts"
}
deploy_script:
- cd electron
@@ -234,7 +201,7 @@ for:
- if exist node_headers.zip (appveyor-retry appveyor PushArtifact node_headers.zip)
- if exist out\Default\mksnapshot.zip (appveyor-retry appveyor PushArtifact out\Default\mksnapshot.zip)
- if exist out\Default\hunspell_dictionaries.zip (appveyor-retry appveyor PushArtifact out\Default\hunspell_dictionaries.zip)
- if exist out\Default\electron.lib (appveyor-retry appveyor PushArtifact out\Default\electron.lib)
- if exist out\Default\electron.lib (appveyor-retry appveyor PushArtifact out\Default\electron.lib)
- ps: >-
if ((Test-Path "pdb.zip") -And ($env:GN_CONFIG -ne 'release')) {
appveyor-retry appveyor PushArtifact pdb.zip
@@ -277,9 +244,6 @@ for:
}
Invoke-RestMethod -Method Get -Uri "$apiUrl/buildjobs/$jobId/artifacts/$artifact_name" -OutFile $outfile
}
# Uncomment the following lines to download the pdb.zip to show real stacktraces when crashes happen during testing
# Invoke-RestMethod -Method Get -Uri "$apiUrl/buildjobs/$jobId/artifacts/pdb.zip" -OutFile pdb.zip
# 7z x -y -osrc pdb.zip
}
}
- ps: |

View File

@@ -1,8 +1,8 @@
is_electron_build = true
root_extra_deps = [ "//electron" ]
# Registry of NMVs --> https://github.com/nodejs/node/blob/main/doc/abi_version_registry.json
node_module_version = 116
# Registry of NMVs --> https://github.com/nodejs/node/blob/master/doc/abi_version_registry.json
node_module_version = 114
v8_promise_internal_field_count = 1
v8_embedder_string = "-electron.0"
@@ -45,13 +45,3 @@ is_cfi = false
# TODO: fix this once sysroots have been updated.
use_qt = false
# https://chromium-review.googlesource.com/c/chromium/src/+/4365718
# TODO(codebytere): fix perfetto incompatibility with Node.js.
use_perfetto_client_library = false
# Ref: https://chromium-review.googlesource.com/c/chromium/src/+/4402277
enable_check_raw_ptr_fields = false
# Disables the builtins PGO for V8
v8_builtins_profiling_log_file = ""

View File

@@ -55,7 +55,7 @@ The `Super` (or `Meta`) key is mapped to the `Windows` key on Windows and Linux
* `0` to `9`
* `A` to `Z`
* `F1` to `F24`
* Various Punctuation: `)`, `!`, `@`, `#`, `$`, `%`, `^`, `&`, `*`, `(`, `:`, `;`, `:`, `+`, `=`, `<`, `,`, `_`, `-`, `>`, `.`, `?`, `/`, `~`, `` ` ``, `{`, `]`, `[`, `|`, `\`, `}`, `"`
* Punctuation like `~`, `!`, `@`, `#`, `$`, etc.
* `Plus`
* `Space`
* `Tab`

View File

@@ -150,20 +150,9 @@ Returns:
* `event` Event
Emitted when the application becomes active. This differs from the `activate` event in
Emitted when mac application become active. Difference from `activate` event is
that `did-become-active` is emitted every time the app becomes active, not only
when Dock icon is clicked or application is re-launched. It is also emitted when a user
switches to the app via the macOS App Switcher.
### Event: 'did-resign-active' _macOS_
Returns:
* `event` Event
Emitted when the app is no longer active and doesnt have focus. This can be triggered,
for example, by clicking on another application or by using the macOS App Switcher to
switch to another application.
when Dock icon is clicked or application is re-launched.
### Event: 'continue-activity' _macOS_
@@ -413,7 +402,18 @@ Returns:
* `event` Event
* `webContents` [WebContents](web-contents.md)
* `details` [RenderProcessGoneDetails](structures/render-process-gone-details.md)
* `details` Object
* `reason` string - The reason the render process is gone. Possible values:
* `clean-exit` - Process exited with an exit code of zero
* `abnormal-exit` - Process exited with a non-zero exit code
* `killed` - Process was sent a SIGTERM or otherwise killed externally
* `crashed` - Process crashed
* `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.

View File

@@ -1110,14 +1110,10 @@ win.setBounds({ width: 100 })
console.log(win.getBounds())
```
**Note:** On macOS, the y-coordinate value cannot be smaller than the [Tray](tray.md) height. The tray height has changed over time and depends on the operating system, but is between 20-40px. Passing a value lower than the tray height will result in a window that is flush to the tray.
#### `win.getBounds()`
Returns [`Rectangle`](structures/rectangle.md) - The `bounds` of the window as `Object`.
**Note:** On macOS, the y-coordinate value returned will be at minimum the [Tray](tray.md) height. For example, calling `win.setBounds({ x: 25, y: 20, width: 800, height: 600 })` with a tray height of 38 means that `win.getBounds()` will return `{ x: 25, y: 38, width: 800, height: 600 }`.
#### `win.getBackgroundColor()`
Returns `string` - Gets the background color of the window in Hex (`#RRGGBB`) format.
@@ -1858,6 +1854,17 @@ will remove the vibrancy effect on the window.
Note that `appearance-based`, `light`, `dark`, `medium-light`, and `ultra-dark` have been
deprecated and will be removed in an upcoming version of macOS.
#### `win.setTrafficLightPosition(position)` _macOS_
* `position` [Point](structures/point.md)
Set a custom position for the traffic light buttons in frameless window.
#### `win.getTrafficLightPosition()` _macOS_
Returns `Point` - The custom position for the traffic light buttons in
frameless window.
#### `win.setBackgroundMaterial(material)` _Windows_
* `material` string
@@ -1873,37 +1880,6 @@ See the [Windows documentation](https://learn.microsoft.com/en-us/windows/win32/
**Note:** This method is only supported on Windows 11 22H2 and up.
#### `win.setWindowButtonPosition(position)` _macOS_
* `position` [Point](structures/point.md) | null
Set a custom position for the traffic light buttons in frameless window.
Passing `null` will reset the position to default.
#### `win.getWindowButtonPosition()` _macOS_
Returns `Point | null` - The custom position for the traffic light buttons in
frameless window, `null` will be returned when there is no custom position.
#### `win.setTrafficLightPosition(position)` _macOS_ _Deprecated_
* `position` [Point](structures/point.md)
Set a custom position for the traffic light buttons in frameless window.
Passing `{ x: 0, y: 0 }` will reset the position to default.
> **Note**
> This function is deprecated. Use [setWindowButtonPosition](#winsetwindowbuttonpositionposition-macos) instead.
#### `win.getTrafficLightPosition()` _macOS_ _Deprecated_
Returns `Point` - The custom position for the traffic light buttons in
frameless window, `{ x: 0, y: 0 }` will be returned when there is no custom
position.
> **Note**
> This function is deprecated. Use [getWindowButtonPosition](#wingetwindowbuttonposition-macos) instead.
#### `win.setTouchBar(touchBar)` _macOS_
* `touchBar` TouchBar | null

View File

@@ -23,14 +23,12 @@ following properties:
with which the request is associated. Defaults to the empty string. The
`session` option supersedes `partition`. Thus if a `session` is explicitly
specified, `partition` is ignored.
* `credentials` string (optional) - Can be `include`, `omit` or
`same-origin`. Whether to send
[credentials](https://fetch.spec.whatwg.org/#credentials) with this
* `credentials` string (optional) - Can be `include` or `omit`. Whether to
send [credentials](https://fetch.spec.whatwg.org/#credentials) with this
request. If set to `include`, credentials from the session associated with
the request will be used. If set to `omit`, credentials will not be sent
with the request (and the `'login'` event will not be triggered in the
event of a 401). If set to `same-origin`, `origin` must also be specified.
This matches the behavior of the
event of a 401). This matches the behavior of the
[fetch](https://fetch.spec.whatwg.org/#concept-request-credentials-mode)
option of the same name. If this option is not specified, authentication
data from the session will be sent, and cookies will not be sent (unless
@@ -51,13 +49,6 @@ following properties:
[`request.followRedirect`](#requestfollowredirect) is invoked synchronously
during the [`redirect`](#event-redirect) event. Defaults to `follow`.
* `origin` string (optional) - The origin URL of the request.
* `referrerPolicy` string (optional) - can be `""`, `no-referrer`,
`no-referrer-when-downgrade`, `origin`, `origin-when-cross-origin`,
`unsafe-url`, `same-origin`, `strict-origin`, or
`strict-origin-when-cross-origin`. Defaults to
`strict-origin-when-cross-origin`.
* `cache` string (optional) - can be `default`, `no-store`, `reload`,
`no-cache`, `force-cache` or `only-if-cached`.
`options` properties such as `protocol`, `host`, `hostname`, `port` and `path`
strictly follow the Node.js model as described in the
@@ -243,8 +234,6 @@ it is not allowed to add or remove a custom header.
* `encoding` string (optional)
* `callback` Function (optional)
Returns `this`.
Sends the last chunk of the request data. Subsequent write or end operations
will not be allowed. The `finish` event is emitted just after the end operation.

View File

@@ -116,20 +116,14 @@ Ignore the connections limit for `domains` list separated by `,`.
### --js-flags=`flags`
Specifies the flags passed to the [V8 engine](https://v8.dev). In order to enable the `flags` in the main process,
this switch must be passed on startup.
Specifies the flags passed to the Node.js engine. It has to be passed when starting
Electron if you want to enable the `flags` in the main process.
```sh
$ electron --js-flags="--harmony_proxies --harmony_collections" your-app
```
Run `node --v8-options` or `electron --js-flags="--help"` in your terminal for the list of available flags. These can be used to enable early-stage JavaScript features, or log and manipulate garbage collection, among other things.
For example, to trace V8 optimization and deoptimization:
```sh
$ electron --js-flags="--trace-opt --trace-deopt" your-app
```
See the [Node.js documentation][node-cli] or run `node --help` in your terminal for a list of available flags. Additionally, run `node --v8-options` to see a list of flags that specifically refer to Node.js's V8 JavaScript engine.
### --lang
@@ -247,25 +241,19 @@ Electron supports some of the [CLI flags][node-cli] supported by Node.js.
**Note:** Passing unsupported command line switches to Electron when it is not running in `ELECTRON_RUN_AS_NODE` will have no effect.
### `--inspect-brk\[=\[host:]port]`
### --inspect-brk\[=\[host:]port]
Activate inspector on host:port and break at start of user script. Default host:port is 127.0.0.1:9229.
Aliased to `--debug-brk=[host:]port`.
#### `--inspect-brk-node[=[host:]port]`
Activate inspector on `host:port` and break at start of the first internal
JavaScript script executed when the inspector is available.
Default `host:port` is `127.0.0.1:9229`.
### `--inspect-port=\[host:]port`
### --inspect-port=\[host:]port
Set the `host:port` to be used when the inspector is activated. Useful when activating the inspector by sending the SIGUSR1 signal. Default host is `127.0.0.1`.
Aliased to `--debug-port=[host:]port`.
### `--inspect\[=\[host:]port]`
### --inspect\[=\[host:]port]
Activate inspector on `host:port`. Default is `127.0.0.1:9229`.
@@ -275,37 +263,12 @@ See the [Debugging the Main Process][debugging-main-process] guide for more deta
Aliased to `--debug[=[host:]port`.
### `--inspect-publish-uid=stderr,http`
### --inspect-publish-uid=stderr,http
Specify ways of the inspector web socket url exposure.
By default inspector websocket url is available in stderr and under /json/list endpoint on http://host:port/json/list.
### `--no-deprecation`
Silence deprecation warnings.
### `--throw-deprecation`
Throw errors for deprecations.
### `--trace-deprecation`
Print stack traces for deprecations.
### `--trace-warnings`
Print stack traces for process warnings (including deprecations).
### `--dns-result-order=order`
Set the default value of the `verbatim` parameter in the Node.js [`dns.lookup()`](https://nodejs.org/api/dns.html#dnslookuphostname-options-callback) and [`dnsPromises.lookup()`](https://nodejs.org/api/dns.html#dnspromiseslookuphostname-options) functions. The value could be:
* `ipv4first`: sets default `verbatim` `false`.
* `verbatim`: sets default `verbatim` `true`.
The default is `verbatim` and `dns.setDefaultResultOrder()` have higher priority than `--dns-result-order`.
[app]: app.md
[append-switch]: command-line.md#commandlineappendswitchswitch-value
[debugging-main-process]: ../tutorial/debugging-main-process.md

View File

@@ -91,9 +91,8 @@ The following events of `chrome.runtime` are supported:
### `chrome.storage`
The following methods of `chrome.storage` are supported:
- `chrome.storage.local`
Only `chrome.storage.local` is supported; `chrome.storage.sync` and
`chrome.storage.managed` are not.
### `chrome.tabs`
@@ -102,8 +101,6 @@ The following methods of `chrome.tabs` are supported:
- `chrome.tabs.sendMessage`
- `chrome.tabs.reload`
- `chrome.tabs.executeScript`
- `chrome.tabs.query` (partial support)
- supported properties: `url`, `title`, `audible`, `active`, `muted`.
- `chrome.tabs.update` (partial support)
- supported properties: `url`, `muted`.
@@ -120,9 +117,6 @@ The following methods of `chrome.management` are supported:
- `chrome.management.getSelf`
- `chrome.management.getPermissionWarningsById`
- `chrome.management.getPermissionWarningsByManifest`
The following events of `chrome.management` are supported:
- `chrome.management.onEnabled`
- `chrome.management.onDisabled`

View File

@@ -72,7 +72,7 @@ Removes listeners of the specified `channel`.
### `ipcMain.handle(channel, listener)`
* `channel` string
* `listener` Function<Promise\<any&#62; | any&#62;
* `listener` Function<Promise\<void&#62; | any&#62;
* `event` [IpcMainInvokeEvent][ipc-main-invoke-event]
* `...args` any[]
@@ -109,8 +109,8 @@ provided to the renderer process. Please refer to
### `ipcMain.handleOnce(channel, listener)`
* `channel` string
* `listener` Function<Promise\<any&#62; | any&#62;
* `event` [IpcMainInvokeEvent][ipc-main-invoke-event]
* `listener` Function<Promise\<void&#62; | any&#62;
* `event` IpcMainInvokeEvent
* `...args` any[]
Handles a single `invoke`able IPC message, then removes the listener. See
@@ -122,6 +122,17 @@ Handles a single `invoke`able IPC message, then removes the listener. See
Removes any handler for `channel`, if present.
## IpcMainEvent object
The documentation for the `event` object passed to the `callback` can be found
in the [`ipc-main-event`][ipc-main-event] structure docs.
## IpcMainInvokeEvent object
The documentation for the `event` object passed to `handle` callbacks can be
found in the [`ipc-main-invoke-event`][ipc-main-invoke-event]
structure docs.
[IPC tutorial]: ../tutorial/ipc.md
[event-emitter]: https://nodejs.org/api/events.html#events_class_eventemitter
[web-contents-send]: ../api/web-contents.md#contentssendchannel-args

View File

@@ -26,7 +26,7 @@ The `ipcRenderer` module has the following method to listen for events and send
* `channel` string
* `listener` Function
* `event` [IpcRendererEvent][ipc-renderer-event]
* `event` IpcRendererEvent
* `...args` any[]
Listens to `channel`, when a new message arrives `listener` would be called with
@@ -36,7 +36,7 @@ Listens to `channel`, when a new message arrives `listener` would be called with
* `channel` string
* `listener` Function
* `event` [IpcRendererEvent][ipc-renderer-event]
* `event` IpcRendererEvent
* `...args` any[]
Adds a one time `listener` function for the event. This `listener` is invoked
@@ -208,8 +208,12 @@ Sends a message to a window with `webContentsId` via `channel`.
Like `ipcRenderer.send` but the event will be sent to the `<webview>` element in
the host page instead of the main process.
## Event object
The documentation for the `event` object passed to the `callback` can be found
in the [`ipc-renderer-event`](./structures/ipc-renderer-event.md) structure docs.
[event-emitter]: https://nodejs.org/api/events.html#events_class_eventemitter
[SCA]: https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Structured_clone_algorithm
[`window.postMessage`]: https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage
[`MessagePort`]: https://developer.mozilla.org/en-US/docs/Web/API/MessagePort
[ipc-renderer-event]: ./structures/ipc-renderer-event.md

View File

@@ -63,62 +63,6 @@ Creates a [`ClientRequest`](./client-request.md) instance using the provided
The `net.request` method would be used to issue both secure and insecure HTTP
requests according to the specified protocol scheme in the `options` object.
### `net.fetch(input[, init])`
* `input` string | [GlobalRequest](https://nodejs.org/api/globals.html#request)
* `init` [RequestInit](https://developer.mozilla.org/en-US/docs/Web/API/fetch#options) & { bypassCustomProtocolHandlers?: boolean } (optional)
Returns `Promise<GlobalResponse>` - see [Response](https://developer.mozilla.org/en-US/docs/Web/API/Response).
Sends a request, similarly to how `fetch()` works in the renderer, using
Chrome's network stack. This differs from Node's `fetch()`, which uses
Node.js's HTTP stack.
Example:
```js
async function example () {
const response = await net.fetch('https://my.app')
if (response.ok) {
const body = await response.json()
// ... use the result.
}
}
```
This method will issue requests from the [default
session](session.md#sessiondefaultsession). To send a `fetch` request from
another session, use [ses.fetch()](session.md#sesfetchinput-init).
See the MDN documentation for
[`fetch()`](https://developer.mozilla.org/en-US/docs/Web/API/fetch) for more
details.
Limitations:
* `net.fetch()` does not support the `data:` or `blob:` schemes.
* The value of the `integrity` option is ignored.
* The `.type` and `.url` values of the returned `Response` object are
incorrect.
By default, requests made with `net.fetch` can be made to [custom
protocols](protocol.md) as well as `file:`, and will trigger
[webRequest](web-request.md) handlers if present. When the non-standard
`bypassCustomProtocolHandlers` option is set in RequestInit, custom protocol
handlers will not be called for this request. This allows forwarding an
intercepted request to the built-in handler. [webRequest](web-request.md)
handlers will still be triggered when bypassing custom protocols.
```js
protocol.handle('https', (req) => {
if (req.url === 'https://my-app.com') {
return new Response('<body>my app</body>')
} else {
return net.fetch(req, { bypassCustomProtocolHandlers: true })
}
})
```
### `net.isOnline()`
Returns `boolean` - Whether there is currently internet connection.

View File

@@ -49,8 +49,6 @@ is used.
Stops the specified power save blocker.
Returns `boolean` - Whether the specified `powerSaveBlocker` has been stopped.
### `powerSaveBlocker.isStarted(id)`
* `id` Integer - The power save blocker id returned by `powerSaveBlocker.start`.

View File

@@ -49,11 +49,8 @@ beginning to load the web page or the main script.
### `process.defaultApp` _Readonly_
A `boolean`. When the app is started by being passed as parameter to the default Electron executable, this
A `boolean`. When app is started by being passed as parameter to the default app, this
property is `true` in the main process, otherwise it is `undefined`.
For example when running the app with `electron .`, it is `true`,
even if the app is packaged ([`isPackaged`](app.md#appispackaged-readonly)) is `true`.
This can be useful to determine how many arguments will need to be sliced off from `process.argv`.
### `process.isMainFrame` _Readonly_

View File

@@ -8,11 +8,15 @@ An example of implementing a protocol that has the same effect as the
`file://` protocol:
```javascript
const { app, protocol, net } = require('electron')
const { app, protocol } = require('electron')
const path = require('path')
const url = require('url')
app.whenReady().then(() => {
protocol.handle('atom', (request) =>
net.fetch('file://' + request.url.slice('atom://'.length)))
protocol.registerFileProtocol('atom', (request, callback) => {
const filePath = url.fileURLToPath('file://' + request.url.slice('atom://'.length))
callback(filePath)
})
})
```
@@ -34,15 +38,14 @@ to register it to that session explicitly.
```javascript
const { app, BrowserWindow, net, protocol, session } = require('electron')
const path = require('path')
const url = require('url')
app.whenReady().then(() => {
const partition = 'persist:example'
const ses = session.fromPartition(partition)
ses.protocol.handle('atom', (request) => {
const filePath = request.url.slice('atom://'.length)
return net.fetch(url.pathToFileURL(path.join(__dirname, filePath)).toString())
ses.protocol.registerFileProtocol('atom', (request, callback) => {
const url = request.url.substr(7)
callback({ path: path.normalize(path.join(__dirname, url)) })
})
const mainWindow = new BrowserWindow({ webPreferences: { partition } })
@@ -106,74 +109,7 @@ The `<video>` and `<audio>` HTML elements expect protocols to buffer their
responses by default. The `stream` flag configures those elements to correctly
expect streaming responses.
### `protocol.handle(scheme, handler)`
* `scheme` string - scheme to handle, for example `https` or `my-app`. This is
the bit before the `:` in a URL.
* `handler` Function<[GlobalResponse](https://nodejs.org/api/globals.html#response) | Promise<GlobalResponse>>
* `request` [GlobalRequest](https://nodejs.org/api/globals.html#request)
Register a protocol handler for `scheme`. Requests made to URLs with this
scheme will delegate to this handler to determine what response should be sent.
Either a `Response` or a `Promise<Response>` can be returned.
Example:
```js
const { app, net, protocol } = require('electron')
const { join } = require('path')
const { pathToFileURL } = require('url')
protocol.registerSchemesAsPrivileged([
{
scheme: 'app',
privileges: {
standard: true,
secure: true,
supportFetchAPI: true
}
}
])
app.whenReady().then(() => {
protocol.handle('app', (req) => {
const { host, pathname } = new URL(req.url)
if (host === 'bundle') {
if (pathname === '/') {
return new Response('<h1>hello, world</h1>', {
headers: { 'content-type': 'text/html' }
})
}
// NB, this does not check for paths that escape the bundle, e.g.
// app://bundle/../../secret_file.txt
return net.fetch(pathToFileURL(join(__dirname, pathname)).toString())
} else if (host === 'api') {
return net.fetch('https://api.my-server.com/' + pathname, {
method: req.method,
headers: req.headers,
body: req.body
})
}
})
})
```
See the MDN docs for [`Request`](https://developer.mozilla.org/en-US/docs/Web/API/Request) and [`Response`](https://developer.mozilla.org/en-US/docs/Web/API/Response) for more details.
### `protocol.unhandle(scheme)`
* `scheme` string - scheme for which to remove the handler.
Removes a protocol handler registered with `protocol.handle`.
### `protocol.isProtocolHandled(scheme)`
* `scheme` string
Returns `boolean` - Whether `scheme` is already handled.
### `protocol.registerFileProtocol(scheme, handler)` _Deprecated_
### `protocol.registerFileProtocol(scheme, handler)`
* `scheme` string
* `handler` Function
@@ -194,7 +130,7 @@ path or an object that has a `path` property, e.g. `callback(filePath)` or
By default the `scheme` is treated like `http:`, which is parsed differently
from protocols that follow the "generic URI syntax" like `file:`.
### `protocol.registerBufferProtocol(scheme, handler)` _Deprecated_
### `protocol.registerBufferProtocol(scheme, handler)`
* `scheme` string
* `handler` Function
@@ -218,7 +154,7 @@ protocol.registerBufferProtocol('atom', (request, callback) => {
})
```
### `protocol.registerStringProtocol(scheme, handler)` _Deprecated_
### `protocol.registerStringProtocol(scheme, handler)`
* `scheme` string
* `handler` Function
@@ -234,7 +170,7 @@ The usage is the same with `registerFileProtocol`, except that the `callback`
should be called with either a `string` or an object that has the `data`
property.
### `protocol.registerHttpProtocol(scheme, handler)` _Deprecated_
### `protocol.registerHttpProtocol(scheme, handler)`
* `scheme` string
* `handler` Function
@@ -249,7 +185,7 @@ Registers a protocol of `scheme` that will send an HTTP request as a response.
The usage is the same with `registerFileProtocol`, except that the `callback`
should be called with an object that has the `url` property.
### `protocol.registerStreamProtocol(scheme, handler)` _Deprecated_
### `protocol.registerStreamProtocol(scheme, handler)`
* `scheme` string
* `handler` Function
@@ -298,7 +234,7 @@ protocol.registerStreamProtocol('atom', (request, callback) => {
})
```
### `protocol.unregisterProtocol(scheme)` _Deprecated_
### `protocol.unregisterProtocol(scheme)`
* `scheme` string
@@ -306,13 +242,13 @@ Returns `boolean` - Whether the protocol was successfully unregistered
Unregisters the custom protocol of `scheme`.
### `protocol.isProtocolRegistered(scheme)` _Deprecated_
### `protocol.isProtocolRegistered(scheme)`
* `scheme` string
Returns `boolean` - Whether `scheme` is already registered.
### `protocol.interceptFileProtocol(scheme, handler)` _Deprecated_
### `protocol.interceptFileProtocol(scheme, handler)`
* `scheme` string
* `handler` Function
@@ -325,7 +261,7 @@ Returns `boolean` - Whether the protocol was successfully intercepted
Intercepts `scheme` protocol and uses `handler` as the protocol's new handler
which sends a file as a response.
### `protocol.interceptStringProtocol(scheme, handler)` _Deprecated_
### `protocol.interceptStringProtocol(scheme, handler)`
* `scheme` string
* `handler` Function
@@ -338,7 +274,7 @@ Returns `boolean` - Whether the protocol was successfully intercepted
Intercepts `scheme` protocol and uses `handler` as the protocol's new handler
which sends a `string` as a response.
### `protocol.interceptBufferProtocol(scheme, handler)` _Deprecated_
### `protocol.interceptBufferProtocol(scheme, handler)`
* `scheme` string
* `handler` Function
@@ -351,7 +287,7 @@ Returns `boolean` - Whether the protocol was successfully intercepted
Intercepts `scheme` protocol and uses `handler` as the protocol's new handler
which sends a `Buffer` as a response.
### `protocol.interceptHttpProtocol(scheme, handler)` _Deprecated_
### `protocol.interceptHttpProtocol(scheme, handler)`
* `scheme` string
* `handler` Function
@@ -364,7 +300,7 @@ Returns `boolean` - Whether the protocol was successfully intercepted
Intercepts `scheme` protocol and uses `handler` as the protocol's new handler
which sends a new HTTP request as a response.
### `protocol.interceptStreamProtocol(scheme, handler)` _Deprecated_
### `protocol.interceptStreamProtocol(scheme, handler)`
* `scheme` string
* `handler` Function
@@ -377,7 +313,7 @@ Returns `boolean` - Whether the protocol was successfully intercepted
Same as `protocol.registerStreamProtocol`, except that it replaces an existing
protocol handler.
### `protocol.uninterceptProtocol(scheme)` _Deprecated_
### `protocol.uninterceptProtocol(scheme)`
* `scheme` string
@@ -385,7 +321,7 @@ Returns `boolean` - Whether the protocol was successfully unintercepted
Remove the interceptor installed for `scheme` and restore its original handler.
### `protocol.isProtocolIntercepted(scheme)` _Deprecated_
### `protocol.isProtocolIntercepted(scheme)`
* `scheme` string

View File

@@ -38,31 +38,3 @@ Returns `string` - the decrypted string. Decrypts the encrypted buffer
obtained with `safeStorage.encryptString` back into a string.
This function will throw an error if decryption fails.
### `safeStorage.setUsePlainTextEncryption(usePlainText)`
* `usePlainText` boolean
This function on Linux will force the module to use an in memory password for creating
symmetric key that is used for encrypt/decrypt functions when a valid OS password
manager cannot be determined for the current active desktop environment. This function
is a no-op on Windows and MacOS.
### `safeStorage.getSelectedStorageBackend()` _Linux_
Returns `string` - User friendly name of the password manager selected on Linux.
This function will return one of the following values:
* `basic_text` - When the desktop environment is not recognised or if the following
command line flag is provided `--password-store="basic"`.
* `gnome_any` - When the desktop environment is `X-Cinnamon`, `Deepin`, `GNOME`, `Pantheon`, `XFCE`, `UKUI`, `unity` or if the following command line flag is provided `--password-store="gnome"`. When this value is present the application
will first try to use `libsecret` backend and if it fails will attempt to use `libgnome_keyring`.
* `gnome_libsecret` - When the following command line flag is provided `--password-store="gnome-libsecret"`.
* `gnome_keyring` - When the following command line flag is provided `--password-store="gnome-keyring"`.
* `kwallet` - When the desktop session is `kde4` or if the following command line flag
is provided `--password-store="kwallet"`.
* `kwallet5` - When the desktop session is `kde5` or if the following command line flag
is provided `--password-store="kwallet5"`.
* `kwallet6` - When the desktop session is `kde6`.
* `unknown` - When the function is called before app has emitted the `ready` event.

View File

@@ -42,22 +42,6 @@ To create a `Session` with `options`, you have to ensure the `Session` with the
`partition` has never been used before. There is no way to change the `options`
of an existing `Session` object.
### `session.fromPath(path[, options])`
* `path` string
* `options` Object (optional)
* `cache` boolean - Whether to enable cache.
Returns `Session` - A session instance from the absolute path as specified by the `path`
string. When there is an existing `Session` with the same absolute path, it
will be returned; otherwise a new `Session` instance will be created with `options`. The
call will throw an error if the path is not an absolute path. Additionally, an error will
be thrown if an empty string is provided.
To create a `Session` with `options`, you have to ensure the `Session` with the
`path` has never been used before. There is no way to change the `options`
of an existing `Session` object.
## Properties
The `session` module has the following properties:
@@ -519,8 +503,9 @@ app.whenReady().then(() => {
Returns:
* `event` Event
* `device` [USBDevice](structures/usb-device.md)
* `webContents` [WebContents](web-contents.md)
* `details` Object
* `device` [USBDevice](structures/usb-device.md)
* `frame` [WebFrameMain](web-frame-main.md)
Emitted after `navigator.usb.requestDevice` has been called and
`select-usb-device` has fired if a new device becomes available before
@@ -533,8 +518,9 @@ with the newly added device.
Returns:
* `event` Event
* `device` [USBDevice](structures/usb-device.md)
* `webContents` [WebContents](web-contents.md)
* `details` Object
* `device` [USBDevice](structures/usb-device.md)
* `frame` [WebFrameMain](web-frame-main.md)
Emitted after `navigator.usb.requestDevice` has been called and
`select-usb-device` has fired if a device has been removed before the callback
@@ -548,7 +534,7 @@ Returns:
* `event` Event
* `details` Object
* `device` [USBDevice](structures/usb-device.md)
* `device` [USBDevice[]](structures/usb-device.md)
* `origin` string (optional) - The origin that the device has been revoked from.
Emitted after `USBDevice.forget()` has been called. This event can be used
@@ -782,61 +768,6 @@ Returns `Promise<void>` - Resolves when all connections are closed.
**Note:** It will terminate / fail all requests currently in flight.
#### `ses.fetch(input[, init])`
* `input` string | [GlobalRequest](https://nodejs.org/api/globals.html#request)
* `init` [RequestInit](https://developer.mozilla.org/en-US/docs/Web/API/fetch#options) (optional)
Returns `Promise<GlobalResponse>` - see [Response](https://developer.mozilla.org/en-US/docs/Web/API/Response).
Sends a request, similarly to how `fetch()` works in the renderer, using
Chrome's network stack. This differs from Node's `fetch()`, which uses
Node.js's HTTP stack.
Example:
```js
async function example () {
const response = await net.fetch('https://my.app')
if (response.ok) {
const body = await response.json()
// ... use the result.
}
}
```
See also [`net.fetch()`](net.md#netfetchinput-init), a convenience method which
issues requests from the [default session](#sessiondefaultsession).
See the MDN documentation for
[`fetch()`](https://developer.mozilla.org/en-US/docs/Web/API/fetch) for more
details.
Limitations:
* `net.fetch()` does not support the `data:` or `blob:` schemes.
* The value of the `integrity` option is ignored.
* The `.type` and `.url` values of the returned `Response` object are
incorrect.
By default, requests made with `net.fetch` can be made to [custom
protocols](protocol.md) as well as `file:`, and will trigger
[webRequest](web-request.md) handlers if present. When the non-standard
`bypassCustomProtocolHandlers` option is set in RequestInit, custom protocol
handlers will not be called for this request. This allows forwarding an
intercepted request to the built-in handler. [webRequest](web-request.md)
handlers will still be triggered when bypassing custom protocols.
```js
protocol.handle('https', (req) => {
if (req.url === 'https://my-app.com') {
return new Response('<body>my app</body>')
} else {
return net.fetch(req, { bypassCustomProtocolHandlers: true })
}
})
```
#### `ses.disableNetworkEmulation()`
Disables any network emulation already active for the `session`. Resets to
@@ -891,19 +822,18 @@ win.webContents.session.setCertificateVerifyProc((request, callback) => {
* `permission` string - The type of requested permission.
* `clipboard-read` - Request access to read from the clipboard.
* `clipboard-sanitized-write` - Request access to write to the clipboard.
* `display-capture` - Request access to capture the screen via the [Screen Capture API](https://developer.mozilla.org/en-US/docs/Web/API/Screen_Capture_API).
* `fullscreen` - Request control of the app's fullscreen state via the [Fullscreen API](https://developer.mozilla.org/en-US/docs/Web/API/Fullscreen_API).
* `geolocation` - Request access to the user's location via the [Geolocation API](https://developer.mozilla.org/en-US/docs/Web/API/Geolocation_API)
* `idle-detection` - Request access to the user's idle state via the [IdleDetector API](https://developer.mozilla.org/en-US/docs/Web/API/IdleDetector).
* `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.
* `midi` - Request MIDI access in the [Web MIDI API](https://developer.mozilla.org/en-US/docs/Web/API/Web_MIDI_API).
* `midiSysex` - Request the use of system exclusive messages in the [Web MIDI API](https://developer.mozilla.org/en-US/docs/Web/API/Web_MIDI_API).
* `notifications` - Request notification creation and the ability to display them in the user's system tray using the [Notifications API](https://developer.mozilla.org/en-US/docs/Web/API/notification)
* `pointerLock` - Request to directly interpret mouse movements as an input method via the [Pointer Lock API](https://developer.mozilla.org/en-US/docs/Web/API/Pointer_Lock_API). These requests always appear to originate from the main frame.
* `geolocation` - Request access to user's current location.
* `notifications` - Request notification creation and the ability to display them in the user's system tray.
* `midi` - Request MIDI access in the `webmidi` API.
* `midiSysex` - Request the use of system exclusive messages in the `webmidi` API.
* `pointerLock` - Request to directly interpret mouse movements as an input method. Click [here](https://developer.mozilla.org/en-US/docs/Web/API/Pointer_Lock_API) to know more. These requests always appear to originate from the main frame.
* `fullscreen` - Request for the app to enter fullscreen mode.
* `openExternal` - Request to open links in external applications.
* `window-management` - Request access to enumerate screens using the [`getScreenDetails`](https://developer.chrome.com/en/articles/multi-screen-window-placement/) API.
* `unknown` - An unrecognized permission request.
* `unknown` - An unrecognized permission request
* `callback` Function
* `permissionGranted` boolean - Allow or deny the permission.
* `details` Object - Some properties are only available on certain permission types.
@@ -935,22 +865,7 @@ session.fromPartition('some-partition').setPermissionRequestHandler((webContents
* `handler` Function\<boolean> | null
* `webContents` ([WebContents](web-contents.md) | null) - WebContents checking the permission. Please note that if the request comes from a subframe you should use `requestingUrl` to check the request origin. All cross origin sub frames making permission checks will pass a `null` webContents to this handler, while certain other permission checks such as `notifications` checks will always pass `null`. You should use `embeddingOrigin` and `requestingOrigin` to determine what origin the owning frame and the requesting frame are on respectively.
* `permission` string - Type of permission check.
* `clipboard-read` - Request access to read from the clipboard.
* `clipboard-sanitized-write` - Request access to write to the clipboard.
* `geolocation` - Access the user's geolocation data via the [Geolocation API](https://developer.mozilla.org/en-US/docs/Web/API/Geolocation_API)
* `fullscreen` - Control of the app's fullscreen state via the [Fullscreen API](https://developer.mozilla.org/en-US/docs/Web/API/Fullscreen_API).
* `hid` - Access the HID protocol to manipulate HID devices via the [WebHID API](https://developer.mozilla.org/en-US/docs/Web/API/WebHID_API).
* `idle-detection` - Access the user's idle state via the [IdleDetector API](https://developer.mozilla.org/en-US/docs/Web/API/IdleDetector).
* `media` - Access to media devices such as camera, microphone and speakers.
* `mediaKeySystem` - Access to DRM protected content.
* `midi` - Enable MIDI access in the [Web MIDI API](https://developer.mozilla.org/en-US/docs/Web/API/Web_MIDI_API).
* `midiSysex` - Use system exclusive messages in the [Web MIDI API](https://developer.mozilla.org/en-US/docs/Web/API/Web_MIDI_API).
* `notifications` - Configure and display desktop notifications to the user with the [Notifications API](https://developer.mozilla.org/en-US/docs/Web/API/notification).
* `openExternal` - Open links in external applications.
* `pointerLock` - Directly interpret mouse movements as an input method via the [Pointer Lock API](https://developer.mozilla.org/en-US/docs/Web/API/Pointer_Lock_API). These requests always appear to originate from the main frame.
* `serial` - Read from and write to serial devices with the [Web Serial API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Serial_API).
* `usb` - Expose non-standard Universal Serial Bus (USB) compatible devices services to the web with the [WebUSB API](https://developer.mozilla.org/en-US/docs/Web/API/WebUSB_API).
* `permission` string - Type of permission check. Valid values are `midiSysex`, `notifications`, `geolocation`, `media`,`mediaKeySystem`,`midi`, `pointerLock`, `fullscreen`, `openExternal`, `hid`, `serial`, or `usb`.
* `requestingOrigin` string - The origin URL of the permission check
* `details` Object - Some properties are only available on certain permission types.
* `embeddingOrigin` string (optional) - The origin of the frame embedding the frame that made the permission check. Only set for cross-origin sub frames making permission checks.
@@ -1300,18 +1215,16 @@ reused for new connections.
Returns `Promise<Buffer>` - resolves with blob data.
#### `ses.downloadURL(url[, options])`
#### `ses.downloadURL(url)`
* `url` string
* `options` Object (optional)
* `headers` Record<string, string> (optional) - HTTP request headers.
Initiates a download of the resource at `url`.
The API will generate a [DownloadItem](download-item.md) that can be accessed
with the [will-download](#event-will-download) event.
**Note:** This does not perform any security checks that relate to a page's origin,
unlike [`webContents.downloadURL`](web-contents.md#contentsdownloadurlurl-options).
unlike [`webContents.downloadURL`](web-contents.md#contentsdownloadurlurl).
#### `ses.createInterruptedDownload(options)`

View File

@@ -0,0 +1,3 @@
# Event Object extends `GlobalEvent`
* `preventDefault` VoidFunction

View File

@@ -2,7 +2,6 @@
* `sender` [IpcRenderer](../ipc-renderer.md) - The `IpcRenderer` instance that emitted the event originally
* `senderId` Integer - The `webContents.id` that sent the message, you can call `event.sender.sendTo(event.senderId, ...)` to reply to the message, see [ipcRenderer.sendTo][ipc-renderer-sendto] for more information. This only applies to messages sent from a different renderer. Messages sent directly from the main process set `event.senderId` to `0`.
* `senderIsMainFrame` boolean (optional) - Whether the message sent via [ipcRenderer.sendTo][ipc-renderer-sendto] was sent by the main frame. This is relevant when `nodeIntegrationInSubFrames` is enabled in the originating `webContents`.
* `ports` [MessagePort][][] - A list of MessagePorts that were transferred with this message
[ipc-renderer-sendto]: ../ipc-renderer.md#ipcrenderersendtowebcontentsid-channel-args

View File

@@ -1,13 +0,0 @@
# RenderProcessGoneDetails Object
* `reason` string - The reason the render process is gone. Possible values:
* `clean-exit` - Process exited with an exit code of zero
* `abnormal-exit` - Process exited with a non-zero exit code
* `killed` - Process was sent a SIGTERM or otherwise killed externally
* `crashed` - Process crashed
* `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.

View File

@@ -2,8 +2,8 @@
* `type` 'file' - `file`.
* `filePath` string - Path of file to be uploaded.
* `offset` Integer (optional) - Defaults to `0`.
* `length` Integer (optional) - Number of bytes to read from `offset`.
* `offset` Integer - Defaults to `0`.
* `length` Integer - Number of bytes to read from `offset`.
Defaults to `0`.
* `modificationTime` Double (optional) - Last Modification time in
number of seconds since the UNIX epoch. Defaults to `0`.
* `modificationTime` Double - Last Modification time in
number of seconds since the UNIX epoch.

View File

@@ -6,7 +6,7 @@ Process: [Main](../glossary.md#main-process)
```javascript
const { systemPreferences } = require('electron')
console.log(systemPreferences.isAeroGlassEnabled())
console.log(systemPreferences.isDarkMode())
```
## Events
@@ -47,6 +47,12 @@ Returns:
## Methods
### `systemPreferences.isDarkMode()` _macOS_ _Windows_ _Deprecated_
Returns `boolean` - Whether the system is in Dark Mode.
**Deprecated:** Should use the new [`nativeTheme.shouldUseDarkColors`](native-theme.md#nativethemeshouldusedarkcolors-readonly) API.
### `systemPreferences.isSwipeTrackingFromScrollEventsEnabled()` _macOS_
Returns `boolean` - Whether the Swipe between pages setting is on.
@@ -291,7 +297,7 @@ This API is only available on macOS 10.14 Mojave or newer.
* `window-frame` - Window frame.
* `window-text` - Text in windows.
* On **macOS**
* `alternate-selected-control-text` - The text on a selected surface in a list or table. _Deprecated_
* `alternate-selected-control-text` - The text on a selected surface in a list or table. _deprecated_
* `control-background` - The background of a large interface element, such as a browser or table.
* `control` - The surface of a control.
* `control-text` -The text of a control that isnt disabled.
@@ -350,6 +356,18 @@ Returns `string` - The standard system color formatted as `#RRGGBBAA`.
Returns one of several standard system colors that automatically adapt to vibrancy and changes in accessibility settings like 'Increase contrast' and 'Reduce transparency'. See [Apple Documentation](https://developer.apple.com/design/human-interface-guidelines/macos/visual-design/color#system-colors) for more details.
### `systemPreferences.isInvertedColorScheme()` _Windows_ _Deprecated_
Returns `boolean` - `true` if an inverted color scheme (a high contrast color scheme with light text and dark backgrounds) is active, `false` otherwise.
**Deprecated:** Should use the new [`nativeTheme.shouldUseInvertedColorScheme`](native-theme.md#nativethemeshoulduseinvertedcolorscheme-macos-windows-readonly) API.
### `systemPreferences.isHighContrastColorScheme()` _macOS_ _Windows_ _Deprecated_
Returns `boolean` - `true` if a high contrast theme is active, `false` otherwise.
**Deprecated:** Should use the new [`nativeTheme.shouldUseHighContrastColors`](native-theme.md#nativethemeshouldusehighcontrastcolors-macos-windows-readonly) API.
### `systemPreferences.getEffectiveAppearance()` _macOS_
Returns `string` - Can be `dark`, `light` or `unknown`.

View File

@@ -19,36 +19,6 @@ const contents = win.webContents
console.log(contents)
```
## Navigation Events
Several events can be used to monitor navigations as they occur within a `webContents`.
### Document Navigations
When a `webContents` navigates to another page (as opposed to an [in-page navigation](web-contents.md#in-page-navigation)), the following events will be fired.
* [`did-start-navigation`](web-contents.md#event-did-start-navigation)
* [`will-frame-navigate`](web-contents.md#event-will-frame-navigate)
* [`will-navigate`](web-contents.md#event-will-navigate) (only fired when main frame navigates)
* [`will-redirect`](web-contents.md#event-will-redirect) (only fired when a redirect happens during navigation)
* [`did-redirect-navigation`](web-contents.md#event-did-redirect-navigation) (only fired when a redirect happens during navigation)
* [`did-frame-navigate`](web-contents.md#event-did-frame-navigate)
* [`did-navigate`](web-contents.md#event-did-navigate) (only fired when main frame navigates)
Subsequent events will not fire if `event.preventDefault()` is called on any of the cancellable events.
### In-page Navigation
In-page navigations don't cause the page to reload, but instead navigate to a location within the current page. These events are not cancellable. For an in-page navigations, the following events will fire in this order:
* [`did-start-navigation`](web-contents.md#event-did-start-navigation)
* [`did-navigate-in-page`](web-contents.md#event-did-navigate-in-page)
### Frame Navigation
The [`will-navigate`](web-contents.md#event-will-navigate) and [`did-navigate`](web-contents.md#event-did-navigate) events only fire when the [mainFrame](web-contents.md#contentsmainframe-readonly) navigates.
If you want to also observe navigations in `<iframe>`s, use [`will-frame-navigate`](web-contents.md#event-will-frame-navigate) and [`did-frame-navigate`](web-contents.md#event-did-frame-navigate) events.
## Methods
These methods can be accessed from the `webContents` module:
@@ -237,25 +207,10 @@ See [`window.open()`](window-open.md) for more details and how to use this in co
Returns:
* `details` Event<>
* `url` string - The URL the frame is navigating to.
* `isSameDocument` boolean - Whether the navigation happened without changing
document. Examples of same document navigations are reference fragment
navigations, pushState/replaceState, and same page history navigation.
* `isMainFrame` boolean - True if the navigation is taking place in a main frame.
* `frame` WebFrameMain - The frame to be navigated.
* `initiator` WebFrameMain (optional) - The frame which initiated the
navigation, which can be a parent frame (e.g. via `window.open` with a
frame's name), or null if the navigation was not initiated by a frame. This
can also be null if the initiating frame was deleted before the event was
emitted.
* `url` string _Deprecated_
* `isInPlace` boolean _Deprecated_
* `isMainFrame` boolean _Deprecated_
* `frameProcessId` Integer _Deprecated_
* `frameRoutingId` Integer _Deprecated_
* `event` Event
* `url` string
Emitted when a user or the page wants to start navigation on the main frame. It can happen when
Emitted when a user or the page wants to start navigation. It can happen when
the `window.location` object is changed or a user clicks a link in the page.
This event will not emit when the navigation is started programmatically with
@@ -267,79 +222,30 @@ this purpose.
Calling `event.preventDefault()` will prevent the navigation.
#### Event: 'will-frame-navigate'
Returns:
* `details` Event<>
* `url` string - The URL the frame is navigating to.
* `isMainFrame` boolean - True if the navigation is taking place in a main frame.
* `frame` WebFrameMain - The frame to be navigated.
* `initiator` WebFrameMain (optional) - The frame which initiated the
navigation, which can be a parent frame (e.g. via `window.open` with a
frame's name), or null if the navigation was not initiated by a frame. This
can also be null if the initiating frame was deleted before the event was
emitted.
Emitted when a user or the page wants to start navigation in any frame. It can happen when
the `window.location` object is changed or a user clicks a link in the page.
Unlike `will-navigate`, `will-frame-navigate` is fired when the main frame or any of its subframes attempts to navigate. When the navigation event comes from the main frame, `isMainFrame` will be `true`.
This event will not emit when the navigation is started programmatically with
APIs like `webContents.loadURL` and `webContents.back`.
It is also not emitted for in-page navigations, such as clicking anchor links
or updating the `window.location.hash`. Use `did-navigate-in-page` event for
this purpose.
Calling `event.preventDefault()` will prevent the navigation.
#### Event: 'did-start-navigation'
Returns:
* `details` Event<>
* `url` string - The URL the frame is navigating to.
* `isSameDocument` boolean - Whether the navigation happened without changing
document. Examples of same document navigations are reference fragment
navigations, pushState/replaceState, and same page history navigation.
* `isMainFrame` boolean - True if the navigation is taking place in a main frame.
* `frame` WebFrameMain - The frame to be navigated.
* `initiator` WebFrameMain (optional) - The frame which initiated the
navigation, which can be a parent frame (e.g. via `window.open` with a
frame's name), or null if the navigation was not initiated by a frame. This
can also be null if the initiating frame was deleted before the event was
emitted.
* `url` string _Deprecated_
* `isInPlace` boolean _Deprecated_
* `isMainFrame` boolean _Deprecated_
* `frameProcessId` Integer _Deprecated_
* `frameRoutingId` Integer _Deprecated_
* `event` Event
* `url` string
* `isInPlace` boolean
* `isMainFrame` boolean
* `frameProcessId` Integer
* `frameRoutingId` Integer
Emitted when any frame (including main) starts navigating.
Emitted when any frame (including main) starts navigating. `isInPlace` will be
`true` for in-page navigations.
#### Event: 'will-redirect'
Returns:
* `details` Event<>
* `url` string - The URL the frame is navigating to.
* `isSameDocument` boolean - Whether the navigation happened without changing
document. Examples of same document navigations are reference fragment
navigations, pushState/replaceState, and same page history navigation.
* `isMainFrame` boolean - True if the navigation is taking place in a main frame.
* `frame` WebFrameMain - The frame to be navigated.
* `initiator` WebFrameMain (optional) - The frame which initiated the
navigation, which can be a parent frame (e.g. via `window.open` with a
frame's name), or null if the navigation was not initiated by a frame. This
can also be null if the initiating frame was deleted before the event was
emitted.
* `url` string _Deprecated_
* `isInPlace` boolean _Deprecated_
* `isMainFrame` boolean _Deprecated_
* `frameProcessId` Integer _Deprecated_
* `frameRoutingId` Integer _Deprecated_
* `event` Event
* `url` string
* `isInPlace` boolean
* `isMainFrame` boolean
* `frameProcessId` Integer
* `frameRoutingId` Integer
Emitted when a server side redirect occurs during navigation. For example a 302
redirect.
@@ -354,23 +260,12 @@ redirect).
Returns:
* `details` Event<>
* `url` string - The URL the frame is navigating to.
* `isSameDocument` boolean - Whether the navigation happened without changing
document. Examples of same document navigations are reference fragment
navigations, pushState/replaceState, and same page history navigation.
* `isMainFrame` boolean - True if the navigation is taking place in a main frame.
* `frame` WebFrameMain - The frame to be navigated.
* `initiator` WebFrameMain (optional) - The frame which initiated the
navigation, which can be a parent frame (e.g. via `window.open` with a
frame's name), or null if the navigation was not initiated by a frame. This
can also be null if the initiating frame was deleted before the event was
emitted.
* `url` string _Deprecated_
* `isInPlace` boolean _Deprecated_
* `isMainFrame` boolean _Deprecated_
* `frameProcessId` Integer _Deprecated_
* `frameRoutingId` Integer _Deprecated_
* `event` Event
* `url` string
* `isInPlace` boolean
* `isMainFrame` boolean
* `frameProcessId` Integer
* `frameRoutingId` Integer
Emitted after a server side redirect occurs during navigation. For example a 302
redirect.
@@ -478,7 +373,18 @@ checking `reason === 'killed'` when you switch to that event.
Returns:
* `event` Event
* `details` [RenderProcessGoneDetails](structures/render-process-gone-details.md)
* `details` Object
* `reason` string - The reason the render process is gone. Possible values:
* `clean-exit` - Process exited with an exit code of zero
* `abnormal-exit` - Process exited with a non-zero exit code
* `killed` - Process was sent a SIGTERM or otherwise killed externally
* `crashed` - Process crashed
* `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.
@@ -683,15 +589,6 @@ Emitted when media starts playing.
Emitted when media is paused or done playing.
#### Event: 'audio-state-changed'
Returns:
* `event` Event<>
* `audible` boolean - True if one or more frames or child `webContents` are emitting audio.
Emitted when media becomes audible or inaudible.
#### Event: 'did-change-theme-color'
Returns:
@@ -944,7 +841,7 @@ Emitted when the preload script `preloadPath` throws an unhandled exception `err
Returns:
* `event` [IpcMainEvent](structures/ipc-main-event.md)
* `event` Event
* `channel` string
* `...args` any[]
@@ -956,7 +853,7 @@ See also [`webContents.ipc`](#contentsipc-readonly), which provides an [`IpcMain
Returns:
* `event` [IpcMainEvent](structures/ipc-main-event.md)
* `event` Event
* `channel` string
* `...args` any[]
@@ -1045,11 +942,9 @@ const win = new BrowserWindow()
win.loadFile('src/index.html')
```
#### `contents.downloadURL(url[, options])`
#### `contents.downloadURL(url)`
* `url` string
* `options` Object (optional)
* `headers` Record<string, string> (optional) - HTTP request headers.
Initiates a download of the resource at `url` without navigating. The
`will-download` event of `session` will be triggered.
@@ -1392,10 +1287,6 @@ Executes the editing command `cut` in web page.
Executes the editing command `copy` in web page.
#### `contents.centerSelection()`
Centers the current text selection in web page.
#### `contents.copyImageAt(x, y)`
* `x` Integer
@@ -1423,46 +1314,6 @@ Executes the editing command `selectAll` in web page.
Executes the editing command `unselect` in web page.
#### `contents.scrollToTop()`
Scrolls to the top of the current `webContents`.
#### `contents.scrollToBottom()`
Scrolls to the bottom of the current `webContents`.
#### `contents.adjustSelection(options)`
* `options` Object
* `start` Number (optional) - Amount to shift the start index of the current selection.
* `end` Number (optional) - Amount to shift the end index of the current selection.
Adjusts the current text selection starting and ending points in the focused frame by the given amounts. A negative amount moves the selection towards the beginning of the document, and a positive amount moves the selection towards the end of the document.
Example:
```js
const win = new BrowserWindow()
// Adjusts the beginning of the selection 1 letter forward,
// and the end of the selection 5 letters forward.
win.webContents.adjustSelection({ start: 1, end: 5 })
// Adjusts the beginning of the selection 2 letters forward,
// and the end of the selection 3 letters backward.
win.webContents.adjustSelection({ start: 2, end: -3 })
```
For a call of `win.webContents.adjustSelection({ start: 1, end: 5 })`
Before:
<img width="487" alt="Image Before Text Selection Adjustment" src="../images/web-contents-text-selection-before.png"/>
After:
<img width="487" alt="Image After Text Selection Adjustment" src="../images/web-contents-text-selection-after.png"/>
#### `contents.replace(text)`
* `text` string

View File

@@ -280,11 +280,9 @@ if the page fails to load (see
Loads the `url` in the webview, the `url` must contain the protocol prefix,
e.g. the `http://` or `file://`.
### `<webview>.downloadURL(url[, options])`
### `<webview>.downloadURL(url)`
* `url` string
* `options` Object (optional)
* `headers` Record<string, string> (optional) - HTTP request headers.
Initiates a download of the resource at `url` without navigating.
@@ -467,10 +465,6 @@ Executes editing command `cut` in page.
Executes editing command `copy` in page.
#### `<webview>.centerSelection()`
Centers the current text selection in page.
### `<webview>.paste()`
Executes editing command `paste` in page.
@@ -491,25 +485,6 @@ Executes editing command `selectAll` in page.
Executes editing command `unselect` in page.
#### `<webview>.scrollToTop()`
Scrolls to the top of the current `<webview>`.
#### `<webview>.scrollToBottom()`
Scrolls to the bottom of the current `<webview>`.
#### `<webview>.adjustSelection(options)`
* `options` Object
* `start` Number (optional) - Amount to shift the start index of the current selection.
* `end` Number (optional) - Amount to shift the end index of the current selection.
Adjusts the current text selection starting and ending points in the focused frame by the given amounts. A negative amount moves the selection towards the beginning of the document, and a positive amount moves the selection towards the end of the document.
See [`webContents.adjustSelection`](web-contents.md#contentsadjustselectionoptions) for
examples.
### `<webview>.replace(text)`
* `text` string
@@ -850,28 +825,6 @@ this purpose.
Calling `event.preventDefault()` does **NOT** have any effect.
### Event: 'will-frame-navigate'
Returns:
* `url` string
* `isMainFrame` boolean
* `frameProcessId` Integer
* `frameRoutingId` Integer
Emitted when a user or the page wants to start navigation anywhere in the `<webview>`
or any frames embedded within. It can happen when the `window.location` object is
changed or a user clicks a link in the page.
This event will not emit when the navigation is started programmatically with
APIs like `<webview>.loadURL` and `<webview>.back`.
It is also not emitted during in-page navigation, such as clicking anchor links
or updating the `window.location.hash`. Use `did-navigate-in-page` event for
this purpose.
Calling `event.preventDefault()` does **NOT** have any effect.
### Event: 'did-start-navigation'
Returns:
@@ -985,22 +938,9 @@ ipcRenderer.on('ping', () => {
})
```
### Event: 'crashed' _Deprecated_
### Event: 'crashed'
Fired when the renderer process crashes or is killed.
**Deprecated:** This event is superceded by the `render-process-gone` event
which contains more information about why the render process disappeared. It
isn't always because it crashed.
### Event: 'render-process-gone'
Returns:
* `details` [RenderProcessGoneDetails](structures/render-process-gone-details.md)
Fired when the renderer process unexpectedly disappears. This is normally
because it was crashed or killed.
Fired when the renderer process is crashed.
### Event: 'plugin-crashed'

View File

@@ -59,7 +59,7 @@ window.open('https://github.com', '_blank', 'top=500,left=200,frame=false,nodeIn
* Non-standard features (that are not handled by Chromium or Electron) given in
`features` will be passed to any registered `webContents`'s
`did-create-window` event handler in the `options` argument.
* `frameName` follows the specification of `target` located in the [native documentation](https://developer.mozilla.org/en-US/docs/Web/API/Window/open#parameters).
* `frameName` follows the specification of `windowName` located in the [native documentation](https://developer.mozilla.org/en-US/docs/Web/API/Window/open#parameters).
* When opening `about:blank`, the child window's `WebPreferences` will be copied
from the parent window, and there is no way to override it because Chromium
skips browser side navigation in this case.

View File

@@ -12,102 +12,6 @@ This document uses the following convention to categorize breaking changes:
* **Deprecated:** An API was marked as deprecated. The API will continue to function, but will emit a deprecation warning, and will be removed in a future release.
* **Removed:** An API or feature was removed, and is no longer supported by Electron.
## Planned Breaking API Changes (27.0)
### Removed: macOS 10.13 / 10.14 support
macOS 10.13 (High Sierra) and macOS 10.14 (Mojave) are no longer supported by [Chromium](https://chromium-review.googlesource.com/c/chromium/src/+/4629466).
Older versions of Electron will continue to run on these operating systems, but macOS 10.15 (Catalina)
or later will be required to run Electron v27.0.0 and higher.
## Planned Breaking API Changes (25.0)
### Deprecated: `protocol.{register,intercept}{Buffer,String,Stream,File,Http}Protocol`
The `protocol.register*Protocol` and `protocol.intercept*Protocol` methods have
been replaced with [`protocol.handle`](api/protocol.md#protocolhandlescheme-handler).
The new method can either register a new protocol or intercept an existing
protocol, and responses can be of any type.
```js
// Deprecated in Electron 25
protocol.registerBufferProtocol('some-protocol', () => {
callback({ mimeType: 'text/html', data: Buffer.from('<h5>Response</h5>') })
})
// Replace with
protocol.handle('some-protocol', () => {
return new Response(
Buffer.from('<h5>Response</h5>'), // Could also be a string or ReadableStream.
{ headers: { 'content-type': 'text/html' } }
)
})
```
```js
// Deprecated in Electron 25
protocol.registerHttpProtocol('some-protocol', () => {
callback({ url: 'https://electronjs.org' })
})
// Replace with
protocol.handle('some-protocol', () => {
return net.fetch('https://electronjs.org')
})
```
```js
// Deprecated in Electron 25
protocol.registerFileProtocol('some-protocol', () => {
callback({ filePath: '/path/to/my/file' })
})
// Replace with
protocol.handle('some-protocol', () => {
return net.fetch('file:///path/to/my/file')
})
```
### Deprecated: `BrowserWindow.setTrafficLightPosition(position)`
`BrowserWindow.setTrafficLightPosition(position)` has been deprecated, the
`BrowserWindow.setWindowButtonPosition(position)` API should be used instead
which accepts `null` instead of `{ x: 0, y: 0 }` to reset the position to
system default.
```js
// Deprecated in Electron 25
win.setTrafficLightPosition({ x: 10, y: 10 })
win.setTrafficLightPosition({ x: 0, y: 0 })
// Replace with
win.setWindowButtonPosition({ x: 10, y: 10 })
win.setWindowButtonPosition(null)
```
### Deprecated: `BrowserWindow.getTrafficLightPosition()`
`BrowserWindow.getTrafficLightPosition()` has been deprecated, the
`BrowserWindow.getWindowButtonPosition()` API should be used instead
which returns `null` instead of `{ x: 0, y: 0 }` when there is no custom
position.
```js
// Deprecated in Electron 25
const pos = win.getTrafficLightPosition()
if (pos.x === 0 && pos.y === 0) {
// No custom position.
}
// Replace with
const ret = win.getWindowButtonPosition()
if (ret === null) {
// No custom position.
}
```
## Planned Breaking API Changes (24.0)
### API Changed: `nativeImage.createThumbnailFromPath(path, size)`

View File

@@ -1,128 +1,128 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Customize Menus</title>
</head>
<body>
<div>
<h1>Customize Menus</h1>
<h3>
The <code>Menu</code> and <code>MenuItem</code> modules can be used to
create custom native menus.
</h3>
<p>
There are two kinds of menus: the application (top) menu and context
(right-click) menu.
</p>
<p>
Open the
<a href="https://electronjs.org/docs/api/menu"
>full API documentation<span
>(opens in new window)</span
></a
>
in your browser.
</p>
</div>
<div>
<h2>Create an application menu</h2>
<div>
<div>
<p>
The <code>Menu</code> and <code>MenuItem</code> modules allow you to
customize your application menu. If you don't set any menu, Electron
will generate a minimal menu for your app by default.
</p>
<p>
If you click the 'View' option in the application menu and then the
'App Menu Demo', you'll see an information box displayed.
</p>
<div>
<h2>ProTip</h2>
<strong>Know operating system menu differences.</strong>
<p>
When designing an app for multiple operating systems it's
important to be mindful of the ways application menu conventions
differ on each operating system.
</p>
<p>
For instance, on Windows, accelerators are set with an
<code>&</code>. Naming conventions also vary, like between
"Settings" or "Preferences". Below are resources for learning
operating system specific standards.
</p>
<ul>
<li>
<a
href="https://developer.apple.com/macos/human-interface-guidelines/menus/menu-anatomy/"
>macOS<span
>(opens in new window)</span
></a
>
</li>
<li>
<a
href="https://learn.microsoft.com/en-us/previous-versions/windows/desktop/bb226797"
>Windows<span
>(opens in new window)</span
></a
>
</li>
<li>
<a
href="https://developer.gnome.org/hig/stable/menu-bars.html.en"
>Linux<span
>(opens in new window)</span
></a
>
</li>
</ul>
</div>
</div>
</div>
</div>
<div>
<h2>Create a context menu</h2>
<div>
<div>
<div>
<button id="context-menu">View Demo</button>
</div>
<p>
A context, or right-click, menu can be created with the
<code>Menu</code> and <code>MenuItem</code> modules as well. You can
right-click anywhere in this app or click the demo button to see an
example context menu.
</p>
<p>
In this demo we use the <code>ipcRenderer</code> module to show the
context menu when explicitly calling it from the renderer process.
</p>
<p>
See the full
<a
href="https://electronjs.org/docs/api/web-contents/#event-context-menu"
>context-menu event documentation</a
>
for all the available properties.
</p>
</div>
</div>
</div>
<script>
// You can also require other files to run in this process
require("./renderer.js");
</script>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Customize Menus</title>
</head>
<body>
<div>
<h1>Customize Menus</h1>
<h3>
The <code>Menu</code> and <code>MenuItem</code> modules can be used to
create custom native menus.
</h3>
<p>
There are two kinds of menus: the application (top) menu and context
(right-click) menu.
</p>
<p>
Open the
<a href="https://electronjs.org/docs/api/menu"
>full API documentation<span
>(opens in new window)</span
></a
>
in your browser.
</p>
</div>
<div>
<h2>Create an application menu</h2>
<div>
<div>
<p>
The <code>Menu</code> and <code>MenuItem</code> modules allow you to
customize your application menu. If you don't set any menu, Electron
will generate a minimal menu for your app by default.
</p>
<p>
If you click the 'View' option in the application menu and then the
'App Menu Demo', you'll see an information box displayed.
</p>
<div>
<h2>ProTip</h2>
<strong>Know operating system menu differences.</strong>
<p>
When designing an app for multiple operating systems it's
important to be mindful of the ways application menu conventions
differ on each operating system.
</p>
<p>
For instance, on Windows, accelerators are set with an
<code>&</code>. Naming conventions also vary, like between
"Settings" or "Preferences". Below are resources for learning
operating system specific standards.
</p>
<ul>
<li>
<a
href="https://developer.apple.com/macos/human-interface-guidelines/menus/menu-anatomy/"
>macOS<span
>(opens in new window)</span
></a
>
</li>
<li>
<a
href="https://learn.microsoft.com/en-us/previous-versions/windows/desktop/bb226797"
>Windows<span
>(opens in new window)</span
></a
>
</li>
<li>
<a
href="https://developer.gnome.org/hig/stable/menu-bars.html.en"
>Linux<span
>(opens in new window)</span
></a
>
</li>
</ul>
</div>
</div>
</div>
</div>
<div>
<h2>Create a context menu</h2>
<div>
<div>
<div>
<button id="context-menu">View Demo</button>
</div>
<p>
A context, or right-click, menu can be created with the
<code>Menu</code> and <code>MenuItem</code> modules as well. You can
right-click anywhere in this app or click the demo button to see an
example context menu.
</p>
<p>
In this demo we use the <code>ipcRenderer</code> module to show the
context menu when explicitly calling it from the renderer process.
</p>
<p>
See the full
<a
href="https://electronjs.org/docs/api/web-contents/#event-context-menu"
>context-menu event documentation</a
>
for all the available properties.
</p>
</div>
</div>
</div>
<script>
// You can also require other files to run in this process
require("./renderer.js");
</script>
</body>
</html>

View File

@@ -1,73 +1,73 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Keyboard Shortcuts</title>
</head>
<body>
<div>
<h1>Keyboard Shortcuts</h1>
<h3>The <code>globalShortcut</code> and <code>Menu</code> modules can be used to define keyboard shortcuts.</h3>
<p>
In Electron, keyboard shortcuts are called accelerators.
They can be assigned to actions in your application's Menu,
or they can be assigned globally so they'll be triggered even when
your app doesn't have keyboard focus.
</p>
<p>
Open the full documentation for the
<a href="https://electronjs.org/docs/api/menu">Menu</a>,
<a href="https://electronjs.org/docs/api/accelerator">Accelerator</a>,
and
<a href="https://electronjs.org/docs/api/global-shortcut">globalShortcut</a>
APIs in your browser.
</p>
</div>
<div>
<div>
<div>
<p>
To try this demo, press <kbd>CommandOrControl+Alt+K</kbd> on your
keyboard.
</p>
<p>
Global shortcuts are detected even when the app doesn't have
keyboard focus, and they must be registered after the app's
`ready` event is emitted.
</p>
<div>
<h2>ProTip</h2>
<strong>Avoid overriding system-wide keyboard shortcuts.</strong>
<p>
When registering global shortcuts, it's important to be aware of
existing defaults in the target operating system, so as not to
override any existing behaviors. For an overview of each
operating system's keyboard shortcuts, view these documents:
</p>
<ul>
<li><a
href="https://developer.apple.com/library/mac/documentation/UserExperience/Conceptual/OSXHIGuidelines/Keyboard.html">macOS</a>
</li>
<li><a
href="http://windows.microsoft.com/en-us/windows-10/keyboard-shortcuts">Windows</a></li>
<li><a
href="https://developer.gnome.org/hig/stable/keyboard-input.html.en">Linux</a></li>
</ul>
</div>
</div>
</div>
</div>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Keyboard Shortcuts</title>
</head>
<body>
<div>
<h1>Keyboard Shortcuts</h1>
<h3>The <code>globalShortcut</code> and <code>Menu</code> modules can be used to define keyboard shortcuts.</h3>
<p>
In Electron, keyboard shortcuts are called accelerators.
They can be assigned to actions in your application's Menu,
or they can be assigned globally so they'll be triggered even when
your app doesn't have keyboard focus.
</p>
<p>
Open the full documentation for the
<a href="https://electronjs.org/docs/api/menu">Menu</a>,
<a href="https://electronjs.org/docs/api/accelerator">Accelerator</a>,
and
<a href="https://electronjs.org/docs/api/global-shortcut">globalShortcut</a>
APIs in your browser.
</p>
</div>
<div>
<div>
<div>
<p>
To try this demo, press <kbd>CommandOrControl+Alt+K</kbd> on your
keyboard.
</p>
<p>
Global shortcuts are detected even when the app doesn't have
keyboard focus, and they must be registered after the app's
`ready` event is emitted.
</p>
<div>
<h2>ProTip</h2>
<strong>Avoid overriding system-wide keyboard shortcuts.</strong>
<p>
When registering global shortcuts, it's important to be aware of
existing defaults in the target operating system, so as not to
override any existing behaviors. For an overview of each
operating system's keyboard shortcuts, view these documents:
</p>
<ul>
<li><a
href="https://developer.apple.com/library/mac/documentation/UserExperience/Conceptual/OSXHIGuidelines/Keyboard.html">macOS</a>
</li>
<li><a
href="http://windows.microsoft.com/en-us/windows-10/keyboard-shortcuts">Windows</a></li>
<li><a
href="https://developer.gnome.org/hig/stable/keyboard-input.html.en">Linux</a></li>
</ul>
</div>
</div>
</div>
</div>
</body>
</html>

View File

@@ -1,81 +1,81 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Error Dialog</title>
</head>
<body>
<div>
<h1>Use system dialogs</h1>
<h3>
The <code>dialog</code> module in Electron allows you to use native
system dialogs for opening files or directories, saving a file or
displaying informational messages.
</h3>
<p>
This is a main process module because this process is more efficient
with native utilities and it allows the call to happen without
interrupting the visible elements in your page's renderer process.
</p>
<p>
Open the
<a href="https://electronjs.org/docs/api/dialog/">
full API documentation (opens in new window)
</a>
in your browser.
</p>
</div>
<div>
<div>
<h2>Error Dialog</h2>
<div>
<div>
<button id="error-dialog">View Demo</button>
</div>
<p>
In this demo, the <code>ipc</code> module is used to send a message
from the renderer process instructing the main process to launch the
error dialog.
</p>
<p>
You can use an error dialog before the app's
<code>ready</code> event, which is useful for showing errors upon
startup.
</p>
<h5>Renderer Process</h5>
<pre>
<code>
const {ipcRenderer} = require('electron')
const errorBtn = document.getElementById('error-dialog')
errorBtn.addEventListener('click', (event) => {
ipcRenderer.send('open-error-dialog')
})
</code></pre>
<h5>Main Process</h5>
<pre>
<code>
const {ipcMain, dialog} = require('electron')
ipcMain.on('open-error-dialog', (event) => {
dialog.showErrorBox('An Error Message', 'Demonstrating an error message.')
})
</code>
</pre>
</div>
</div>
</div>
<script>
// You can also require other files to run in this process
require("./renderer.js");
</script>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Error Dialog</title>
</head>
<body>
<div>
<h1>Use system dialogs</h1>
<h3>
The <code>dialog</code> module in Electron allows you to use native
system dialogs for opening files or directories, saving a file or
displaying informational messages.
</h3>
<p>
This is a main process module because this process is more efficient
with native utilities and it allows the call to happen without
interrupting the visible elements in your page's renderer process.
</p>
<p>
Open the
<a href="https://electronjs.org/docs/api/dialog/">
full API documentation (opens in new window)
</a>
in your browser.
</p>
</div>
<div>
<div>
<h2>Error Dialog</h2>
<div>
<div>
<button id="error-dialog">View Demo</button>
</div>
<p>
In this demo, the <code>ipc</code> module is used to send a message
from the renderer process instructing the main process to launch the
error dialog.
</p>
<p>
You can use an error dialog before the app's
<code>ready</code> event, which is useful for showing errors upon
startup.
</p>
<h5>Renderer Process</h5>
<pre>
<code>
const {ipcRenderer} = require('electron')
const errorBtn = document.getElementById('error-dialog')
errorBtn.addEventListener('click', (event) => {
ipcRenderer.send('open-error-dialog')
})
</code></pre>
<h5>Main Process</h5>
<pre>
<code>
const {ipcMain, dialog} = require('electron')
ipcMain.on('open-error-dialog', (event) => {
dialog.showErrorBox('An Error Message', 'Demonstrating an error message.')
})
</code>
</pre>
</div>
</div>
</div>
<script>
// You can also require other files to run in this process
require("./renderer.js");
</script>
</body>
</html>

View File

@@ -1,104 +1,104 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Information Dialog</title>
</head>
<body>
<div class="section-wrapper">
<h1>Use system dialogs</h1>
<h3>
The <code>dialog</code> module in Electron allows you to use native
system dialogs for opening files or directories, saving a file or
displaying informational messages.
</h3>
<p>
This is a main process module because this process is more efficient
with native utilities and it allows the call to happen without
interrupting the visible elements in your page's renderer process.
</p>
<p>
Open the
<a href="https://electronjs.org/docs/api/dialog/">
full API documentation (opens in new window)
</a>
in your browser.
</p>
</div>
<div>
<div>
<h2>Information Dialog</h2>
<div>
<div>
<button id="information-dialog">
View Demo
</button>
<span id="info-selection"></span>
</div>
<p>
In this demo, the <code>ipc</code> module is used to send a message
from the renderer process instructing the main process to launch the
information dialog. Options may be provided for responses which can
then be relayed back to the renderer process.
</p>
<p>
Note: The <code>title</code> property is not displayed in macOS.
</p>
<p>
An information dialog can contain an icon, your choice of buttons,
title and message.
</p>
<h5>Renderer Process</h5>
<pre>
<code>
const {ipcRenderer} = require('electron')
const informationBtn = document.getElementById('information-dialog')
informationBtn.addEventListener('click', (event) => {
ipcRenderer.send('open-information-dialog')
})
ipcRenderer.on('information-dialog-selection', (event, index) => {
let message = 'You selected '
if (index === 0) message += 'yes.'
else message += 'no.'
document.getElementById('info-selection').innerHTML = message
})
</code>
</pre>
<h5>Main Process</h5>
<pre>
<code>
const {ipcMain, dialog} = require('electron')
ipcMain.on('open-information-dialog', (event) => {
const options = {
type: 'info',
title: 'Information',
message: "This is an information dialog. Isn't it nice?",
buttons: ['Yes', 'No']
}
dialog.showMessageBox(options, (index) => {
event.sender.send('information-dialog-selection', index)
})
})
</code>
</pre>
</div>
</div>
</div>
<script>
// You can also require other files to run in this process
require("./renderer.js");
</script>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Information Dialog</title>
</head>
<body>
<div class="section-wrapper">
<h1>Use system dialogs</h1>
<h3>
The <code>dialog</code> module in Electron allows you to use native
system dialogs for opening files or directories, saving a file or
displaying informational messages.
</h3>
<p>
This is a main process module because this process is more efficient
with native utilities and it allows the call to happen without
interrupting the visible elements in your page's renderer process.
</p>
<p>
Open the
<a href="https://electronjs.org/docs/api/dialog/">
full API documentation (opens in new window)
</a>
in your browser.
</p>
</div>
<div>
<div>
<h2>Information Dialog</h2>
<div>
<div>
<button id="information-dialog">
View Demo
</button>
<span id="info-selection"></span>
</div>
<p>
In this demo, the <code>ipc</code> module is used to send a message
from the renderer process instructing the main process to launch the
information dialog. Options may be provided for responses which can
then be relayed back to the renderer process.
</p>
<p>
Note: The <code>title</code> property is not displayed in macOS.
</p>
<p>
An information dialog can contain an icon, your choice of buttons,
title and message.
</p>
<h5>Renderer Process</h5>
<pre>
<code>
const {ipcRenderer} = require('electron')
const informationBtn = document.getElementById('information-dialog')
informationBtn.addEventListener('click', (event) => {
ipcRenderer.send('open-information-dialog')
})
ipcRenderer.on('information-dialog-selection', (event, index) => {
let message = 'You selected '
if (index === 0) message += 'yes.'
else message += 'no.'
document.getElementById('info-selection').innerHTML = message
})
</code>
</pre>
<h5>Main Process</h5>
<pre>
<code>
const {ipcMain, dialog} = require('electron')
ipcMain.on('open-information-dialog', (event) => {
const options = {
type: 'info',
title: 'Information',
message: "This is an information dialog. Isn't it nice?",
buttons: ['Yes', 'No']
}
dialog.showMessageBox(options, (index) => {
event.sender.send('information-dialog-selection', index)
})
})
</code>
</pre>
</div>
</div>
</div>
<script>
// You can also require other files to run in this process
require("./renderer.js");
</script>
</body>
</html>

View File

@@ -1,108 +1,108 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Open File or Directory</title>
</head>
<body>
<div class="section-wrapper">
<h1>Use system dialogs</h1>
<h3>
The <code>dialog</code> module in Electron allows you to use native
system dialogs for opening files or directories, saving a file or
displaying informational messages.
</h3>
<p>
This is a main process module because this process is more efficient
with native utilities and it allows the call to happen without
interrupting the visible elements in your page's renderer process.
</p>
<p>
Open the
<a href="https://electronjs.org/docs/api/dialog/">
full API documentation (opens in new window)
</a>
in your browser.
</p>
</div>
<div>
<div>
<h2>Open a File or Directory</h2>
<div>
<div>
<button id="select-directory">View Demo</button>
<span id="selected-file"></span>
</div>
<p>
In this demo, the <code>ipc</code> module is used to send a message
from the renderer process instructing the main process to launch the
open file (or directory) dialog. If a file is selected, the main
process can send that information back to the renderer process.
</p>
<h5>Renderer Process</h5>
<pre>
<code>
const {ipcRenderer} = require('electron')
const selectDirBtn = document.getElementById('select-directory')
selectDirBtn.addEventListener('click', (event) => {
ipcRenderer.send('open-file-dialog')
})
ipcRenderer.on('selected-directory', (event, path) => {
document.getElementById('selected-file').innerHTML = `You selected: ${path}`
})
</code>
</pre>
<h5>Main Process</h5>
<pre>
<code>
const {ipcMain, dialog} = require('electron')
ipcMain.on('open-file-dialog', (event) => {
dialog.showOpenDialog({
properties: ['openFile', 'openDirectory']
}, (files) => {
if (files) {
event.sender.send('selected-directory', files)
}
})
})
</code>
</pre>
<div>
<h2>ProTip</h2>
<strong>The sheet-style dialog on macOS.</strong>
<p>
On macOS you can choose between a "sheet" dialog or a default
dialog. The sheet version descends from the top of the window. To
use sheet version, pass the <code>window</code> as the first
argument in the dialog method.
</p>
<pre><code class="language-js">const ipc = require('electron').ipcMain
const dialog = require('electron').dialog
const BrowserWindow = require('electron').BrowserWindow
ipc.on('open-file-dialog-sheet', function (event) {
const window = BrowserWindow.fromWebContents(event.sender)
const files = dialog.showOpenDialog(window, { properties: [ 'openFile' ]})
})</code></pre>
</div>
</div>
</div>
</div>
<script>
// You can also require other files to run in this process
require("./renderer.js");
</script>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Open File or Directory</title>
</head>
<body>
<div class="section-wrapper">
<h1>Use system dialogs</h1>
<h3>
The <code>dialog</code> module in Electron allows you to use native
system dialogs for opening files or directories, saving a file or
displaying informational messages.
</h3>
<p>
This is a main process module because this process is more efficient
with native utilities and it allows the call to happen without
interrupting the visible elements in your page's renderer process.
</p>
<p>
Open the
<a href="https://electronjs.org/docs/api/dialog/">
full API documentation (opens in new window)
</a>
in your browser.
</p>
</div>
<div>
<div>
<h2>Open a File or Directory</h2>
<div>
<div>
<button id="select-directory">View Demo</button>
<span id="selected-file"></span>
</div>
<p>
In this demo, the <code>ipc</code> module is used to send a message
from the renderer process instructing the main process to launch the
open file (or directory) dialog. If a file is selected, the main
process can send that information back to the renderer process.
</p>
<h5>Renderer Process</h5>
<pre>
<code>
const {ipcRenderer} = require('electron')
const selectDirBtn = document.getElementById('select-directory')
selectDirBtn.addEventListener('click', (event) => {
ipcRenderer.send('open-file-dialog')
})
ipcRenderer.on('selected-directory', (event, path) => {
document.getElementById('selected-file').innerHTML = `You selected: ${path}`
})
</code>
</pre>
<h5>Main Process</h5>
<pre>
<code>
const {ipcMain, dialog} = require('electron')
ipcMain.on('open-file-dialog', (event) => {
dialog.showOpenDialog({
properties: ['openFile', 'openDirectory']
}, (files) => {
if (files) {
event.sender.send('selected-directory', files)
}
})
})
</code>
</pre>
<div>
<h2>ProTip</h2>
<strong>The sheet-style dialog on macOS.</strong>
<p>
On macOS you can choose between a "sheet" dialog or a default
dialog. The sheet version descends from the top of the window. To
use sheet version, pass the <code>window</code> as the first
argument in the dialog method.
</p>
<pre><code class="language-js">const ipc = require('electron').ipcMain
const dialog = require('electron').dialog
const BrowserWindow = require('electron').BrowserWindow
ipc.on('open-file-dialog-sheet', function (event) {
const window = BrowserWindow.fromWebContents(event.sender)
const files = dialog.showOpenDialog(window, { properties: [ 'openFile' ]})
})</code></pre>
</div>
</div>
</div>
</div>
<script>
// You can also require other files to run in this process
require("./renderer.js");
</script>
</body>
</html>

View File

@@ -1,91 +1,91 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Save Dialog</title>
</head>
<body>
<div>
<h1>Use system dialogs</h1>
<h3>
The <code>dialog</code> module in Electron allows you to use native
system dialogs for opening files or directories, saving a file or
displaying informational messages.
</h3>
<p>
This is a main process module because this process is more efficient
with native utilities and it allows the call to happen without
interrupting the visible elements in your page's renderer process.
</p>
<p>
Open the
<a href="https://electronjs.org/docs/api/dialog/">
full API documentation (opens in new window)
</a>
in your browser.
</p>
</div>
<div>
<div>
<h2>Save Dialog</h2>
<div>
<div>
<button button id="save-dialog">View Demo</button>
<span id="file-saved"></span>
</div>
<p>
In this demo, the <code>ipc</code> module is used to send a message
from the renderer process instructing the main process to launch the
save dialog. It returns the path selected by the user which can be
relayed back to the renderer process.
</p>
<h5>Renderer Process</h5>
<pre>
<code>
const {ipcRenderer} = require('electron')
const saveBtn = document.getElementById('save-dialog')
saveBtn.addEventListener('click', (event) => {
ipcRenderer.send('save-dialog')
})
ipcRenderer.on('saved-file', (event, path) => {
if (!path) path = 'No path'
document.getElementById('file-saved').innerHTML = `Path selected: ${path}`
})
</code>
</pre>
<h5>Main Process</h5>
<pre>
<code>
const {ipcMain, dialog} = require('electron')
ipcMain.on('save-dialog', (event) => {
const options = {
title: 'Save an Image',
filters: [
{ name: 'Images', extensions: ['jpg', 'png', 'gif'] }
]
}
dialog.showSaveDialog(options, (filename) => {
event.sender.send('saved-file', filename)
})
})
</code>
</pre>
</div>
</div>
</div>
<script>
// You can also require other files to run in this process
require("./renderer.js");
</script>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Save Dialog</title>
</head>
<body>
<div>
<h1>Use system dialogs</h1>
<h3>
The <code>dialog</code> module in Electron allows you to use native
system dialogs for opening files or directories, saving a file or
displaying informational messages.
</h3>
<p>
This is a main process module because this process is more efficient
with native utilities and it allows the call to happen without
interrupting the visible elements in your page's renderer process.
</p>
<p>
Open the
<a href="https://electronjs.org/docs/api/dialog/">
full API documentation (opens in new window)
</a>
in your browser.
</p>
</div>
<div>
<div>
<h2>Save Dialog</h2>
<div>
<div>
<button button id="save-dialog">View Demo</button>
<span id="file-saved"></span>
</div>
<p>
In this demo, the <code>ipc</code> module is used to send a message
from the renderer process instructing the main process to launch the
save dialog. It returns the path selected by the user which can be
relayed back to the renderer process.
</p>
<h5>Renderer Process</h5>
<pre>
<code>
const {ipcRenderer} = require('electron')
const saveBtn = document.getElementById('save-dialog')
saveBtn.addEventListener('click', (event) => {
ipcRenderer.send('save-dialog')
})
ipcRenderer.on('saved-file', (event, path) => {
if (!path) path = 'No path'
document.getElementById('file-saved').innerHTML = `Path selected: ${path}`
})
</code>
</pre>
<h5>Main Process</h5>
<pre>
<code>
const {ipcMain, dialog} = require('electron')
ipcMain.on('save-dialog', (event) => {
const options = {
title: 'Save an Image',
filters: [
{ name: 'Images', extensions: ['jpg', 'png', 'gif'] }
]
}
dialog.showSaveDialog(options, (filename) => {
event.sender.send('saved-file', filename)
})
})
</code>
</pre>
</div>
</div>
</div>
<script>
// You can also require other files to run in this process
require("./renderer.js");
</script>
</body>
</html>

View File

@@ -1,76 +1,76 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Drag and drop files</title>
</head>
<body>
<div>
<h1>Drag and drop files</h1>
<div>Supports: Win, macOS, Linux <span>|</span> Process: Both</div>
<h3>
Electron supports dragging files and content out from web content into
the operating system's world.
</h3>
<p>
Open the
<a href="https://electronjs.org/docs/tutorial/native-file-drag-drop">
full API documentation (opens in new window)
</a>
in your browser.
</p>
</div>
<div>
<div>
<h2>Dragging files</h2>
<div>
<div>
<a href="#" id="drag-file-link">Drag Demo</a>
</div>
<p>
Click and drag the link above to copy the renderer process
javascript file on to your machine.
</p>
<p>
In this demo, the <code>webContents.startDrag()</code> API is called
in response to the <code>ondragstart</code> event.
</p>
<h5>Renderer Process</h5>
<pre><code>
const {ipcRenderer} = require('electron')
const dragFileLink = document.getElementById('drag-file-link')
dragFileLink.addEventListener('dragstart', (event) => {
event.preventDefault()
ipcRenderer.send('ondragstart', __filename)
})
</code></pre>
<h5>Main Process</h5>
<pre>
<code>
const {ipcMain} = require('electron')
const path = require('path')
ipcMain.on('ondragstart', (event, filepath) => {
const iconName = 'codeIcon.png'
event.sender.startDrag({
file: filepath,
icon: path.join(__dirname, iconName)
})
})
</code></pre>
</div>
</div>
</div>
<script>
// You can also require other files to run in this process
require("./renderer.js");
</script>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Drag and drop files</title>
</head>
<body>
<div>
<h1>Drag and drop files</h1>
<div>Supports: Win, macOS, Linux <span>|</span> Process: Both</div>
<h3>
Electron supports dragging files and content out from web content into
the operating system's world.
</h3>
<p>
Open the
<a href="https://electronjs.org/docs/tutorial/native-file-drag-drop">
full API documentation (opens in new window)
</a>
in your browser.
</p>
</div>
<div>
<div>
<h2>Dragging files</h2>
<div>
<div>
<a href="#" id="drag-file-link">Drag Demo</a>
</div>
<p>
Click and drag the link above to copy the renderer process
javascript file on to your machine.
</p>
<p>
In this demo, the <code>webContents.startDrag()</code> API is called
in response to the <code>ondragstart</code> event.
</p>
<h5>Renderer Process</h5>
<pre><code>
const {ipcRenderer} = require('electron')
const dragFileLink = document.getElementById('drag-file-link')
dragFileLink.addEventListener('dragstart', (event) => {
event.preventDefault()
ipcRenderer.send('ondragstart', __filename)
})
</code></pre>
<h5>Main Process</h5>
<pre>
<code>
const {ipcMain} = require('electron')
const path = require('path')
ipcMain.on('ondragstart', (event, filepath) => {
const iconName = 'codeIcon.png'
event.sender.startDrag({
file: filepath,
icon: path.join(__dirname, iconName)
})
})
</code></pre>
</div>
</div>
</div>
<script>
// You can also require other files to run in this process
require("./renderer.js");
</script>
</body>
</html>

View File

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

View File

@@ -1,67 +1,67 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Desktop notifications</title>
</head>
<body>
<div>
<h1>Desktop notifications</h1>
<h3>
The <code>notification</code> module in Electron allows you to add basic
desktop notifications.
</h3>
<p>
Electron conveniently allows developers to send notifications with the
<a href="https://notifications.spec.whatwg.org/">HTML5 Notification API</a>,
using the currently running operating systems native notification
APIs to display it.
</p>
<p>
<b>Note:</b> Since this is an HTML5 API it is only available in the
renderer process.
</p>
<p>
Open the
<a href="https://electronjs.org/docs/all/#notifications-windows-linux-macos">
full API documentation<span>(opens in new window)</span>
</a>
in your browser.
</p>
</div>
<div>
<div>
<h2>Basic notification</h2>
<div>
<div>
<button id="basic-noti">View demo</button>
</div>
<p>This demo demonstrates a basic notification. Text only.</p>
</div>
</div>
</div>
<div>
<div>
<h2>Notification with image</h2>
<div>
<div>
<button id="advanced-noti">View demo</button>
</div>
<p>
This demo demonstrates a basic notification. Both text and a image
</p>
</div>
</div>
</div>
<script>
// You can also require other files to run in this process
require("./renderer.js");
</script>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Desktop notifications</title>
</head>
<body>
<div>
<h1>Desktop notifications</h1>
<h3>
The <code>notification</code> module in Electron allows you to add basic
desktop notifications.
</h3>
<p>
Electron conveniently allows developers to send notifications with the
<a href="https://notifications.spec.whatwg.org/">HTML5 Notification API</a>,
using the currently running operating systems native notification
APIs to display it.
</p>
<p>
<b>Note:</b> Since this is an HTML5 API it is only available in the
renderer process.
</p>
<p>
Open the
<a href="https://electronjs.org/docs/all/#notifications-windows-linux-macos">
full API documentation<span>(opens in new window)</span>
</a>
in your browser.
</p>
</div>
<div>
<div>
<h2>Basic notification</h2>
<div>
<div>
<button id="basic-noti">View demo</button>
</div>
<p>This demo demonstrates a basic notification. Text only.</p>
</div>
</div>
</div>
<div>
<div>
<h2>Notification with image</h2>
<div>
<div>
<button id="advanced-noti">View demo</button>
</div>
<p>
This demo demonstrates a basic notification. Both text and a image
</p>
</div>
</div>
</div>
<script>
// You can also require other files to run in this process
require("./renderer.js");
</script>
</body>
</html>

View File

@@ -1,47 +1,47 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Tray</title>
</head>
<body>
<div>
<h1>Tray</h1>
<h3>
The <code>tray</code> module allows you to create an icon in the
operating system's notification area.
</h3>
<p>This icon can also have a context menu attached.</p>
<p>
Open the
<a href="https://electronjs.org/docs/api/tray">
full API documentation
</a>
in your browser.
</p>
</div>
<div>
<div>
<h2>ProTip</h2>
<strong>Tray support in Linux.</strong>
<p>
On Linux distributions that only have app indicator support, users
will need to install <code>libappindicator1</code> to make the
tray icon work. See the
<a href="https://electronjs.org/docs/api/tray">
full API documentation
</a>
for more details about using Tray on Linux.
</p>
</div>
</div>
</div>
</div>
<script>
// You can also require other files to run in this process
require("./renderer.js");
</script>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Tray</title>
</head>
<body>
<div>
<h1>Tray</h1>
<h3>
The <code>tray</code> module allows you to create an icon in the
operating system's notification area.
</h3>
<p>This icon can also have a context menu attached.</p>
<p>
Open the
<a href="https://electronjs.org/docs/api/tray">
full API documentation
</a>
in your browser.
</p>
</div>
<div>
<div>
<h2>ProTip</h2>
<strong>Tray support in Linux.</strong>
<p>
On Linux distributions that only have app indicator support, users
will need to install <code>libappindicator1</code> to make the
tray icon work. See the
<a href="https://electronjs.org/docs/api/tray">
full API documentation
</a>
for more details about using Tray on Linux.
</p>
</div>
</div>
</div>
</div>
<script>
// You can also require other files to run in this process
require("./renderer.js");
</script>
</body>
</html>

View File

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

View File

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

View File

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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

View File

@@ -41,9 +41,7 @@ Valid `algorithm` values are currently `SHA256` only. The `hash` is a hash of t
ASAR integrity checking is currently disabled by default and can be enabled by toggling a fuse. See [Electron Fuses](fuses.md) for more information on what Electron Fuses are and how they work. When enabling this fuse you typically also want to enable the `onlyLoadAppFromAsar` fuse otherwise the validity checking can be bypassed via the Electron app code search path.
```js @ts-nocheck
const { flipFuses, FuseVersion, FuseV1Options } = require('@electron/fuses')
flipFuses(
require('@electron/fuses').flipFuses(
// E.g. /a/b/Foo.app
pathToPackagedApp,
{

View File

@@ -9,11 +9,10 @@ check out our [Electron Versioning](./electron-versioning.md) doc.
| Electron | Alpha | Beta | Stable | EOL | Chrome | Node | Supported |
| ------- | ----- | ------- | ------ | ------ | ---- | ---- | ---- |
| 26.0.0 | 2023-Jun-01 | 2023-Jun-27 | 2023-Aug-15 | TBD | M116 | TBD | ✅ |
| 25.0.0 | 2023-Apr-10 | 2023-May-02 | 2023-May-30 | 2024-Jan-02 | M114 | v18.15 | ✅ |
| 24.0.0 | 2022-Feb-09 | 2023-Mar-07 | 2023-Apr-04 | 2023-Oct-10 | M112 | v18.14 | ✅ |
| 23.0.0 | 2022-Dec-01 | 2023-Jan-10 | 2023-Feb-07 | 2023-Aug-15 | M110 | v18.12 | ✅ |
| 22.0.0 | 2022-Sep-29 | 2022-Oct-25 | 2022-Nov-29 | 2023-Oct-10 | M108 | v16.17 | ✅ |
| 25.0.0 | 2023-Apr-10 | 2023-May-02 | 2023-May-30 | 2023-Dec-05 | M114 | TBD | ✅ |
| 24.0.0 | 2022-Feb-09 | 2023-Mar-07 | 2023-Apr-04 | 2023-Oct-03 | M112 | v18.14 | ✅ |
| 23.0.0 | 2022-Dec-01 | 2023-Jan-10 | 2023-Feb-07 | 2023-Aug-08 | M110 | v18.12 | ✅ |
| 22.0.0 | 2022-Sep-29 | 2022-Oct-25 | 2022-Nov-29 | 2023-May-30 | M108 | v16.17 | ✅ |
| 21.0.0 | 2022-Aug-04 | 2022-Aug-30 | 2022-Sep-27 | 2023-Apr-04 | M106 | v16.16 | 🚫 |
| 20.0.0 | 2022-May-26 | 2022-Jun-21 | 2022-Aug-02 | 2023-Feb-07 | M104 | v16.15 | 🚫 |
| 19.0.0 | 2022-Mar-31 | 2022-Apr-26 | 2022-May-24 | 2022-Nov-29 | M102 | v16.14 | 🚫 |
@@ -57,12 +56,12 @@ Chromium has the own public release schedule [here](https://chromiumdash.appspot
:::info
The Electron team will temporarily support Electron 22 until October 10, 2023.
This extended support is intended to help Electron developers who still need
support for Windows 7/8/8.1, which ended support in Electron 23. The October
support date follows the extended support dates from both Chromium and Microsoft.
On October 11, the Electron team will drop support back to the latest three
stable major versions.
Beginning in September 2021 (Electron 15), the Electron team
will temporarily support the latest **four** stable major versions. This
extended support is intended to help Electron developers transition to
the [new 8-week release cadence](https://electronjs.org/blog/8-week-cadence),
and will continue until the release of Electron 19. At that time,
the Electron team will drop support back to the latest three stable major versions.
:::

View File

@@ -68,9 +68,7 @@ The loadBrowserProcessSpecificV8Snapshot fuse changes which V8 snapshot file is
We've made a handy module, [`@electron/fuses`](https://npmjs.com/package/@electron/fuses), to make flipping these fuses easy. Check out the README of that module for more details on usage and potential error cases.
```js @ts-nocheck
const { flipFuses, FuseVersion, FuseV1Options } = require('@electron/fuses')
flipFuses(
require('@electron/fuses').flipFuses(
// Path to electron
require('electron'),
// Fuses to flip
@@ -84,7 +82,7 @@ flipFuses(
You can validate the fuses have been flipped or check the fuse status of an arbitrary Electron app using the fuses CLI.
```bash
npx @electron/fuses read --app /Applications/Foo.app
npx @electron/fuses read --app /Applications/Foo.app
```
### The hard way

View File

@@ -63,9 +63,9 @@ const createWindow = () => {
In this next step, we will create our `BrowserWindow` and tell our application how to handle an event in which an external protocol is clicked.
This code will be different in Windows and Linux compared to MacOS. This is due to both platforms emitting the `second-instance` event rather than the `open-url` event and Windows requiring additional code in order to open the contents of the protocol link within the same Electron instance. Read more about this [here](../api/app.md#apprequestsingleinstancelockadditionaldata).
This code will be different in Windows compared to MacOS and Linux. This is due to Windows requiring additional code in order to open the contents of the protocol link within the same Electron instance. Read more about this [here](../api/app.md#apprequestsingleinstancelockadditionaldata).
#### Windows and Linux code:
#### Windows code:
```javascript @ts-type={mainWindow:Electron.BrowserWindow} @ts-type={createWindow:()=>void}
const gotTheLock = app.requestSingleInstanceLock()
@@ -80,7 +80,8 @@ if (!gotTheLock) {
mainWindow.focus()
}
// the commandLine is array of strings in which last element is deep link url
dialog.showErrorBox('Welcome Back', `You arrived from: ${commandLine.pop()}`)
// the url str ends with /
dialog.showErrorBox('Welcome Back', `You arrived from: ${commandLine.pop().slice(0, -1)}`)
})
// Create mainWindow, load the rest of the app, etc...
@@ -90,7 +91,7 @@ if (!gotTheLock) {
}
```
#### MacOS code:
#### MacOS and Linux code:
```javascript @ts-type={createWindow:()=>void}
// This method will be called when Electron has finished

View File

@@ -150,7 +150,7 @@ renderer.
```js title='renderer.js (Renderer Process)' @ts-nocheck
// elsewhere in your code to send a message to the other renderers message handler
window.electronMessagePort.postMessage('ping')
window.electronMessagePort.postmessage('ping')
```
### Worker process

View File

@@ -202,7 +202,7 @@ Then, set up your `handle` listener in the main process. We do this _before_
loading the HTML file so that the handler is guaranteed to be ready before
you send out the `invoke` call from the renderer.
```js {1,15} title="main.js"
```js {1,12} title="main.js"
const { app, BrowserWindow, ipcMain } = require('electron')
const path = require('path')
@@ -214,12 +214,10 @@ const createWindow = () => {
preload: path.join(__dirname, 'preload.js')
}
})
ipcMain.handle('ping', () => 'pong')
win.loadFile('index.html')
}
app.whenReady().then(() => {
ipcMain.handle('ping', () => 'pong')
createWindow()
})
app.whenReady().then(createWindow)
```
Once you have the sender and receiver set up, you can now send messages from the renderer

View File

@@ -115,7 +115,7 @@ const win = new BrowserWindow({
})
```
On either platform `titleBarOverlay` can also be an object. On both macOS and Windows, the height of the overlay can be specified with the `height` property. On Windows, the color of the overlay and its symbols can be specified using the `color` and `symbolColor` properties respectively. `rgba()`, `hsla()`, and `#RRGGBBAA` color formats are supported to apply transparency.
On either platform `titleBarOverlay` can also be an object. On both macOS and Windows, the height of the overlay can be specified with the `height` property. On Windows, the color of the overlay and its symbols can be specified using the `color` and `symbolColor` properties respectively.
If a color option is not specified, the color will default to its system color for the window control buttons. Similarly, if the height option is not specified it will default to the default height:
@@ -136,6 +136,10 @@ const win = new BrowserWindow({
> color and dimension values from a renderer using a set of readonly
> [JavaScript APIs][overlay-javascript-apis] and [CSS Environment Variables][overlay-css-env-vars].
### Limitations
* Transparent colors are currently not supported. Progress updates for this feature can be found in PR [#33567](https://github.com/electron/electron/issues/33567).
## Create transparent windows
By setting the `transparent` option to `true`, you can make a fully transparent window.

View File

@@ -78,6 +78,7 @@ auto_filenames = {
"docs/api/structures/custom-scheme.md",
"docs/api/structures/desktop-capturer-source.md",
"docs/api/structures/display.md",
"docs/api/structures/event.md",
"docs/api/structures/extension-info.md",
"docs/api/structures/extension.md",
"docs/api/structures/file-filter.md",
@@ -114,7 +115,6 @@ auto_filenames = {
"docs/api/structures/protocol-response.md",
"docs/api/structures/rectangle.md",
"docs/api/structures/referrer.md",
"docs/api/structures/render-process-gone-details.md",
"docs/api/structures/resolved-endpoint.md",
"docs/api/structures/resolved-host.md",
"docs/api/structures/scrubber-item.md",
@@ -210,8 +210,6 @@ auto_filenames = {
"lib/browser/api/message-channel.ts",
"lib/browser/api/module-list.ts",
"lib/browser/api/native-theme.ts",
"lib/browser/api/net-client-request.ts",
"lib/browser/api/net-fetch.ts",
"lib/browser/api/net-log.ts",
"lib/browser/api/net.ts",
"lib/browser/api/notification.ts",

View File

@@ -265,6 +265,7 @@ filenames = {
"shell/browser/api/electron_api_dialog.cc",
"shell/browser/api/electron_api_download_item.cc",
"shell/browser/api/electron_api_download_item.h",
"shell/browser/api/electron_api_event.cc",
"shell/browser/api/electron_api_event_emitter.cc",
"shell/browser/api/electron_api_event_emitter.h",
"shell/browser/api/electron_api_global_shortcut.cc",
@@ -317,6 +318,8 @@ filenames = {
"shell/browser/api/electron_api_web_request.cc",
"shell/browser/api/electron_api_web_request.h",
"shell/browser/api/electron_api_web_view_manager.cc",
"shell/browser/api/event.cc",
"shell/browser/api/event.h",
"shell/browser/api/frame_subscriber.cc",
"shell/browser/api/frame_subscriber.h",
"shell/browser/api/gpu_info_enumerator.cc",
@@ -377,6 +380,7 @@ filenames = {
"shell/browser/electron_web_contents_utility_handler_impl.h",
"shell/browser/electron_web_ui_controller_factory.cc",
"shell/browser/electron_web_ui_controller_factory.h",
"shell/browser/event_emitter_mixin.cc",
"shell/browser/event_emitter_mixin.h",
"shell/browser/extended_web_contents_observer.h",
"shell/browser/feature_list.cc",
@@ -582,7 +586,6 @@ filenames = {
"shell/common/gin_converters/native_window_converter.h",
"shell/common/gin_converters/net_converter.cc",
"shell/common/gin_converters/net_converter.h",
"shell/common/gin_converters/optional_converter.h",
"shell/common/gin_converters/serial_port_info_converter.h",
"shell/common/gin_converters/std_converter.h",
"shell/common/gin_converters/time_converter.cc",
@@ -603,13 +606,10 @@ filenames = {
"shell/common/gin_helper/dictionary.h",
"shell/common/gin_helper/error_thrower.cc",
"shell/common/gin_helper/error_thrower.h",
"shell/common/gin_helper/event.cc",
"shell/common/gin_helper/event.h",
"shell/common/gin_helper/event_emitter.cc",
"shell/common/gin_helper/event_emitter.h",
"shell/common/gin_helper/event_emitter_caller.cc",
"shell/common/gin_helper/event_emitter_caller.h",
"shell/common/gin_helper/event_emitter_template.cc",
"shell/common/gin_helper/event_emitter_template.h",
"shell/common/gin_helper/function_template.cc",
"shell/common/gin_helper/function_template.h",
"shell/common/gin_helper/function_template_extensions.h",

View File

@@ -226,15 +226,10 @@ libcxx_headers = [
"//buildtools/third_party/libc++/trunk/include/__bsd_locale_defaults.h",
"//buildtools/third_party/libc++/trunk/include/__bsd_locale_fallbacks.h",
"//buildtools/third_party/libc++/trunk/include/__charconv/chars_format.h",
"//buildtools/third_party/libc++/trunk/include/__charconv/from_chars_integral.h",
"//buildtools/third_party/libc++/trunk/include/__charconv/from_chars_result.h",
"//buildtools/third_party/libc++/trunk/include/__charconv/tables.h",
"//buildtools/third_party/libc++/trunk/include/__charconv/to_chars.h",
"//buildtools/third_party/libc++/trunk/include/__charconv/to_chars_base_10.h",
"//buildtools/third_party/libc++/trunk/include/__charconv/to_chars_floating_point.h",
"//buildtools/third_party/libc++/trunk/include/__charconv/to_chars_integral.h",
"//buildtools/third_party/libc++/trunk/include/__charconv/to_chars_result.h",
"//buildtools/third_party/libc++/trunk/include/__charconv/traits.h",
"//buildtools/third_party/libc++/trunk/include/__chrono/calendar.h",
"//buildtools/third_party/libc++/trunk/include/__chrono/concepts.h",
"//buildtools/third_party/libc++/trunk/include/__chrono/convert_to_timespec.h",
@@ -295,7 +290,6 @@ libcxx_headers = [
"//buildtools/third_party/libc++/trunk/include/__concepts/semiregular.h",
"//buildtools/third_party/libc++/trunk/include/__concepts/swappable.h",
"//buildtools/third_party/libc++/trunk/include/__concepts/totally_ordered.h",
"//buildtools/third_party/libc++/trunk/include/__condition_variable/condition_variable.h",
"//buildtools/third_party/libc++/trunk/include/__config",
"//buildtools/third_party/libc++/trunk/include/__config_site.in",
"//buildtools/third_party/libc++/trunk/include/__coroutine/coroutine_handle.h",
@@ -304,11 +298,7 @@ libcxx_headers = [
"//buildtools/third_party/libc++/trunk/include/__coroutine/trivial_awaitables.h",
"//buildtools/third_party/libc++/trunk/include/__debug",
"//buildtools/third_party/libc++/trunk/include/__debug_utils/randomize_range.h",
"//buildtools/third_party/libc++/trunk/include/__exception/exception.h",
"//buildtools/third_party/libc++/trunk/include/__exception/exception_ptr.h",
"//buildtools/third_party/libc++/trunk/include/__exception/nested_exception.h",
"//buildtools/third_party/libc++/trunk/include/__exception/operations.h",
"//buildtools/third_party/libc++/trunk/include/__exception/terminate.h",
"//buildtools/third_party/libc++/trunk/include/__errc",
"//buildtools/third_party/libc++/trunk/include/__expected/bad_expected_access.h",
"//buildtools/third_party/libc++/trunk/include/__expected/expected.h",
"//buildtools/third_party/libc++/trunk/include/__expected/unexpect.h",
@@ -476,10 +466,7 @@ libcxx_headers = [
"//buildtools/third_party/libc++/trunk/include/__memory_resource/pool_options.h",
"//buildtools/third_party/libc++/trunk/include/__memory_resource/synchronized_pool_resource.h",
"//buildtools/third_party/libc++/trunk/include/__memory_resource/unsynchronized_pool_resource.h",
"//buildtools/third_party/libc++/trunk/include/__mutex/lock_guard.h",
"//buildtools/third_party/libc++/trunk/include/__mutex/mutex.h",
"//buildtools/third_party/libc++/trunk/include/__mutex/tag_types.h",
"//buildtools/third_party/libc++/trunk/include/__mutex/unique_lock.h",
"//buildtools/third_party/libc++/trunk/include/__mutex_base",
"//buildtools/third_party/libc++/trunk/include/__node_handle",
"//buildtools/third_party/libc++/trunk/include/__numeric/accumulate.h",
"//buildtools/third_party/libc++/trunk/include/__numeric/adjacent_difference.h",
@@ -570,6 +557,7 @@ libcxx_headers = [
"//buildtools/third_party/libc++/trunk/include/__ranges/views.h",
"//buildtools/third_party/libc++/trunk/include/__ranges/zip_view.h",
"//buildtools/third_party/libc++/trunk/include/__split_buffer",
"//buildtools/third_party/libc++/trunk/include/__std_stream",
"//buildtools/third_party/libc++/trunk/include/__string/char_traits.h",
"//buildtools/third_party/libc++/trunk/include/__string/constexpr_c_functions.h",
"//buildtools/third_party/libc++/trunk/include/__string/extern_template_lists.h",
@@ -589,25 +577,20 @@ libcxx_headers = [
"//buildtools/third_party/libc++/trunk/include/__support/xlocale/__nop_locale_mgmt.h",
"//buildtools/third_party/libc++/trunk/include/__support/xlocale/__posix_l_fallback.h",
"//buildtools/third_party/libc++/trunk/include/__support/xlocale/__strtonum_fallback.h",
"//buildtools/third_party/libc++/trunk/include/__system_error/errc.h",
"//buildtools/third_party/libc++/trunk/include/__system_error/error_category.h",
"//buildtools/third_party/libc++/trunk/include/__system_error/error_code.h",
"//buildtools/third_party/libc++/trunk/include/__system_error/error_condition.h",
"//buildtools/third_party/libc++/trunk/include/__system_error/system_error.h",
"//buildtools/third_party/libc++/trunk/include/__thread/poll_with_backoff.h",
"//buildtools/third_party/libc++/trunk/include/__thread/timed_backoff_policy.h",
"//buildtools/third_party/libc++/trunk/include/__threading_support",
"//buildtools/third_party/libc++/trunk/include/__tree",
"//buildtools/third_party/libc++/trunk/include/__tuple/apply_cv.h",
"//buildtools/third_party/libc++/trunk/include/__tuple/make_tuple_types.h",
"//buildtools/third_party/libc++/trunk/include/__tuple/pair_like.h",
"//buildtools/third_party/libc++/trunk/include/__tuple/sfinae_helpers.h",
"//buildtools/third_party/libc++/trunk/include/__tuple/tuple_element.h",
"//buildtools/third_party/libc++/trunk/include/__tuple/tuple_indices.h",
"//buildtools/third_party/libc++/trunk/include/__tuple/tuple_like.h",
"//buildtools/third_party/libc++/trunk/include/__tuple/tuple_like_ext.h",
"//buildtools/third_party/libc++/trunk/include/__tuple/tuple_size.h",
"//buildtools/third_party/libc++/trunk/include/__tuple/tuple_types.h",
"//buildtools/third_party/libc++/trunk/include/__tuple_dir/apply_cv.h",
"//buildtools/third_party/libc++/trunk/include/__tuple_dir/make_tuple_types.h",
"//buildtools/third_party/libc++/trunk/include/__tuple_dir/pair_like.h",
"//buildtools/third_party/libc++/trunk/include/__tuple_dir/sfinae_helpers.h",
"//buildtools/third_party/libc++/trunk/include/__tuple_dir/tuple_element.h",
"//buildtools/third_party/libc++/trunk/include/__tuple_dir/tuple_indices.h",
"//buildtools/third_party/libc++/trunk/include/__tuple_dir/tuple_like.h",
"//buildtools/third_party/libc++/trunk/include/__tuple_dir/tuple_like_ext.h",
"//buildtools/third_party/libc++/trunk/include/__tuple_dir/tuple_size.h",
"//buildtools/third_party/libc++/trunk/include/__tuple_dir/tuple_types.h",
"//buildtools/third_party/libc++/trunk/include/__type_traits/add_const.h",
"//buildtools/third_party/libc++/trunk/include/__type_traits/add_cv.h",
"//buildtools/third_party/libc++/trunk/include/__type_traits/add_lvalue_reference.h",
@@ -811,8 +794,10 @@ libcxx_headers = [
"//buildtools/third_party/libc++/trunk/include/expected",
"//buildtools/third_party/libc++/trunk/include/experimental/__config",
"//buildtools/third_party/libc++/trunk/include/experimental/__memory",
"//buildtools/third_party/libc++/trunk/include/experimental/algorithm",
"//buildtools/third_party/libc++/trunk/include/experimental/deque",
"//buildtools/third_party/libc++/trunk/include/experimental/forward_list",
"//buildtools/third_party/libc++/trunk/include/experimental/functional",
"//buildtools/third_party/libc++/trunk/include/experimental/iterator",
"//buildtools/third_party/libc++/trunk/include/experimental/list",
"//buildtools/third_party/libc++/trunk/include/experimental/map",

View File

@@ -839,7 +839,7 @@ export const wrapFsWithAsar = (fs: Record<string, any>) => {
const originalModuleLoad = Module._load;
Module._load = (request: string, ...args: any[]) => {
const loadResult = originalModuleLoad(request, ...args);
if (request === 'child_process' || request === 'node:child_process') {
if (request === 'child_process') {
if (!asarReady.has(loadResult)) {
asarReady.add(loadResult);
// Just to make it obvious what we are dealing with here

View File

@@ -1,6 +1,5 @@
import { EventEmitter } from 'events';
import type { BaseWindow as TLWT } from 'electron/main';
import * as deprecate from '@electron/internal/common/deprecate';
const { BaseWindow } = process._linkedBinding('electron_browser_base_window') as { BaseWindow: typeof TLWT };
Object.setPrototypeOf(BaseWindow.prototype, EventEmitter.prototype);
@@ -16,25 +15,6 @@ BaseWindow.prototype._init = function () {
}
};
// Deprecation.
const setTrafficLightPositionDeprecated = deprecate.warnOnce('setTrafficLightPosition', 'setWindowButtonPosition');
// Converting to any as the methods are defined under BrowserWindow in our docs.
(BaseWindow as any).prototype.setTrafficLightPosition = function (pos: Electron.Point) {
setTrafficLightPositionDeprecated();
if (typeof pos === 'object' && pos.x === 0 && pos.y === 0) {
this.setWindowButtonPosition(null);
} else {
this.setWindowButtonPosition(pos);
}
};
const getTrafficLightPositionDeprecated = deprecate.warnOnce('getTrafficLightPosition', 'getWindowButtonPosition');
(BaseWindow as any).prototype.getTrafficLightPosition = function () {
getTrafficLightPositionDeprecated();
const pos = this.getWindowButtonPosition();
return pos === null ? { x: 0, y: 0 } : pos;
};
// Properties
Object.defineProperty(BaseWindow.prototype, 'autoHideMenuBar', {

View File

@@ -1,4 +1,4 @@
import { BaseWindow, WebContents, BrowserView, TouchBar } from 'electron/main';
import { BaseWindow, WebContents, Event, BrowserView, TouchBar } from 'electron/main';
import type { BrowserWindow as BWT } from 'electron/main';
import * as deprecate from '@electron/internal/common/deprecate';
const { BrowserWindow } = process._linkedBinding('electron_browser_window') as { BrowserWindow: typeof BWT };
@@ -30,10 +30,10 @@ BrowserWindow.prototype._init = function (this: BWT) {
};
// Redirect focus/blur event to app instance too.
this.on('blur', (event: Electron.Event) => {
this.on('blur', (event: Event) => {
app.emit('browser-window-blur', event, this);
});
this.on('focus', (event: Electron.Event) => {
this.on('focus', (event: Event) => {
app.emit('browser-window-focus', event, this);
});
@@ -76,7 +76,8 @@ BrowserWindow.prototype._init = function (this: BWT) {
});
// Notify the creation of the window.
app.emit('browser-window-created', { preventDefault () {} }, this);
const event = process._linkedBinding('electron_browser_event').createEmpty();
app.emit('browser-window-created', event, this);
Object.defineProperty(this, 'devToolsWebContents', {
enumerable: true,

View File

@@ -1,5 +1,5 @@
import * as roles from '@electron/internal/browser/api/menu-item-roles';
import { Menu, BrowserWindow, WebContents, KeyboardEvent } from 'electron/main';
import { Menu, Event, BrowserWindow, WebContents } from 'electron/main';
let nextCommandId = 0;
@@ -53,7 +53,7 @@ const MenuItem = function (this: any, options: any) {
});
const click = options.click;
this.click = (event: KeyboardEvent, focusedWindow: BrowserWindow, focusedWebContents: WebContents) => {
this.click = (event: Event, focusedWindow: BrowserWindow, focusedWebContents: WebContents) => {
// Manually flip the checked flags when clicked.
if (!roles.shouldOverrideCheckStatus(this.role) &&
(this.type === 'checkbox' || this.type === 'radio')) {

View File

@@ -1,537 +0,0 @@
import * as url from 'url';
import { Readable, Writable } from 'stream';
import { app } from 'electron/main';
import type { ClientRequestConstructorOptions, UploadProgress } from 'electron/main';
const {
isValidHeaderName,
isValidHeaderValue,
createURLLoader
} = process._linkedBinding('electron_browser_net');
const { Session } = process._linkedBinding('electron_browser_session');
const kHttpProtocols = new Set(['http:', 'https:']);
// set of headers that Node.js discards duplicates for
// see https://nodejs.org/api/http.html#http_message_headers
const discardableDuplicateHeaders = new Set([
'content-type',
'content-length',
'user-agent',
'referer',
'host',
'authorization',
'proxy-authorization',
'if-modified-since',
'if-unmodified-since',
'from',
'location',
'max-forwards',
'retry-after',
'etag',
'last-modified',
'server',
'age',
'expires'
]);
class IncomingMessage extends Readable {
_shouldPush: boolean = false;
_data: (Buffer | null)[] = [];
_responseHead: NodeJS.ResponseHead;
_resume: (() => void) | null = null;
constructor (responseHead: NodeJS.ResponseHead) {
super();
this._responseHead = responseHead;
}
get statusCode () {
return this._responseHead.statusCode;
}
get statusMessage () {
return this._responseHead.statusMessage;
}
get headers () {
const filteredHeaders: Record<string, string | string[]> = {};
const { headers, rawHeaders } = this._responseHead;
for (const [name, values] of Object.entries(headers)) {
filteredHeaders[name] = discardableDuplicateHeaders.has(name) ? values[0] : values.join(', ');
}
const cookies = rawHeaders.filter(({ key }) => key.toLowerCase() === 'set-cookie').map(({ value }) => value);
// keep set-cookie as an array per Node.js rules
// see https://nodejs.org/api/http.html#http_message_headers
if (cookies.length) { filteredHeaders['set-cookie'] = cookies; }
return filteredHeaders;
}
get rawHeaders () {
const rawHeadersArr: string[] = [];
const { rawHeaders } = this._responseHead;
rawHeaders.forEach(header => {
rawHeadersArr.push(header.key, header.value);
});
return rawHeadersArr;
}
get httpVersion () {
return `${this.httpVersionMajor}.${this.httpVersionMinor}`;
}
get httpVersionMajor () {
return this._responseHead.httpVersion.major;
}
get httpVersionMinor () {
return this._responseHead.httpVersion.minor;
}
get rawTrailers () {
throw new Error('HTTP trailers are not supported');
}
get trailers () {
throw new Error('HTTP trailers are not supported');
}
_storeInternalData (chunk: Buffer | null, resume: (() => void) | null) {
// save the network callback for use in _pushInternalData
this._resume = resume;
this._data.push(chunk);
this._pushInternalData();
}
_pushInternalData () {
while (this._shouldPush && this._data.length > 0) {
const chunk = this._data.shift();
this._shouldPush = this.push(chunk);
}
if (this._shouldPush && this._resume) {
// Reset the callback, so that a new one is used for each
// batch of throttled data. Do this before calling resume to avoid a
// potential race-condition
const resume = this._resume;
this._resume = null;
resume();
}
}
_read () {
this._shouldPush = true;
this._pushInternalData();
}
}
/** Writable stream that buffers up everything written to it. */
class SlurpStream extends Writable {
_data: Buffer;
constructor () {
super();
this._data = Buffer.alloc(0);
}
_write (chunk: Buffer, encoding: string, callback: () => void) {
this._data = Buffer.concat([this._data, chunk]);
callback();
}
data () { return this._data; }
}
class ChunkedBodyStream extends Writable {
_pendingChunk: Buffer | undefined;
_downstream?: NodeJS.DataPipe;
_pendingCallback?: (error?: Error) => void;
_clientRequest: ClientRequest;
constructor (clientRequest: ClientRequest) {
super();
this._clientRequest = clientRequest;
}
_write (chunk: Buffer, encoding: string, callback: () => void) {
if (this._downstream) {
this._downstream.write(chunk).then(callback, callback);
} else {
// the contract of _write is that we won't be called again until we call
// the callback, so we're good to just save a single chunk.
this._pendingChunk = chunk;
this._pendingCallback = callback;
// The first write to a chunked body stream begins the request.
this._clientRequest._startRequest();
}
}
_final (callback: () => void) {
this._downstream!.done();
callback();
}
startReading (pipe: NodeJS.DataPipe) {
if (this._downstream) {
throw new Error('two startReading calls???');
}
this._downstream = pipe;
if (this._pendingChunk) {
const doneWriting = (maybeError: Error | void) => {
// If the underlying request has been aborted, we honestly 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;
cb(maybeError || undefined);
};
this._downstream.write(this._pendingChunk).then(doneWriting, doneWriting);
}
}
}
type RedirectPolicy = 'manual' | 'follow' | 'error';
const kAllowNonHttpProtocols = Symbol('kAllowNonHttpProtocols');
export function allowAnyProtocol (opts: ClientRequestConstructorOptions): ClientRequestConstructorOptions {
return {
...opts,
[kAllowNonHttpProtocols]: true
} as any;
}
type ExtraURLLoaderOptions = {
redirectPolicy: RedirectPolicy;
headers: Record<string, { name: string, value: string | string[] }>;
allowNonHttpProtocols: boolean;
}
function parseOptions (optionsIn: ClientRequestConstructorOptions | string): NodeJS.CreateURLLoaderOptions & ExtraURLLoaderOptions {
const options: any = typeof optionsIn === 'string' ? url.parse(optionsIn) : { ...optionsIn };
let urlStr: string = options.url;
if (!urlStr) {
const urlObj: url.UrlObject = {};
const protocol = options.protocol || 'http:';
urlObj.protocol = protocol;
if (options.host) {
urlObj.host = options.host;
} else {
if (options.hostname) {
urlObj.hostname = options.hostname;
} else {
urlObj.hostname = 'localhost';
}
if (options.port) {
urlObj.port = options.port;
}
}
if (options.path && / /.test(options.path)) {
// The actual regex is more like /[^A-Za-z0-9\-._~!$&'()*+,;=/:@]/
// with an additional rule for ignoring percentage-escaped characters
// but that's a) hard to capture in a regular expression that performs
// well, and b) possibly too restrictive for real-world usage. That's
// why it only scans for spaces because those are guaranteed to create
// an invalid request.
throw new TypeError('Request path contains unescaped characters');
}
const pathObj = url.parse(options.path || '/');
urlObj.pathname = pathObj.pathname;
urlObj.search = pathObj.search;
urlObj.hash = pathObj.hash;
urlStr = url.format(urlObj);
}
const redirectPolicy = options.redirect || 'follow';
if (!['follow', 'error', 'manual'].includes(redirectPolicy)) {
throw new Error('redirect mode should be one of follow, error or manual');
}
if (options.headers != null && typeof options.headers !== 'object') {
throw new TypeError('headers must be an object');
}
const urlLoaderOptions: NodeJS.CreateURLLoaderOptions & { redirectPolicy: RedirectPolicy, headers: Record<string, { name: string, value: string | string[] }>, allowNonHttpProtocols: boolean } = {
method: (options.method || 'GET').toUpperCase(),
url: urlStr,
redirectPolicy,
headers: {},
body: null as any,
useSessionCookies: options.useSessionCookies,
credentials: options.credentials,
origin: options.origin,
referrerPolicy: options.referrerPolicy,
cache: options.cache,
allowNonHttpProtocols: Object.prototype.hasOwnProperty.call(options, kAllowNonHttpProtocols)
};
const headers: Record<string, string | string[]> = options.headers || {};
for (const [name, value] of Object.entries(headers)) {
if (!isValidHeaderName(name)) {
throw new Error(`Invalid header name: '${name}'`);
}
if (!isValidHeaderValue(value.toString())) {
throw new Error(`Invalid value for header '${name}': '${value}'`);
}
const key = name.toLowerCase();
urlLoaderOptions.headers[key] = { name, value };
}
if (options.session) {
if (!(options.session instanceof Session)) { throw new TypeError('`session` should be an instance of the Session class'); }
urlLoaderOptions.session = options.session;
} else if (options.partition) {
if (typeof options.partition === 'string') {
urlLoaderOptions.partition = options.partition;
} else {
throw new TypeError('`partition` should be a string');
}
}
return urlLoaderOptions;
}
export class ClientRequest extends Writable implements Electron.ClientRequest {
_started: boolean = false;
_firstWrite: boolean = false;
_aborted: boolean = false;
_chunkedEncoding: boolean | undefined;
_body: Writable | undefined;
_urlLoaderOptions: NodeJS.CreateURLLoaderOptions & { headers: Record<string, { name: string, value: string | string[] }> };
_redirectPolicy: RedirectPolicy;
_followRedirectCb?: () => void;
_uploadProgress?: { active: boolean, started: boolean, current: number, total: number };
_urlLoader?: NodeJS.URLLoader;
_response?: IncomingMessage;
constructor (options: ClientRequestConstructorOptions | string, callback?: (message: IncomingMessage) => void) {
super({ autoDestroy: true });
if (!app.isReady()) {
throw new Error('net module can only be used after app is ready');
}
if (callback) {
this.once('response', callback);
}
const { redirectPolicy, ...urlLoaderOptions } = parseOptions(options);
const urlObj = new URL(urlLoaderOptions.url);
if (!urlLoaderOptions.allowNonHttpProtocols && !kHttpProtocols.has(urlObj.protocol)) {
throw new Error('ClientRequest only supports http: and https: protocols');
}
if (urlLoaderOptions.credentials === 'same-origin' && !urlLoaderOptions.origin) { throw new Error('credentials: same-origin requires origin to be set'); }
this._urlLoaderOptions = urlLoaderOptions;
this._redirectPolicy = redirectPolicy;
}
get chunkedEncoding () {
return this._chunkedEncoding || false;
}
set chunkedEncoding (value: boolean) {
if (this._started) {
throw new Error('chunkedEncoding can only be set before the request is started');
}
if (typeof this._chunkedEncoding !== 'undefined') {
throw new Error('chunkedEncoding can only be set once');
}
this._chunkedEncoding = !!value;
if (this._chunkedEncoding) {
this._body = new ChunkedBodyStream(this);
this._urlLoaderOptions.body = (pipe: NodeJS.DataPipe) => {
(this._body! as ChunkedBodyStream).startReading(pipe);
};
}
}
setHeader (name: string, value: string) {
if (typeof name !== 'string') {
throw new TypeError('`name` should be a string in setHeader(name, value)');
}
if (value == null) {
throw new Error('`value` required in setHeader("' + name + '", value)');
}
if (this._started || this._firstWrite) {
throw new Error('Can\'t set headers after they are sent');
}
if (!isValidHeaderName(name)) {
throw new Error(`Invalid header name: '${name}'`);
}
if (!isValidHeaderValue(value.toString())) {
throw new Error(`Invalid value for header '${name}': '${value}'`);
}
const key = name.toLowerCase();
this._urlLoaderOptions.headers[key] = { name, value };
}
getHeader (name: string) {
if (name == null) {
throw new Error('`name` is required for getHeader(name)');
}
const key = name.toLowerCase();
const header = this._urlLoaderOptions.headers[key];
return header && header.value as any;
}
removeHeader (name: string) {
if (name == null) {
throw new Error('`name` is required for removeHeader(name)');
}
if (this._started || this._firstWrite) {
throw new Error('Can\'t remove headers after they are sent');
}
const key = name.toLowerCase();
delete this._urlLoaderOptions.headers[key];
}
_write (chunk: Buffer, encoding: BufferEncoding, callback: () => void) {
this._firstWrite = true;
if (!this._body) {
this._body = new SlurpStream();
this._body.on('finish', () => {
this._urlLoaderOptions.body = (this._body as SlurpStream).data();
this._startRequest();
});
}
// TODO: is this the right way to forward to another stream?
this._body.write(chunk, encoding, callback);
}
_final (callback: () => void) {
if (this._body) {
// TODO: is this the right way to forward to another stream?
this._body.end(callback);
} else {
// end() called without a body, go ahead and start the request
this._startRequest();
callback();
}
}
_startRequest () {
this._started = true;
const stringifyValues = (obj: Record<string, { name: string, value: string | string[] }>) => {
const ret: Record<string, string> = {};
for (const k of Object.keys(obj)) {
const kv = obj[k];
ret[kv.name] = kv.value.toString();
}
return ret;
};
this._urlLoaderOptions.referrer = this.getHeader('referer') || '';
this._urlLoaderOptions.origin = this._urlLoaderOptions.origin || this.getHeader('origin') || '';
this._urlLoaderOptions.hasUserActivation = this.getHeader('sec-fetch-user') === '?1';
this._urlLoaderOptions.mode = this.getHeader('sec-fetch-mode') || '';
this._urlLoaderOptions.destination = this.getHeader('sec-fetch-dest') || '';
const opts = { ...this._urlLoaderOptions, extraHeaders: stringifyValues(this._urlLoaderOptions.headers) };
this._urlLoader = createURLLoader(opts);
this._urlLoader.on('response-started', (event, finalUrl, responseHead) => {
const response = this._response = new IncomingMessage(responseHead);
this.emit('response', response);
});
this._urlLoader.on('data', (event, data, resume) => {
this._response!._storeInternalData(Buffer.from(data), resume);
});
this._urlLoader.on('complete', () => {
if (this._response) { this._response._storeInternalData(null, null); }
});
this._urlLoader.on('error', (event, netErrorString) => {
const error = new Error(netErrorString);
if (this._response) this._response.destroy(error);
this._die(error);
});
this._urlLoader.on('login', (event, authInfo, callback) => {
const handled = this.emit('login', authInfo, callback);
if (!handled) {
// If there were no listeners, cancel the authentication request.
callback();
}
});
this._urlLoader.on('redirect', (event, redirectInfo, headers) => {
const { statusCode, newMethod, newUrl } = redirectInfo;
if (this._redirectPolicy === 'error') {
this._die(new Error('Attempted to redirect, but redirect policy was \'error\''));
} else if (this._redirectPolicy === 'manual') {
let _followRedirect = false;
this._followRedirectCb = () => { _followRedirect = true; };
try {
this.emit('redirect', statusCode, newMethod, newUrl, headers);
} finally {
this._followRedirectCb = undefined;
if (!_followRedirect && !this._aborted) {
this._die(new Error('Redirect was cancelled'));
}
}
} else if (this._redirectPolicy === 'follow') {
// Calling followRedirect() when the redirect policy is 'follow' is
// allowed but does nothing. (Perhaps it should throw an error
// though...? Since the redirect will happen regardless.)
try {
this._followRedirectCb = () => {};
this.emit('redirect', statusCode, newMethod, newUrl, headers);
} finally {
this._followRedirectCb = undefined;
}
} else {
this._die(new Error(`Unexpected redirect policy '${this._redirectPolicy}'`));
}
});
this._urlLoader.on('upload-progress', (event, position, total) => {
this._uploadProgress = { active: true, started: true, current: position, total };
this.emit('upload-progress', position, total); // Undocumented, for now
});
this._urlLoader.on('download-progress', (event, current) => {
if (this._response) {
this._response.emit('download-progress', current); // Undocumented, for now
}
});
}
followRedirect () {
if (this._followRedirectCb) {
this._followRedirectCb();
} else {
throw new Error('followRedirect() called, but was not waiting for a redirect');
}
}
abort () {
if (!this._aborted) {
process.nextTick(() => { this.emit('abort'); });
}
this._aborted = true;
this._die();
}
_die (err?: Error) {
// Node.js assumes that any stream which is ended is no longer capable of emitted events
// which is a faulty assumption for the case of an object that is acting like a stream
// (our urlRequest). If we don't emit here, this causes errors since we *do* expect
// that error events can be emitted after urlRequest.end().
if ((this as any)._writableState.destroyed && err) {
this.emit('error', err);
}
this.destroy(err);
if (this._urlLoader) {
this._urlLoader.cancel();
if (this._response) this._response.destroy(err);
}
}
getUploadProgress (): UploadProgress {
return this._uploadProgress ? { ...this._uploadProgress } : { active: false, started: false, current: 0, total: 0 };
}
}

View File

@@ -1,120 +0,0 @@
import { net, IncomingMessage, Session as SessionT } from 'electron/main';
import { Readable, Writable, isReadable } from 'stream';
import { allowAnyProtocol } from '@electron/internal/browser/api/net-client-request';
function createDeferredPromise<T, E extends Error = Error> (): { promise: Promise<T>; resolve: (x: T) => void; reject: (e: E) => void; } {
let res: (x: T) => void;
let rej: (e: E) => void;
const promise = new Promise<T>((resolve, reject) => {
res = resolve;
rej = reject;
});
return { promise, resolve: res!, reject: rej! };
}
export function fetchWithSession (input: RequestInfo, init: (RequestInit & {bypassCustomProtocolHandlers?: boolean}) | undefined, session: SessionT): Promise<Response> {
const p = createDeferredPromise<Response>();
let req: Request;
try {
req = new Request(input, init);
} catch (e: any) {
p.reject(e);
return p.promise;
}
if (req.signal.aborted) {
// 1. Abort the fetch() call with p, request, null, and
// requestObjects signals abort reason.
const error = (req.signal as any).reason ?? new DOMException('The operation was aborted.', 'AbortError');
p.reject(error);
if (req.body != null && isReadable(req.body as unknown as NodeJS.ReadableStream)) {
req.body.cancel(error).catch((err) => {
if (err.code === 'ERR_INVALID_STATE') {
// Node bug?
return;
}
throw err;
});
}
// 2. Return p.
return p.promise;
}
let locallyAborted = false;
req.signal.addEventListener(
'abort',
() => {
// 1. Set locallyAborted to true.
locallyAborted = true;
// 2. Abort the fetch() call with p, request, responseObject,
// and requestObjects signals abort reason.
const error = (req.signal as any).reason ?? new DOMException('The operation was aborted.', 'AbortError');
p.reject(error);
if (req.body != null && isReadable(req.body as unknown as NodeJS.ReadableStream)) {
req.body.cancel(error).catch((err) => {
if (err.code === 'ERR_INVALID_STATE') {
// Node bug?
return;
}
throw err;
});
}
r.abort();
},
{ once: true }
);
const origin = req.headers.get('origin') ?? undefined;
// We can't set credentials to same-origin unless there's an origin set.
const credentials = req.credentials === 'same-origin' && !origin ? 'include' : req.credentials;
const r = net.request(allowAnyProtocol({
session,
method: req.method,
url: req.url,
origin,
credentials,
cache: req.cache,
referrerPolicy: req.referrerPolicy,
redirect: req.redirect
}));
(r as any)._urlLoaderOptions.bypassCustomProtocolHandlers = !!init?.bypassCustomProtocolHandlers;
// cors is the default mode, but we can't set mode=cors without an origin.
if (req.mode && (req.mode !== 'cors' || origin)) {
r.setHeader('Sec-Fetch-Mode', req.mode);
}
for (const [k, v] of req.headers) {
r.setHeader(k, v);
}
r.on('response', (resp: IncomingMessage) => {
if (locallyAborted) return;
const headers = new Headers();
for (const [k, v] of Object.entries(resp.headers)) { headers.set(k, Array.isArray(v) ? v.join(', ') : v); }
const nullBodyStatus = [101, 204, 205, 304];
const body = nullBodyStatus.includes(resp.statusCode) || req.method === 'HEAD' ? null : Readable.toWeb(resp as unknown as Readable) as ReadableStream;
const rResp = new Response(body, {
headers,
status: resp.statusCode,
statusText: resp.statusMessage
});
(rResp as any).__original_resp = resp;
p.resolve(rResp);
});
r.on('error', (err) => {
p.reject(err);
});
if (!req.body?.pipeTo(Writable.toWeb(r as unknown as Writable)).then(() => r.end())) { r.end(); }
return p.promise;
}

View File

@@ -1,17 +1,531 @@
import { IncomingMessage, session } from 'electron/main';
import type { ClientRequestConstructorOptions } from 'electron/main';
import { ClientRequest } from '@electron/internal/browser/api/net-client-request';
import * as url from 'url';
import { Readable, Writable } from 'stream';
import { app, session } from 'electron/main';
import type { ClientRequestConstructorOptions, UploadProgress } from 'electron/main';
const { isOnline } = process._linkedBinding('electron_browser_net');
const {
isOnline,
isValidHeaderName,
isValidHeaderValue,
createURLLoader
} = process._linkedBinding('electron_browser_net');
const kSupportedProtocols = new Set(['http:', 'https:']);
// set of headers that Node.js discards duplicates for
// see https://nodejs.org/api/http.html#http_message_headers
const discardableDuplicateHeaders = new Set([
'content-type',
'content-length',
'user-agent',
'referer',
'host',
'authorization',
'proxy-authorization',
'if-modified-since',
'if-unmodified-since',
'from',
'location',
'max-forwards',
'retry-after',
'etag',
'last-modified',
'server',
'age',
'expires'
]);
class IncomingMessage extends Readable {
_shouldPush: boolean = false;
_data: (Buffer | null)[] = [];
_responseHead: NodeJS.ResponseHead;
_resume: (() => void) | null = null;
constructor (responseHead: NodeJS.ResponseHead) {
super();
this._responseHead = responseHead;
}
get statusCode () {
return this._responseHead.statusCode;
}
get statusMessage () {
return this._responseHead.statusMessage;
}
get headers () {
const filteredHeaders: Record<string, string | string[]> = {};
const { headers, rawHeaders } = this._responseHead;
for (const [name, values] of Object.entries(headers)) {
filteredHeaders[name] = discardableDuplicateHeaders.has(name) ? values[0] : values.join(', ');
}
const cookies = rawHeaders.filter(({ key }) => key.toLowerCase() === 'set-cookie').map(({ value }) => value);
// keep set-cookie as an array per Node.js rules
// see https://nodejs.org/api/http.html#http_message_headers
if (cookies.length) { filteredHeaders['set-cookie'] = cookies; }
return filteredHeaders;
}
get rawHeaders () {
const rawHeadersArr: string[] = [];
const { rawHeaders } = this._responseHead;
rawHeaders.forEach(header => {
rawHeadersArr.push(header.key, header.value);
});
return rawHeadersArr;
}
get httpVersion () {
return `${this.httpVersionMajor}.${this.httpVersionMinor}`;
}
get httpVersionMajor () {
return this._responseHead.httpVersion.major;
}
get httpVersionMinor () {
return this._responseHead.httpVersion.minor;
}
get rawTrailers () {
throw new Error('HTTP trailers are not supported');
}
get trailers () {
throw new Error('HTTP trailers are not supported');
}
_storeInternalData (chunk: Buffer | null, resume: (() => void) | null) {
// save the network callback for use in _pushInternalData
this._resume = resume;
this._data.push(chunk);
this._pushInternalData();
}
_pushInternalData () {
while (this._shouldPush && this._data.length > 0) {
const chunk = this._data.shift();
this._shouldPush = this.push(chunk);
}
if (this._shouldPush && this._resume) {
// Reset the callback, so that a new one is used for each
// batch of throttled data. Do this before calling resume to avoid a
// potential race-condition
const resume = this._resume;
this._resume = null;
resume();
}
}
_read () {
this._shouldPush = true;
this._pushInternalData();
}
}
/** Writable stream that buffers up everything written to it. */
class SlurpStream extends Writable {
_data: Buffer;
constructor () {
super();
this._data = Buffer.alloc(0);
}
_write (chunk: Buffer, encoding: string, callback: () => void) {
this._data = Buffer.concat([this._data, chunk]);
callback();
}
data () { return this._data; }
}
class ChunkedBodyStream extends Writable {
_pendingChunk: Buffer | undefined;
_downstream?: NodeJS.DataPipe;
_pendingCallback?: (error?: Error) => void;
_clientRequest: ClientRequest;
constructor (clientRequest: ClientRequest) {
super();
this._clientRequest = clientRequest;
}
_write (chunk: Buffer, encoding: string, callback: () => void) {
if (this._downstream) {
this._downstream.write(chunk).then(callback, callback);
} else {
// the contract of _write is that we won't be called again until we call
// the callback, so we're good to just save a single chunk.
this._pendingChunk = chunk;
this._pendingCallback = callback;
// The first write to a chunked body stream begins the request.
this._clientRequest._startRequest();
}
}
_final (callback: () => void) {
this._downstream!.done();
callback();
}
startReading (pipe: NodeJS.DataPipe) {
if (this._downstream) {
throw new Error('two startReading calls???');
}
this._downstream = pipe;
if (this._pendingChunk) {
const doneWriting = (maybeError: Error | void) => {
// If the underlying request has been aborted, we honestly 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;
cb(maybeError || undefined);
};
this._downstream.write(this._pendingChunk).then(doneWriting, doneWriting);
}
}
}
type RedirectPolicy = 'manual' | 'follow' | 'error';
function parseOptions (optionsIn: ClientRequestConstructorOptions | string): NodeJS.CreateURLLoaderOptions & { redirectPolicy: RedirectPolicy, headers: Record<string, { name: string, value: string | string[] }> } {
const options: any = typeof optionsIn === 'string' ? url.parse(optionsIn) : { ...optionsIn };
let urlStr: string = options.url;
if (!urlStr) {
const urlObj: url.UrlObject = {};
const protocol = options.protocol || 'http:';
if (!kSupportedProtocols.has(protocol)) {
throw new Error('Protocol "' + protocol + '" not supported');
}
urlObj.protocol = protocol;
if (options.host) {
urlObj.host = options.host;
} else {
if (options.hostname) {
urlObj.hostname = options.hostname;
} else {
urlObj.hostname = 'localhost';
}
if (options.port) {
urlObj.port = options.port;
}
}
if (options.path && / /.test(options.path)) {
// The actual regex is more like /[^A-Za-z0-9\-._~!$&'()*+,;=/:@]/
// with an additional rule for ignoring percentage-escaped characters
// but that's a) hard to capture in a regular expression that performs
// well, and b) possibly too restrictive for real-world usage. That's
// why it only scans for spaces because those are guaranteed to create
// an invalid request.
throw new TypeError('Request path contains unescaped characters');
}
const pathObj = url.parse(options.path || '/');
urlObj.pathname = pathObj.pathname;
urlObj.search = pathObj.search;
urlObj.hash = pathObj.hash;
urlStr = url.format(urlObj);
}
const redirectPolicy = options.redirect || 'follow';
if (!['follow', 'error', 'manual'].includes(redirectPolicy)) {
throw new Error('redirect mode should be one of follow, error or manual');
}
if (options.headers != null && typeof options.headers !== 'object') {
throw new TypeError('headers must be an object');
}
const urlLoaderOptions: NodeJS.CreateURLLoaderOptions & { redirectPolicy: RedirectPolicy, headers: Record<string, { name: string, value: string | string[] }> } = {
method: (options.method || 'GET').toUpperCase(),
url: urlStr,
redirectPolicy,
headers: {},
body: null as any,
useSessionCookies: options.useSessionCookies,
credentials: options.credentials,
origin: options.origin
};
const headers: Record<string, string | string[]> = options.headers || {};
for (const [name, value] of Object.entries(headers)) {
if (!isValidHeaderName(name)) {
throw new Error(`Invalid header name: '${name}'`);
}
if (!isValidHeaderValue(value.toString())) {
throw new Error(`Invalid value for header '${name}': '${value}'`);
}
const key = name.toLowerCase();
urlLoaderOptions.headers[key] = { name, value };
}
if (options.session) {
// Weak check, but it should be enough to catch 99% of accidental misuses.
if (options.session.constructor && options.session.constructor.name === 'Session') {
urlLoaderOptions.session = options.session;
} else {
throw new TypeError('`session` should be an instance of the Session class');
}
} else if (options.partition) {
if (typeof options.partition === 'string') {
urlLoaderOptions.partition = options.partition;
} else {
throw new TypeError('`partition` should be a string');
}
}
return urlLoaderOptions;
}
export class ClientRequest extends Writable implements Electron.ClientRequest {
_started: boolean = false;
_firstWrite: boolean = false;
_aborted: boolean = false;
_chunkedEncoding: boolean | undefined;
_body: Writable | undefined;
_urlLoaderOptions: NodeJS.CreateURLLoaderOptions & { headers: Record<string, { name: string, value: string | string[] }> };
_redirectPolicy: RedirectPolicy;
_followRedirectCb?: () => void;
_uploadProgress?: { active: boolean, started: boolean, current: number, total: number };
_urlLoader?: NodeJS.URLLoader;
_response?: IncomingMessage;
constructor (options: ClientRequestConstructorOptions | string, callback?: (message: IncomingMessage) => void) {
super({ autoDestroy: true });
if (!app.isReady()) {
throw new Error('net module can only be used after app is ready');
}
if (callback) {
this.once('response', callback);
}
const { redirectPolicy, ...urlLoaderOptions } = parseOptions(options);
this._urlLoaderOptions = urlLoaderOptions;
this._redirectPolicy = redirectPolicy;
}
get chunkedEncoding () {
return this._chunkedEncoding || false;
}
set chunkedEncoding (value: boolean) {
if (this._started) {
throw new Error('chunkedEncoding can only be set before the request is started');
}
if (typeof this._chunkedEncoding !== 'undefined') {
throw new Error('chunkedEncoding can only be set once');
}
this._chunkedEncoding = !!value;
if (this._chunkedEncoding) {
this._body = new ChunkedBodyStream(this);
this._urlLoaderOptions.body = (pipe: NodeJS.DataPipe) => {
(this._body! as ChunkedBodyStream).startReading(pipe);
};
}
}
setHeader (name: string, value: string) {
if (typeof name !== 'string') {
throw new TypeError('`name` should be a string in setHeader(name, value)');
}
if (value == null) {
throw new Error('`value` required in setHeader("' + name + '", value)');
}
if (this._started || this._firstWrite) {
throw new Error('Can\'t set headers after they are sent');
}
if (!isValidHeaderName(name)) {
throw new Error(`Invalid header name: '${name}'`);
}
if (!isValidHeaderValue(value.toString())) {
throw new Error(`Invalid value for header '${name}': '${value}'`);
}
const key = name.toLowerCase();
this._urlLoaderOptions.headers[key] = { name, value };
}
getHeader (name: string) {
if (name == null) {
throw new Error('`name` is required for getHeader(name)');
}
const key = name.toLowerCase();
const header = this._urlLoaderOptions.headers[key];
return header && header.value as any;
}
removeHeader (name: string) {
if (name == null) {
throw new Error('`name` is required for removeHeader(name)');
}
if (this._started || this._firstWrite) {
throw new Error('Can\'t remove headers after they are sent');
}
const key = name.toLowerCase();
delete this._urlLoaderOptions.headers[key];
}
_write (chunk: Buffer, encoding: BufferEncoding, callback: () => void) {
this._firstWrite = true;
if (!this._body) {
this._body = new SlurpStream();
this._body.on('finish', () => {
this._urlLoaderOptions.body = (this._body as SlurpStream).data();
this._startRequest();
});
}
// TODO: is this the right way to forward to another stream?
this._body.write(chunk, encoding, callback);
}
_final (callback: () => void) {
if (this._body) {
// TODO: is this the right way to forward to another stream?
this._body.end(callback);
} else {
// end() called without a body, go ahead and start the request
this._startRequest();
callback();
}
}
_startRequest () {
this._started = true;
const stringifyValues = (obj: Record<string, { name: string, value: string | string[] }>) => {
const ret: Record<string, string> = {};
for (const k of Object.keys(obj)) {
const kv = obj[k];
ret[kv.name] = kv.value.toString();
}
return ret;
};
this._urlLoaderOptions.referrer = this.getHeader('referer') || '';
this._urlLoaderOptions.origin = this._urlLoaderOptions.origin || this.getHeader('origin') || '';
this._urlLoaderOptions.hasUserActivation = this.getHeader('sec-fetch-user') === '?1';
this._urlLoaderOptions.mode = this.getHeader('sec-fetch-mode') || '';
this._urlLoaderOptions.destination = this.getHeader('sec-fetch-dest') || '';
const opts = { ...this._urlLoaderOptions, extraHeaders: stringifyValues(this._urlLoaderOptions.headers) };
this._urlLoader = createURLLoader(opts);
this._urlLoader.on('response-started', (event, finalUrl, responseHead) => {
const response = this._response = new IncomingMessage(responseHead);
this.emit('response', response);
});
this._urlLoader.on('data', (event, data, resume) => {
this._response!._storeInternalData(Buffer.from(data), resume);
});
this._urlLoader.on('complete', () => {
if (this._response) { this._response._storeInternalData(null, null); }
});
this._urlLoader.on('error', (event, netErrorString) => {
const error = new Error(netErrorString);
if (this._response) this._response.destroy(error);
this._die(error);
});
this._urlLoader.on('login', (event, authInfo, callback) => {
const handled = this.emit('login', authInfo, callback);
if (!handled) {
// If there were no listeners, cancel the authentication request.
callback();
}
});
this._urlLoader.on('redirect', (event, redirectInfo, headers) => {
const { statusCode, newMethod, newUrl } = redirectInfo;
if (this._redirectPolicy === 'error') {
this._die(new Error('Attempted to redirect, but redirect policy was \'error\''));
} else if (this._redirectPolicy === 'manual') {
let _followRedirect = false;
this._followRedirectCb = () => { _followRedirect = true; };
try {
this.emit('redirect', statusCode, newMethod, newUrl, headers);
} finally {
this._followRedirectCb = undefined;
if (!_followRedirect && !this._aborted) {
this._die(new Error('Redirect was cancelled'));
}
}
} else if (this._redirectPolicy === 'follow') {
// Calling followRedirect() when the redirect policy is 'follow' is
// allowed but does nothing. (Perhaps it should throw an error
// though...? Since the redirect will happen regardless.)
try {
this._followRedirectCb = () => {};
this.emit('redirect', statusCode, newMethod, newUrl, headers);
} finally {
this._followRedirectCb = undefined;
}
} else {
this._die(new Error(`Unexpected redirect policy '${this._redirectPolicy}'`));
}
});
this._urlLoader.on('upload-progress', (event, position, total) => {
this._uploadProgress = { active: true, started: true, current: position, total };
this.emit('upload-progress', position, total); // Undocumented, for now
});
this._urlLoader.on('download-progress', (event, current) => {
if (this._response) {
this._response.emit('download-progress', current); // Undocumented, for now
}
});
}
followRedirect () {
if (this._followRedirectCb) {
this._followRedirectCb();
} else {
throw new Error('followRedirect() called, but was not waiting for a redirect');
}
}
abort () {
if (!this._aborted) {
process.nextTick(() => { this.emit('abort'); });
}
this._aborted = true;
this._die();
}
_die (err?: Error) {
// Node.js assumes that any stream which is ended is no longer capable of emitted events
// which is a faulty assumption for the case of an object that is acting like a stream
// (our urlRequest). If we don't emit here, this causes errors since we *do* expect
// that error events can be emitted after urlRequest.end().
if ((this as any)._writableState.destroyed && err) {
this.emit('error', err);
}
this.destroy(err);
if (this._urlLoader) {
this._urlLoader.cancel();
if (this._response) this._response.destroy(err);
}
}
getUploadProgress (): UploadProgress {
return this._uploadProgress ? { ...this._uploadProgress } : { active: false, started: false, current: 0, total: 0 };
}
}
export function request (options: ClientRequestConstructorOptions | string, callback?: (message: IncomingMessage) => void) {
return new ClientRequest(options, callback);
}
export function fetch (input: RequestInfo, init?: RequestInit): Promise<Response> {
return session.defaultSession.fetch(input, init);
}
export function resolveHost (host: string, options?: Electron.ResolveHostOptions): Promise<Electron.ResolvedHost> {
return session.defaultSession.resolveHost(host, options);
}

View File

@@ -1,151 +1,33 @@
import { ProtocolRequest, session } from 'electron/main';
import { createReadStream } from 'fs';
import { Readable } from 'stream';
import { ReadableStream } from 'stream/web';
import { app, session } from 'electron/main';
// Global protocol APIs.
const { registerSchemesAsPrivileged, getStandardSchemes, Protocol } = process._linkedBinding('electron_browser_protocol');
const protocol = process._linkedBinding('electron_browser_protocol');
const ERR_FAILED = -2;
const ERR_UNEXPECTED = -9;
// Fallback protocol APIs of default session.
Object.setPrototypeOf(protocol, new Proxy({}, {
get (_target, property) {
if (!app.isReady()) return;
const isBuiltInScheme = (scheme: string) => ['http', 'https', 'file'].includes(scheme);
const protocol = session.defaultSession!.protocol;
if (!Object.prototype.hasOwnProperty.call(protocol, property)) return;
function makeStreamFromPipe (pipe: any): ReadableStream {
const buf = new Uint8Array(1024 * 1024 /* 1 MB */);
return new ReadableStream({
async pull (controller) {
try {
const rv = await pipe.read(buf);
if (rv > 0) {
controller.enqueue(buf.subarray(0, rv));
} else {
controller.close();
}
} catch (e) {
controller.error(e);
}
}
});
}
// Returning a native function directly would throw error.
return (...args: any[]) => (protocol[property as keyof Electron.Protocol] as Function)(...args);
},
function convertToRequestBody (uploadData: ProtocolRequest['uploadData']): RequestInit['body'] {
if (!uploadData) return null;
// Optimization: skip creating a stream if the request is just a single buffer.
if (uploadData.length === 1 && (uploadData[0] as any).type === 'rawData') return uploadData[0].bytes;
ownKeys () {
if (!app.isReady()) return [];
return Reflect.ownKeys(session.defaultSession!.protocol);
},
const chunks = [...uploadData] as any[]; // TODO: types are wrong
let current: ReadableStreamDefaultReader | null = null;
return new ReadableStream({
pull (controller) {
if (current) {
current.read().then(({ done, value }) => {
controller.enqueue(value);
if (done) current = null;
}, (err) => {
controller.error(err);
});
} else {
if (!chunks.length) { return controller.close(); }
const chunk = chunks.shift()!;
if (chunk.type === 'rawData') { controller.enqueue(chunk.bytes); } else if (chunk.type === 'file') {
current = Readable.toWeb(createReadStream(chunk.filePath, { start: chunk.offset ?? 0, end: chunk.length >= 0 ? chunk.offset + chunk.length : undefined })).getReader();
this.pull!(controller);
} else if (chunk.type === 'stream') {
current = makeStreamFromPipe(chunk.body).getReader();
this.pull!(controller);
}
}
}
}) as RequestInit['body'];
}
has: (target, property: string) => {
if (!app.isReady()) return false;
return Reflect.has(session.defaultSession!.protocol, property);
},
// TODO(codebytere): Use Object.hasOwn() once we update to ECMAScript 2022.
function validateResponse (res: Response) {
if (!res || typeof res !== 'object') return false;
if (res.type === 'error') return true;
const exists = (key: string) => Object.prototype.hasOwnProperty.call(res, key);
if (exists('status') && typeof res.status !== 'number') return false;
if (exists('statusText') && typeof res.statusText !== 'string') return false;
if (exists('headers') && typeof res.headers !== 'object') return false;
if (exists('body')) {
if (typeof res.body !== 'object') return false;
if (res.body !== null && !(res.body instanceof ReadableStream)) return false;
getOwnPropertyDescriptor () {
return { configurable: true, enumerable: true };
}
return true;
}
Protocol.prototype.handle = function (this: Electron.Protocol, scheme: string, handler: (req: Request) => Response | Promise<Response>) {
const register = isBuiltInScheme(scheme) ? this.interceptProtocol : this.registerProtocol;
const success = register.call(this, scheme, async (preq: ProtocolRequest, cb: any) => {
try {
const body = convertToRequestBody(preq.uploadData);
const req = new Request(preq.url, {
headers: preq.headers,
method: preq.method,
referrer: preq.referrer,
body,
duplex: body instanceof ReadableStream ? 'half' : undefined
} as any);
const res = await handler(req);
if (!validateResponse(res)) {
return cb({ error: ERR_UNEXPECTED });
} else if (res.type === 'error') {
cb({ error: ERR_FAILED });
} else {
cb({
data: res.body ? Readable.fromWeb(res.body as ReadableStream<ArrayBufferView>) : null,
headers: res.headers ? Object.fromEntries(res.headers) : {},
statusCode: res.status,
statusText: res.statusText,
mimeType: (res as any).__original_resp?._responseHead?.mimeType
});
}
} catch (e) {
console.error(e);
cb({ error: ERR_UNEXPECTED });
}
});
if (!success) throw new Error(`Failed to register protocol: ${scheme}`);
};
Protocol.prototype.unhandle = function (this: Electron.Protocol, scheme: string) {
const unregister = isBuiltInScheme(scheme) ? this.uninterceptProtocol : this.unregisterProtocol;
if (!unregister.call(this, scheme)) { throw new Error(`Failed to unhandle protocol: ${scheme}`); }
};
Protocol.prototype.isProtocolHandled = function (this: Electron.Protocol, scheme: string) {
const isRegistered = isBuiltInScheme(scheme) ? this.isProtocolIntercepted : this.isProtocolRegistered;
return isRegistered.call(this, scheme);
};
const protocol = {
registerSchemesAsPrivileged,
getStandardSchemes,
registerStringProtocol: (...args) => session.defaultSession.protocol.registerStringProtocol(...args),
registerBufferProtocol: (...args) => session.defaultSession.protocol.registerBufferProtocol(...args),
registerStreamProtocol: (...args) => session.defaultSession.protocol.registerStreamProtocol(...args),
registerFileProtocol: (...args) => session.defaultSession.protocol.registerFileProtocol(...args),
registerHttpProtocol: (...args) => session.defaultSession.protocol.registerHttpProtocol(...args),
registerProtocol: (...args) => session.defaultSession.protocol.registerProtocol(...args),
unregisterProtocol: (...args) => session.defaultSession.protocol.unregisterProtocol(...args),
isProtocolRegistered: (...args) => session.defaultSession.protocol.isProtocolRegistered(...args),
interceptStringProtocol: (...args) => session.defaultSession.protocol.interceptStringProtocol(...args),
interceptBufferProtocol: (...args) => session.defaultSession.protocol.interceptBufferProtocol(...args),
interceptStreamProtocol: (...args) => session.defaultSession.protocol.interceptStreamProtocol(...args),
interceptFileProtocol: (...args) => session.defaultSession.protocol.interceptFileProtocol(...args),
interceptHttpProtocol: (...args) => session.defaultSession.protocol.interceptHttpProtocol(...args),
interceptProtocol: (...args) => session.defaultSession.protocol.interceptProtocol(...args),
uninterceptProtocol: (...args) => session.defaultSession.protocol.uninterceptProtocol(...args),
isProtocolIntercepted: (...args) => session.defaultSession.protocol.isProtocolIntercepted(...args),
handle: (...args) => session.defaultSession.protocol.handle(...args),
unhandle: (...args) => session.defaultSession.protocol.unhandle(...args),
isProtocolHandled: (...args) => session.defaultSession.protocol.isProtocolHandled(...args)
} as typeof Electron.protocol;
}));
export default protocol;

View File

@@ -1,13 +1,7 @@
import { fetchWithSession } from '@electron/internal/browser/api/net-fetch';
const { fromPartition, fromPath, Session } = process._linkedBinding('electron_browser_session');
Session.prototype.fetch = function (input: RequestInfo, init?: RequestInit) {
return fetchWithSession(input, init, this);
};
const { fromPartition } = process._linkedBinding('electron_browser_session');
export default {
fromPartition,
fromPath,
get defaultSession () {
return fromPartition('');
}

View File

@@ -337,9 +337,10 @@ WebContents.prototype.printToPDF = async function (options) {
// TODO(codebytere): deduplicate argument sanitization by moving rest of
// print param logic into new file shared between printToPDF and print
WebContents.prototype.print = function (options: ElectronInternal.WebContentsPrintOptions, callback) {
if (typeof options === 'object') {
const pageSize = options.pageSize ?? 'A4';
WebContents.prototype.print = function (printOptions: ElectronInternal.WebContentsPrintOptions, callback) {
const options = printOptions ?? {};
if (options.pageSize) {
const pageSize = options.pageSize;
if (typeof pageSize === 'object') {
if (!pageSize.height || !pageSize.width) {
throw new Error('height and width properties are required for pageSize');
@@ -356,21 +357,10 @@ WebContents.prototype.print = function (options: ElectronInternal.WebContentsPri
name: 'CUSTOM',
custom_display_name: 'Custom',
height_microns: height,
width_microns: width,
imageable_area_left_microns: 0,
imageable_area_bottom_microns: 0,
imageable_area_right_microns: width,
imageable_area_top_microns: height
};
} else if (typeof pageSize === 'string' && PDFPageSizes[pageSize]) {
const mediaSize = PDFPageSizes[pageSize];
options.mediaSize = {
...mediaSize,
imageable_area_left_microns: 0,
imageable_area_bottom_microns: 0,
imageable_area_right_microns: mediaSize.width_microns,
imageable_area_top_microns: mediaSize.height_microns
width_microns: width
};
} else if (PDFPageSizes[pageSize]) {
options.mediaSize = PDFPageSizes[pageSize];
} else {
throw new Error(`Unsupported pageSize: ${pageSize}`);
}
@@ -426,6 +416,10 @@ WebContents.prototype.loadFile = function (filePath, options = {}) {
};
WebContents.prototype.loadURL = function (url, options) {
if (!options) {
options = {};
}
const p = new Promise<void>((resolve, reject) => {
const resolveAndCleanup = () => {
removeListeners();
@@ -492,7 +486,7 @@ WebContents.prototype.loadURL = function (url, options) {
});
// Add a no-op rejection handler to silence the unhandled rejection error.
p.catch(() => {});
this._loadURL(url, options ?? {});
this._loadURL(url, options);
return p;
};
@@ -545,8 +539,7 @@ const addReplyToEvent = (event: Electron.IpcMainEvent) => {
};
};
const addSenderToEvent = (event: Electron.IpcMainEvent | Electron.IpcMainInvokeEvent, sender: Electron.WebContents) => {
event.sender = sender;
const addSenderFrameToEvent = (event: Electron.IpcMainEvent | Electron.IpcMainInvokeEvent) => {
const { processId, frameId } = event;
Object.defineProperty(event, 'senderFrame', {
get: () => webFrameMain.fromId(processId, frameId)
@@ -555,7 +548,7 @@ const addSenderToEvent = (event: Electron.IpcMainEvent | Electron.IpcMainInvokeE
const addReturnValueToEvent = (event: Electron.IpcMainEvent) => {
Object.defineProperty(event, 'returnValue', {
set: (value) => event._replyChannel.sendReply(value),
set: (value) => event.sendReply(value),
get: () => {}
});
};
@@ -596,7 +589,7 @@ WebContents.prototype._init = function () {
// Dispatch IPC messages to the ipc module.
this.on('-ipc-message' as any, function (this: Electron.WebContents, event: Electron.IpcMainEvent, internal: boolean, channel: string, args: any[]) {
addSenderToEvent(event, this);
addSenderFrameToEvent(event);
if (internal) {
ipcMainInternal.emit(channel, event, ...args);
} else {
@@ -609,30 +602,25 @@ WebContents.prototype._init = function () {
}
});
this.on('-ipc-invoke' as any, async function (this: Electron.WebContents, event: Electron.IpcMainInvokeEvent, internal: boolean, channel: string, args: any[]) {
addSenderToEvent(event, this);
const replyWithResult = (result: any) => event._replyChannel.sendReply({ result });
const replyWithError = (error: Error) => {
this.on('-ipc-invoke' as any, function (event: Electron.IpcMainInvokeEvent, internal: boolean, channel: string, args: any[]) {
addSenderFrameToEvent(event);
event._reply = (result: any) => event.sendReply({ result });
event._throw = (error: Error) => {
console.error(`Error occurred in handler for '${channel}':`, error);
event._replyChannel.sendReply({ error: error.toString() });
event.sendReply({ error: error.toString() });
};
const maybeWebFrame = getWebFrameForEvent(event);
const targets: (ElectronInternal.IpcMainInternal| undefined)[] = internal ? [ipcMainInternal] : [maybeWebFrame?.ipc, ipc, ipcMain];
const target = targets.find(target => target && (target as any)._invokeHandlers.has(channel));
if (target) {
const handler = (target as any)._invokeHandlers.get(channel);
try {
replyWithResult(await Promise.resolve(handler(event, ...args)));
} catch (err) {
replyWithError(err as Error);
}
(target as any)._invokeHandlers.get(channel)(event, ...args);
} else {
replyWithError(new Error(`No handler registered for '${channel}'`));
event._throw(`No handler registered for '${channel}'`);
}
});
this.on('-ipc-message-sync' as any, function (this: Electron.WebContents, event: Electron.IpcMainEvent, internal: boolean, channel: string, args: any[]) {
addSenderToEvent(event, this);
addSenderFrameToEvent(event);
addReturnValueToEvent(event);
if (internal) {
ipcMainInternal.emit(channel, event, ...args);
@@ -649,8 +637,8 @@ WebContents.prototype._init = function () {
}
});
this.on('-ipc-ports' as any, function (this: Electron.WebContents, event: Electron.IpcMainEvent, internal: boolean, channel: string, message: any, ports: any[]) {
addSenderToEvent(event, this);
this.on('-ipc-ports' as any, function (event: Electron.IpcMainEvent, internal: boolean, channel: string, message: any, ports: any[]) {
addSenderFrameToEvent(event);
event.ports = ports.map(p => new MessagePortMain(p));
const maybeWebFrame = getWebFrameForEvent(event);
maybeWebFrame && maybeWebFrame.ipc.emit(channel, event, message);
@@ -678,7 +666,7 @@ 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: Electron.Event, url: string, frameName: string, disposition: Electron.HandlerDetails['disposition'],
this.on('-new-window' as any, (event: ElectronInternal.Event, url: string, frameName: string, disposition: Electron.HandlerDetails['disposition'],
rawFeatures: string, referrer: Electron.Referrer, postData: PostData) => {
const postBody = postData ? {
data: postData,
@@ -704,7 +692,7 @@ WebContents.prototype._init = function () {
const options = result.browserWindowConstructorOptions;
if (!event.defaultPrevented) {
openGuestWindow({
embedder: this,
embedder: event.sender,
disposition,
referrer,
postData,
@@ -717,7 +705,7 @@ WebContents.prototype._init = function () {
let windowOpenOverriddenOptions: BrowserWindowConstructorOptions | null = null;
let windowOpenOutlivesOpenerOption: boolean = false;
this.on('-will-add-new-contents' as any, (event: Electron.Event, url: string, frameName: string, rawFeatures: string, disposition: Electron.HandlerDetails['disposition'], referrer: Electron.Referrer, postData: PostData) => {
this.on('-will-add-new-contents' as any, (event: ElectronInternal.Event, url: string, frameName: string, rawFeatures: string, disposition: Electron.HandlerDetails['disposition'], referrer: Electron.Referrer, postData: PostData) => {
const postBody = postData ? {
data: postData,
...parseContentTypeFormat(postData)
@@ -752,7 +740,7 @@ WebContents.prototype._init = function () {
} : undefined;
const { webPreferences: parsedWebPreferences } = parseFeatures(rawFeatures);
const webPreferences = makeWebPreferences({
embedder: this,
embedder: event.sender,
insecureParsedWebPreferences: parsedWebPreferences,
secureOverrideWebPreferences
});
@@ -765,7 +753,7 @@ WebContents.prototype._init = function () {
});
// Create a new browser window for "window.open"
this.on('-add-new-contents' as any, (event: Electron.Event, webContents: Electron.WebContents, disposition: string,
this.on('-add-new-contents' as any, (event: ElectronInternal.Event, webContents: Electron.WebContents, disposition: string,
_userGesture: boolean, _left: number, _top: number, _width: number, _height: number, url: string, frameName: string,
referrer: Electron.Referrer, rawFeatures: string, postData: PostData) => {
const overriddenOptions = windowOpenOverriddenOptions || undefined;
@@ -781,7 +769,7 @@ WebContents.prototype._init = function () {
}
openGuestWindow({
embedder: this,
embedder: event.sender,
guest: webContents,
overrideBrowserWindowOptions: overriddenOptions,
disposition,
@@ -818,7 +806,8 @@ WebContents.prototype._init = function () {
}
});
app.emit('web-contents-created', { sender: this, preventDefault () {}, get defaultPrevented () { return false; } }, this);
const event = process._linkedBinding('electron_browser_event').createEmpty();
app.emit('web-contents-created', event, this);
// Properties

View File

@@ -14,6 +14,7 @@ interface GuestInstance {
}
const webViewManager = process._linkedBinding('electron_browser_web_view_manager');
const eventBinding = process._linkedBinding('electron_browser_event');
const netBinding = process._linkedBinding('electron_browser_net');
const supportedWebViewEvents = Object.keys(webViewEvents);
@@ -81,13 +82,7 @@ function makeLoadURLOptions (params: Record<string, any>) {
// Create a new guest instance.
const createGuest = function (embedder: Electron.WebContents, embedderFrameId: number, elementInstanceId: number, params: Record<string, any>) {
const webPreferences = makeWebPreferences(embedder, params);
const event = {
sender: embedder,
preventDefault () {
this.defaultPrevented = true;
},
defaultPrevented: false
};
const event = eventBinding.createWithSender(embedder);
const { instanceId } = params;
@@ -163,16 +158,6 @@ const createGuest = function (embedder: Electron.WebContents, embedderFrameId: n
});
});
// Dispatch guest's frame navigation event to embedder.
guest.on('will-frame-navigate', function (event: Electron.WebContentsWillFrameNavigateEventParams) {
sendToEmbedder(IPC_MESSAGES.GUEST_VIEW_INTERNAL_DISPATCH_EVENT, 'will-frame-navigate', {
url: event.url,
isMainFrame: event.isMainFrame,
frameProcessId: event.frame.processId,
frameRoutingId: event.frame.routingId
});
});
// Notify guest of embedder window visibility when it is ready
// FIXME Remove once https://github.com/electron/electron/issues/6828 is fixed
guest.on('dom-ready', function () {

View File

@@ -18,7 +18,13 @@ export class IpcMainImpl extends EventEmitter {
if (typeof fn !== 'function') {
throw new Error(`Expected handler to be a function, but found type '${typeof fn}'`);
}
this._invokeHandlers.set(method, fn);
this._invokeHandlers.set(method, async (e, ...args) => {
try {
e._reply(await Promise.resolve(fn(e, ...args)));
} catch (err) {
e._throw(err as Error);
}
});
}
handleOnce: Electron.IpcMain['handleOnce'] = (method, fn) => {

View File

@@ -31,15 +31,11 @@ export const syncMethods = new Set([
'redo',
'cut',
'copy',
'centerSelection',
'paste',
'pasteAndMatchStyle',
'delete',
'selectAll',
'unselect',
'scrollToTop',
'scrollToBottom',
'adjustSelection',
'replace',
'replaceMisspelling',
'findInPage',

View File

@@ -17,13 +17,13 @@ const isWebView = mainFrame.getWebPreference('isWebView');
// ElectronApiServiceImpl will look for the "ipcNative" hidden object when
// invoking the 'onMessage' callback.
v8Util.setHiddenValue(global, 'ipcNative', {
onMessage (internal: boolean, channel: string, ports: MessagePort[], args: any[], senderId: number, senderIsMainFrame: boolean) {
onMessage (internal: boolean, channel: string, ports: MessagePort[], args: any[], senderId: number) {
if (internal && senderId !== 0) {
console.error(`Message ${channel} sent by unexpected WebContents (${senderId})`);
return;
}
const sender = internal ? ipcRendererInternal : ipcRenderer;
sender.emit(channel, { sender, senderId, ...(senderId ? { senderIsMainFrame } : {}), ports }, ...args);
sender.emit(channel, { sender, senderId, ports }, ...args);
}
});

View File

@@ -6,11 +6,11 @@
"devDependencies": {
"@azure/storage-blob": "^12.9.0",
"@electron/asar": "^3.2.1",
"@electron/docs-parser": "^1.1.0",
"@electron/docs-parser": "^1.0.0",
"@electron/fiddle-core": "^1.0.4",
"@electron/github-app-auth": "^2.0.0",
"@electron/lint-roller": "^1.5.0",
"@electron/typescript-definitions": "^8.14.0",
"@electron/typescript-definitions": "^8.10.0",
"@octokit/rest": "^19.0.7",
"@primer/octicons": "^10.0.0",
"@types/basic-auth": "^1.1.3",
@@ -73,7 +73,7 @@
"ts-loader": "^8.0.2",
"ts-node": "6.2.0",
"typescript": "^4.5.5",
"webpack": "^5.76.0",
"webpack": "^5.73.0",
"webpack-cli": "^4.10.0",
"wrapper-webpack-plugin": "^2.2.0"
},

View File

@@ -1,6 +1 @@
cherry-pick-d0ee0197ddff.patch
cherry-pick-285c7712c506.patch
cherry-pick-2bf945775fe6.patch
cherry-pick-cafe56b591ed.patch
cherry-pick-5486190be556.patch
cherry-pick-e4669a74888d.patch
fix_rename_webswapcgllayer_to_webswapcgllayerchromium.patch

View File

@@ -1,153 +0,0 @@
From 285c7712c50654e3d7238b059c4631bc91285514 Mon Sep 17 00:00:00 2001
From: Shahbaz Youssefi <syoussefi@chromium.org>
Date: Thu, 13 Jul 2023 15:23:49 -0400
Subject: [PATCH] M116: Translator: Unconditionally limit variable sizes
... instead of just for WebGL. This is to avoid hitting driver bugs
that were prevented with this check for WebGL on a compromised renderer
that can create non-WebGL contexts.
Bug: chromium:1464682
Change-Id: I2b1c5a8c51f06225f5f850109d30778d97e574c7
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/4717371
Reviewed-by: Roman Lavrov <romanl@google.com>
---
diff --git a/src/compiler/translator/Compiler.cpp b/src/compiler/translator/Compiler.cpp
index 7b1ac4e..383feeb 100644
--- a/src/compiler/translator/Compiler.cpp
+++ b/src/compiler/translator/Compiler.cpp
@@ -397,9 +397,10 @@
bool TCompiler::shouldLimitTypeSizes() const
{
- // WebGL shaders limit the size of variables' types in shaders,
- // including arrays, structs and interface blocks.
- return IsWebGLBasedSpec(mShaderSpec);
+ // Prevent unrealistically large variable sizes in shaders. This works around driver bugs
+ // around int-size limits (such as 2GB). The limits are generously large enough that no real
+ // shader should ever hit it.
+ return true;
}
bool TCompiler::Init(const ShBuiltInResources &resources)
diff --git a/src/compiler/translator/ValidateTypeSizeLimitations.cpp b/src/compiler/translator/ValidateTypeSizeLimitations.cpp
index 2a033ad..19a4821 100644
--- a/src/compiler/translator/ValidateTypeSizeLimitations.cpp
+++ b/src/compiler/translator/ValidateTypeSizeLimitations.cpp
@@ -23,10 +23,10 @@
// Arbitrarily enforce that all types declared with a size in bytes of over 2 GB will cause
// compilation failure.
//
-// For local and global variables, the limit is much lower (1MB) as that much memory won't fit in
+// For local and global variables, the limit is much lower (16MB) as that much memory won't fit in
// the GPU registers anyway.
constexpr size_t kMaxVariableSizeInBytes = static_cast<size_t>(2) * 1024 * 1024 * 1024;
-constexpr size_t kMaxPrivateVariableSizeInBytes = static_cast<size_t>(1) * 1024 * 1024;
+constexpr size_t kMaxPrivateVariableSizeInBytes = static_cast<size_t>(16) * 1024 * 1024;
// Traverses intermediate tree to ensure that the shader does not
// exceed certain implementation-defined limits on the sizes of types.
diff --git a/src/compiler/translator/util.cpp b/src/compiler/translator/util.cpp
index a91f8b0..a866b25 100644
--- a/src/compiler/translator/util.cpp
+++ b/src/compiler/translator/util.cpp
@@ -282,6 +282,9 @@
return kBoolGLType[type.getNominalSize() - 1];
+ case EbtYuvCscStandardEXT:
+ return GL_UNSIGNED_INT;
+
case EbtSampler2D:
return GL_SAMPLER_2D;
case EbtSampler3D:
diff --git a/src/tests/gl_tests/WebGLCompatibilityTest.cpp b/src/tests/gl_tests/WebGLCompatibilityTest.cpp
index 9ae56f5..a8d2ce4 100644
--- a/src/tests/gl_tests/WebGLCompatibilityTest.cpp
+++ b/src/tests/gl_tests/WebGLCompatibilityTest.cpp
@@ -5284,8 +5284,8 @@
constexpr char kVSArrayTooLarge[] =
R"(varying vec4 color;
-// 1 MB / 32 aligned bytes per mat2 = 32768
-const int array_size = 32769;
+// 16 MB / 32 aligned bytes per mat2 = 524288
+const int array_size = 524289;
void main()
{
mat2 array[array_size];
@@ -5297,7 +5297,7 @@
constexpr char kVSArrayMuchTooLarge[] =
R"(varying vec4 color;
-const int array_size = 55600;
+const int array_size = 757000;
void main()
{
mat2 array[array_size];
@@ -5361,9 +5361,9 @@
constexpr char kTooLargeGlobalMemory1[] =
R"(precision mediump float;
-// 1 MB / 16 bytes per vec4 = 65536
-vec4 array[32768];
-vec4 array2[32769];
+// 16 MB / 16 bytes per vec4 = 1048576
+vec4 array[524288];
+vec4 array2[524289];
void main()
{
@@ -5376,9 +5376,9 @@
constexpr char kTooLargeGlobalMemory2[] =
R"(precision mediump float;
-// 1 MB / 16 bytes per vec4 = 65536
-vec4 array[32767];
-vec4 array2[32767];
+// 16 MB / 16 bytes per vec4 = 1048576
+vec4 array[524287];
+vec4 array2[524287];
vec4 x, y, z;
void main()
@@ -5392,12 +5392,12 @@
constexpr char kTooLargeGlobalAndLocalMemory1[] =
R"(precision mediump float;
-// 1 MB / 16 bytes per vec4 = 65536
-vec4 array[32768];
+// 16 MB / 16 bytes per vec4 = 1048576
+vec4 array[524288];
void main()
{
- vec4 array2[32769];
+ vec4 array2[524289];
if (array[0].x + array[1].x == 2.0)
gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);
else
@@ -5408,18 +5408,18 @@
constexpr char kTooLargeGlobalAndLocalMemory2[] =
R"(precision mediump float;
-// 1 MB / 16 bytes per vec4 = 65536
-vec4 array[32768];
+// 16 MB / 16 bytes per vec4 = 1048576
+vec4 array[524288];
float f()
{
- vec4 array2[16384];
+ vec4 array2[524288];
return array2[0].x;
}
float g()
{
- vec4 array3[16383];
+ vec4 array3[524287];
return array3[0].x;
}

View File

@@ -1,197 +0,0 @@
From 2bf945775fe634eb9e420c2263dae6043bbb5ece Mon Sep 17 00:00:00 2001
From: Shahbaz Youssefi <syoussefi@chromium.org>
Date: Fri, 14 Jul 2023 12:30:15 -0400
Subject: [PATCH] M116: Translator: Limit variable sizes vs uint overflow
Bug: chromium:1464680
Change-Id: Iee41a2da7a7a330e6cc4d6da59a6e9836ee9dd36
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/4717372
Reviewed-by: Roman Lavrov <romanl@google.com>
---
diff --git a/src/compiler/translator/ValidateTypeSizeLimitations.cpp b/src/compiler/translator/ValidateTypeSizeLimitations.cpp
index 19a4821..f0ff9cb 100644
--- a/src/compiler/translator/ValidateTypeSizeLimitations.cpp
+++ b/src/compiler/translator/ValidateTypeSizeLimitations.cpp
@@ -7,6 +7,7 @@
#include "compiler/translator/ValidateTypeSizeLimitations.h"
#include "angle_gl.h"
+#include "common/mathutil.h"
#include "compiler/translator/Diagnostics.h"
#include "compiler/translator/Symbol.h"
#include "compiler/translator/SymbolTable.h"
@@ -113,7 +114,8 @@
void validateTotalPrivateVariableSize()
{
- if (mTotalPrivateVariablesSize > kMaxPrivateVariableSizeInBytes)
+ if (mTotalPrivateVariablesSize.ValueOrDefault(std::numeric_limits<size_t>::max()) >
+ kMaxPrivateVariableSizeInBytes)
{
mDiagnostics->error(
TSourceLoc{},
@@ -231,7 +233,7 @@
TDiagnostics *mDiagnostics;
std::vector<int> mLoopSymbolIds;
- size_t mTotalPrivateVariablesSize;
+ angle::base::CheckedNumeric<size_t> mTotalPrivateVariablesSize;
};
} // namespace
diff --git a/src/tests/gl_tests/WebGLCompatibilityTest.cpp b/src/tests/gl_tests/WebGLCompatibilityTest.cpp
index a8d2ce4..542d49f 100644
--- a/src/tests/gl_tests/WebGLCompatibilityTest.cpp
+++ b/src/tests/gl_tests/WebGLCompatibilityTest.cpp
@@ -5426,7 +5426,7 @@
float h()
{
vec4 value;
- float value2
+ float value2;
return value.x + value2;
}
@@ -5438,6 +5438,131 @@
gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
})";
+ constexpr char kTooLargeGlobalMemoryOverflow[] =
+ R"(precision mediump float;
+
+// 16 MB / 16 bytes per vec4 = 1048576
+// Create 256 arrays so each is small, but the total overflows a 32-bit number
+vec4 array[1048576], array2[1048576], array3[1048576], array4[1048576], array5[1048576];
+vec4 array6[1048576], array7[1048576], array8[1048576], array9[1048576], array10[1048576];
+vec4 array11[1048576], array12[1048576], array13[1048576], array14[1048576], array15[1048576];
+vec4 array16[1048576], array17[1048576], array18[1048576], array19[1048576], array20[1048576];
+vec4 array21[1048576], array22[1048576], array23[1048576], array24[1048576], array25[1048576];
+vec4 array26[1048576], array27[1048576], array28[1048576], array29[1048576], array30[1048576];
+vec4 array31[1048576], array32[1048576], array33[1048576], array34[1048576], array35[1048576];
+vec4 array36[1048576], array37[1048576], array38[1048576], array39[1048576], array40[1048576];
+vec4 array41[1048576], array42[1048576], array43[1048576], array44[1048576], array45[1048576];
+vec4 array46[1048576], array47[1048576], array48[1048576], array49[1048576], array50[1048576];
+vec4 array51[1048576], array52[1048576], array53[1048576], array54[1048576], array55[1048576];
+vec4 array56[1048576], array57[1048576], array58[1048576], array59[1048576], array60[1048576];
+vec4 array61[1048576], array62[1048576], array63[1048576], array64[1048576], array65[1048576];
+vec4 array66[1048576], array67[1048576], array68[1048576], array69[1048576], array70[1048576];
+vec4 array71[1048576], array72[1048576], array73[1048576], array74[1048576], array75[1048576];
+vec4 array76[1048576], array77[1048576], array78[1048576], array79[1048576], array80[1048576];
+vec4 array81[1048576], array82[1048576], array83[1048576], array84[1048576], array85[1048576];
+vec4 array86[1048576], array87[1048576], array88[1048576], array89[1048576], array90[1048576];
+vec4 array91[1048576], array92[1048576], array93[1048576], array94[1048576], array95[1048576];
+vec4 array96[1048576], array97[1048576], array98[1048576], array99[1048576], array100[1048576];
+vec4 array101[1048576], array102[1048576], array103[1048576], array104[1048576], array105[1048576];
+vec4 array106[1048576], array107[1048576], array108[1048576], array109[1048576], array110[1048576];
+vec4 array111[1048576], array112[1048576], array113[1048576], array114[1048576], array115[1048576];
+vec4 array116[1048576], array117[1048576], array118[1048576], array119[1048576], array120[1048576];
+vec4 array121[1048576], array122[1048576], array123[1048576], array124[1048576], array125[1048576];
+vec4 array126[1048576], array127[1048576], array128[1048576], array129[1048576], array130[1048576];
+vec4 array131[1048576], array132[1048576], array133[1048576], array134[1048576], array135[1048576];
+vec4 array136[1048576], array137[1048576], array138[1048576], array139[1048576], array140[1048576];
+vec4 array141[1048576], array142[1048576], array143[1048576], array144[1048576], array145[1048576];
+vec4 array146[1048576], array147[1048576], array148[1048576], array149[1048576], array150[1048576];
+vec4 array151[1048576], array152[1048576], array153[1048576], array154[1048576], array155[1048576];
+vec4 array156[1048576], array157[1048576], array158[1048576], array159[1048576], array160[1048576];
+vec4 array161[1048576], array162[1048576], array163[1048576], array164[1048576], array165[1048576];
+vec4 array166[1048576], array167[1048576], array168[1048576], array169[1048576], array170[1048576];
+vec4 array171[1048576], array172[1048576], array173[1048576], array174[1048576], array175[1048576];
+vec4 array176[1048576], array177[1048576], array178[1048576], array179[1048576], array180[1048576];
+vec4 array181[1048576], array182[1048576], array183[1048576], array184[1048576], array185[1048576];
+vec4 array186[1048576], array187[1048576], array188[1048576], array189[1048576], array190[1048576];
+vec4 array191[1048576], array192[1048576], array193[1048576], array194[1048576], array195[1048576];
+vec4 array196[1048576], array197[1048576], array198[1048576], array199[1048576], array200[1048576];
+vec4 array201[1048576], array202[1048576], array203[1048576], array204[1048576], array205[1048576];
+vec4 array206[1048576], array207[1048576], array208[1048576], array209[1048576], array210[1048576];
+vec4 array211[1048576], array212[1048576], array213[1048576], array214[1048576], array215[1048576];
+vec4 array216[1048576], array217[1048576], array218[1048576], array219[1048576], array220[1048576];
+vec4 array221[1048576], array222[1048576], array223[1048576], array224[1048576], array225[1048576];
+vec4 array226[1048576], array227[1048576], array228[1048576], array229[1048576], array230[1048576];
+vec4 array231[1048576], array232[1048576], array233[1048576], array234[1048576], array235[1048576];
+vec4 array236[1048576], array237[1048576], array238[1048576], array239[1048576], array240[1048576];
+vec4 array241[1048576], array242[1048576], array243[1048576], array244[1048576], array245[1048576];
+vec4 array246[1048576], array247[1048576], array248[1048576], array249[1048576], array250[1048576];
+vec4 array251[1048576], array252[1048576], array253[1048576], array254[1048576], array255[1048576];
+vec4 array256[1048576];
+
+void main()
+{
+ float f = array[0].x; f += array2[0].x; f += array3[0].x; f += array4[0].x; f += array5[0].x;
+ f += array6[0].x; f += array7[0].x; f += array8[0].x; f += array9[0].x; f += array10[0].x;
+ f += array11[0].x; f += array12[0].x; f += array13[0].x; f += array14[0].x; f += array15[0].x;
+ f += array16[0].x; f += array17[0].x; f += array18[0].x; f += array19[0].x; f += array20[0].x;
+ f += array21[0].x; f += array22[0].x; f += array23[0].x; f += array24[0].x; f += array25[0].x;
+ f += array26[0].x; f += array27[0].x; f += array28[0].x; f += array29[0].x; f += array30[0].x;
+ f += array31[0].x; f += array32[0].x; f += array33[0].x; f += array34[0].x; f += array35[0].x;
+ f += array36[0].x; f += array37[0].x; f += array38[0].x; f += array39[0].x; f += array40[0].x;
+ f += array41[0].x; f += array42[0].x; f += array43[0].x; f += array44[0].x; f += array45[0].x;
+ f += array46[0].x; f += array47[0].x; f += array48[0].x; f += array49[0].x; f += array50[0].x;
+ f += array51[0].x; f += array52[0].x; f += array53[0].x; f += array54[0].x; f += array55[0].x;
+ f += array56[0].x; f += array57[0].x; f += array58[0].x; f += array59[0].x; f += array60[0].x;
+ f += array61[0].x; f += array62[0].x; f += array63[0].x; f += array64[0].x; f += array65[0].x;
+ f += array66[0].x; f += array67[0].x; f += array68[0].x; f += array69[0].x; f += array70[0].x;
+ f += array71[0].x; f += array72[0].x; f += array73[0].x; f += array74[0].x; f += array75[0].x;
+ f += array76[0].x; f += array77[0].x; f += array78[0].x; f += array79[0].x; f += array80[0].x;
+ f += array81[0].x; f += array82[0].x; f += array83[0].x; f += array84[0].x; f += array85[0].x;
+ f += array86[0].x; f += array87[0].x; f += array88[0].x; f += array89[0].x; f += array90[0].x;
+ f += array91[0].x; f += array92[0].x; f += array93[0].x; f += array94[0].x; f += array95[0].x;
+ f += array96[0].x; f += array97[0].x; f += array98[0].x; f += array99[0].x; f += array100[0].x;
+ f += array101[0].x; f += array102[0].x; f += array103[0].x; f += array104[0].x;
+ f += array105[0].x; f += array106[0].x; f += array107[0].x; f += array108[0].x;
+ f += array109[0].x; f += array110[0].x; f += array111[0].x; f += array112[0].x;
+ f += array113[0].x; f += array114[0].x; f += array115[0].x; f += array116[0].x;
+ f += array117[0].x; f += array118[0].x; f += array119[0].x; f += array120[0].x;
+ f += array121[0].x; f += array122[0].x; f += array123[0].x; f += array124[0].x;
+ f += array125[0].x; f += array126[0].x; f += array127[0].x; f += array128[0].x;
+ f += array129[0].x; f += array130[0].x; f += array131[0].x; f += array132[0].x;
+ f += array133[0].x; f += array134[0].x; f += array135[0].x; f += array136[0].x;
+ f += array137[0].x; f += array138[0].x; f += array139[0].x; f += array140[0].x;
+ f += array141[0].x; f += array142[0].x; f += array143[0].x; f += array144[0].x;
+ f += array145[0].x; f += array146[0].x; f += array147[0].x; f += array148[0].x;
+ f += array149[0].x; f += array150[0].x; f += array151[0].x; f += array152[0].x;
+ f += array153[0].x; f += array154[0].x; f += array155[0].x; f += array156[0].x;
+ f += array157[0].x; f += array158[0].x; f += array159[0].x; f += array160[0].x;
+ f += array161[0].x; f += array162[0].x; f += array163[0].x; f += array164[0].x;
+ f += array165[0].x; f += array166[0].x; f += array167[0].x; f += array168[0].x;
+ f += array169[0].x; f += array170[0].x; f += array171[0].x; f += array172[0].x;
+ f += array173[0].x; f += array174[0].x; f += array175[0].x; f += array176[0].x;
+ f += array177[0].x; f += array178[0].x; f += array179[0].x; f += array180[0].x;
+ f += array181[0].x; f += array182[0].x; f += array183[0].x; f += array184[0].x;
+ f += array185[0].x; f += array186[0].x; f += array187[0].x; f += array188[0].x;
+ f += array189[0].x; f += array190[0].x; f += array191[0].x; f += array192[0].x;
+ f += array193[0].x; f += array194[0].x; f += array195[0].x; f += array196[0].x;
+ f += array197[0].x; f += array198[0].x; f += array199[0].x; f += array200[0].x;
+ f += array201[0].x; f += array202[0].x; f += array203[0].x; f += array204[0].x;
+ f += array205[0].x; f += array206[0].x; f += array207[0].x; f += array208[0].x;
+ f += array209[0].x; f += array210[0].x; f += array211[0].x; f += array212[0].x;
+ f += array213[0].x; f += array214[0].x; f += array215[0].x; f += array216[0].x;
+ f += array217[0].x; f += array218[0].x; f += array219[0].x; f += array220[0].x;
+ f += array221[0].x; f += array222[0].x; f += array223[0].x; f += array224[0].x;
+ f += array225[0].x; f += array226[0].x; f += array227[0].x; f += array228[0].x;
+ f += array229[0].x; f += array230[0].x; f += array231[0].x; f += array232[0].x;
+ f += array233[0].x; f += array234[0].x; f += array235[0].x; f += array236[0].x;
+ f += array237[0].x; f += array238[0].x; f += array239[0].x; f += array240[0].x;
+ f += array241[0].x; f += array242[0].x; f += array243[0].x; f += array244[0].x;
+ f += array245[0].x; f += array246[0].x; f += array247[0].x; f += array248[0].x;
+ f += array249[0].x; f += array250[0].x; f += array251[0].x; f += array252[0].x;
+ f += array253[0].x; f += array254[0].x; f += array255[0].x; f += array256[0].x;
+ if (f == 2.0)
+ gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);
+ else
+ gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
+})";
+
GLuint program = CompileProgram(essl1_shaders::vs::Simple(), kTooLargeGlobalMemory1);
EXPECT_EQ(0u, program);
@@ -5449,6 +5574,9 @@
program = CompileProgram(essl1_shaders::vs::Simple(), kTooLargeGlobalAndLocalMemory2);
EXPECT_EQ(0u, program);
+
+ program = CompileProgram(essl1_shaders::vs::Simple(), kTooLargeGlobalMemoryOverflow);
+ EXPECT_EQ(0u, program);
}
// Linking should fail when corresponding vertex/fragment uniform blocks have different precision

View File

@@ -1,42 +0,0 @@
From 5486190be5565f9b5567fbd252a10425af3d59ee Mon Sep 17 00:00:00 2001
From: Geoff Lang <geofflang@chromium.org>
Date: Fri, 21 Jul 2023 13:45:52 -0400
Subject: [PATCH] [M114-LTS] Fix read size validation for RGBX formats.
GL_RGBX8_ANGLE is the only format where the upload format is 3-channel
RGB, whilethe download format is 4-channel RGBX. As such, the internal
format corresponding to format+type expects 3-byte input/output. The
format is fixed here for readPixels to output 4 bytes per pixel.
Bug: chromium:1458046
Change-Id: Iec737ed64bade003cfab50dc5f595eb4875e81e4
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/4706957
Commit-Queue: Shahbaz Youssefi <syoussefi@chromium.org>
(cherry picked from commit 430a4f559cbc2bcd5d026e8b36ee46ddd80e9651)
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/4765136
Commit-Queue: Daniel Yip <danielyip@google.com>
Auto-Submit: Daniel Yip <danielyip@google.com>
(cherry picked from commit 4a372ad49ceddea6c13f79adb212a777ec770a66)
---
diff --git a/src/libANGLE/formatutils.cpp b/src/libANGLE/formatutils.cpp
index f2845dc..bb1389aaa 100644
--- a/src/libANGLE/formatutils.cpp
+++ b/src/libANGLE/formatutils.cpp
@@ -1702,7 +1702,15 @@
GLuint InternalFormat::computePixelBytes(GLenum formatType) const
{
const auto &typeInfo = GetTypeInfo(formatType);
- GLuint components = typeInfo.specialInterpretation ? 1u : componentCount;
+ GLuint components = componentCount;
+ if (sizedInternalFormat == GL_RGBX8_ANGLE)
+ {
+ components = 4;
+ }
+ else if (typeInfo.specialInterpretation)
+ {
+ components = 1;
+ }
return components * typeInfo.bytes;
}

View File

@@ -1,286 +0,0 @@
From cafe56b591edb77f041be70b58cac3a61565644a Mon Sep 17 00:00:00 2001
From: Geoff Lang <geofflang@chromium.org>
Date: Fri, 23 Jun 2023 14:46:28 -0400
Subject: [PATCH] M116: GL: Ensure all instanced attributes have a buffer with data
Apple OpenGL drivers sometimes crash when given an instanced draw with
a buffer that has never been given data.
It's not efficient to check if the attribute is both zero-sized and
instanced so just ensure that every time a zero-sized buffer is bound
to an attribute, it gets initialized with some data.
Bug: chromium:1456243
Change-Id: I66b7c7017843153db2df3bc50010cba765d03c5f
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/4642048
Commit-Queue: Geoff Lang <geofflang@chromium.org>
Reviewed-by: Shahbaz Youssefi <syoussefi@chromium.org>
(cherry picked from commit 4e6124dae892690204f8e5996aeaad14f45e0a97)
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/4727452
---
diff --git a/include/platform/FeaturesGL_autogen.h b/include/platform/FeaturesGL_autogen.h
index aa0565c..2f6e094 100644
--- a/include/platform/FeaturesGL_autogen.h
+++ b/include/platform/FeaturesGL_autogen.h
@@ -501,6 +501,12 @@
"supportsShaderPixelLocalStorageEXT", FeatureCategory::OpenGLFeatures,
"Backend GL context supports EXT_shader_pixel_local_storage extension", &members,
"http://anglebug.com/7279"};
+
+ FeatureInfo ensureNonEmptyBufferIsBoundForDraw = {
+ "ensureNonEmptyBufferIsBoundForDraw", FeatureCategory::OpenGLFeatures,
+ "Apple OpenGL drivers crash when drawing with a zero-sized buffer bound using a non-zero "
+ "divisor.",
+ &members, "http://crbug.com/1456243"};
};
inline FeaturesGL::FeaturesGL() = default;
diff --git a/include/platform/gl_features.json b/include/platform/gl_features.json
index 032f29a..b358cea 100644
--- a/include/platform/gl_features.json
+++ b/include/platform/gl_features.json
@@ -699,6 +699,14 @@
"Backend GL context supports EXT_shader_pixel_local_storage extension"
],
"issue": "http://anglebug.com/7279"
+ },
+ {
+ "name": "ensure_non_empty_buffer_is_bound_for_draw",
+ "category": "Features",
+ "description": [
+ "Apple OpenGL drivers crash when drawing with a zero-sized buffer bound using a non-zero divisor."
+ ],
+ "issue": "http://crbug.com/1456243"
}
]
}
diff --git a/scripts/code_generation_hashes/ANGLE_features.json b/scripts/code_generation_hashes/ANGLE_features.json
index d4576c2..503001c 100644
--- a/scripts/code_generation_hashes/ANGLE_features.json
+++ b/scripts/code_generation_hashes/ANGLE_features.json
@@ -2,7 +2,7 @@
"include/platform/FeaturesD3D_autogen.h":
"9923fb44d0a6f31948d0c8f46ee1d9e2",
"include/platform/FeaturesGL_autogen.h":
- "a795a806d71b0e6d1f9e6d95c6e11971",
+ "fef16ab3946346a2a7d5b76bb39471a4",
"include/platform/FeaturesMtl_autogen.h":
"407426c8874de9295482ace9c94bd812",
"include/platform/FeaturesVk_autogen.h":
@@ -16,13 +16,13 @@
"include/platform/gen_features.py":
"062989f7a8f3ff3b383f98fc8908dc33",
"include/platform/gl_features.json":
- "3335055a70e35ebb7bf74c6d7c58897b",
+ "c9aead89696e7fd0c8bfe5c5ca85ca63",
"include/platform/mtl_features.json":
"c66d170e7a8eb3448030f4c423ed0133",
"include/platform/vk_features.json":
"416bbb28b9fa1a3c4ef141f243c0a9e6",
"util/angle_features_autogen.cpp":
- "73169f63c755192c3b4bd27d6f4096ca",
+ "288daaec490eb816883d744f108d74c9",
"util/angle_features_autogen.h":
- "7aa8120eb8f8fd335946b8c27074745d"
+ "daf25d3e4ffea143d1c082416513f7e7"
}
\ No newline at end of file
diff --git a/src/libANGLE/renderer/gl/BufferGL.cpp b/src/libANGLE/renderer/gl/BufferGL.cpp
index c99fd5d..9651838 100644
--- a/src/libANGLE/renderer/gl/BufferGL.cpp
+++ b/src/libANGLE/renderer/gl/BufferGL.cpp
@@ -296,6 +296,11 @@
return angle::Result::Continue;
}
+size_t BufferGL::getBufferSize() const
+{
+ return mBufferSize;
+}
+
GLuint BufferGL::getBufferID() const
{
return mBufferID;
diff --git a/src/libANGLE/renderer/gl/BufferGL.h b/src/libANGLE/renderer/gl/BufferGL.h
index 7b57594..fe9138e 100644
--- a/src/libANGLE/renderer/gl/BufferGL.h
+++ b/src/libANGLE/renderer/gl/BufferGL.h
@@ -56,6 +56,7 @@
bool primitiveRestartEnabled,
gl::IndexRange *outRange) override;
+ size_t getBufferSize() const;
GLuint getBufferID() const;
private:
diff --git a/src/libANGLE/renderer/gl/VertexArrayGL.cpp b/src/libANGLE/renderer/gl/VertexArrayGL.cpp
index dc981de..fda9099 100644
--- a/src/libANGLE/renderer/gl/VertexArrayGL.cpp
+++ b/src/libANGLE/renderer/gl/VertexArrayGL.cpp
@@ -646,6 +646,7 @@
angle::Result VertexArrayGL::updateAttribPointer(const gl::Context *context, size_t attribIndex)
{
+ const angle::FeaturesGL &features = GetFeaturesGL(context);
const VertexAttribute &attrib = mState.getVertexAttribute(attribIndex);
@@ -687,8 +688,16 @@
// is not NULL.
StateManagerGL *stateManager = GetStateManagerGL(context);
- GLuint bufferId = GetNativeBufferID(arrayBuffer);
+ BufferGL *bufferGL = GetImplAs<BufferGL>(arrayBuffer);
+ GLuint bufferId = bufferGL->getBufferID();
stateManager->bindBuffer(gl::BufferBinding::Array, bufferId);
+ if (features.ensureNonEmptyBufferIsBoundForDraw.enabled && bufferGL->getBufferSize() == 0)
+ {
+ constexpr uint32_t data = 0;
+ ANGLE_TRY(bufferGL->setData(context, gl::BufferBinding::Array, &data, sizeof(data),
+ gl::BufferUsage::StaticDraw));
+ ASSERT(bufferGL->getBufferSize() > 0);
+ }
ANGLE_TRY(callVertexAttribPointer(context, static_cast<GLuint>(attribIndex), attrib,
binding.getStride(), binding.getOffset()));
diff --git a/src/libANGLE/renderer/gl/renderergl_utils.cpp b/src/libANGLE/renderer/gl/renderergl_utils.cpp
index 6911247..ab2a608 100644
--- a/src/libANGLE/renderer/gl/renderergl_utils.cpp
+++ b/src/libANGLE/renderer/gl/renderergl_utils.cpp
@@ -2465,6 +2465,9 @@
// EXT_shader_pixel_local_storage
ANGLE_FEATURE_CONDITION(features, supportsShaderPixelLocalStorageEXT,
functions->hasGLESExtension("GL_EXT_shader_pixel_local_storage"));
+
+ // http://crbug.com/1456243
+ ANGLE_FEATURE_CONDITION(features, ensureNonEmptyBufferIsBoundForDraw, IsApple() || IsAndroid());
}
void InitializeFrontendFeatures(const FunctionsGL *functions, angle::FrontendFeatures *features)
diff --git a/src/tests/angle_end2end_tests_expectations.txt b/src/tests/angle_end2end_tests_expectations.txt
index 59ec7c2..44ff3e4 100644
--- a/src/tests/angle_end2end_tests_expectations.txt
+++ b/src/tests/angle_end2end_tests_expectations.txt
@@ -380,6 +380,7 @@
7294 WIN D3D11 : StateChangeTestES3.StencilWriteMask/* = SKIP
7316 WIN D3D11 : StateChangeTestES3.StencilTestAndFunc/* = SKIP
7329 WIN D3D11 : StateChangeTestES3.PrimitiveRestart/* = SKIP
+1456243 WIN D3D11 : WebGL2CompatibilityTest.DrawWithZeroSizedBuffer/* = SKIP
// Android
6095 ANDROID GLES : GLSLTest_ES3.InitGlobalComplexConstant/* = SKIP
diff --git a/src/tests/gl_tests/WebGLCompatibilityTest.cpp b/src/tests/gl_tests/WebGLCompatibilityTest.cpp
index 7dc56cd..bd7ecd1 100644
--- a/src/tests/gl_tests/WebGLCompatibilityTest.cpp
+++ b/src/tests/gl_tests/WebGLCompatibilityTest.cpp
@@ -1632,10 +1632,10 @@
constexpr GLuint kMaxIntAsGLuint = static_cast<GLuint>(std::numeric_limits<GLint>::max());
constexpr GLuint kIndexData[] = {
- kMaxIntAsGLuint,
- kMaxIntAsGLuint + 1,
- kMaxIntAsGLuint + 2,
- kMaxIntAsGLuint + 3,
+ kMaxIntAsGLuint,
+ kMaxIntAsGLuint + 1,
+ kMaxIntAsGLuint + 2,
+ kMaxIntAsGLuint + 3,
};
GLBuffer indexBuffer;
@@ -3687,8 +3687,8 @@
constexpr float readPixelsData[] = {-5000.0f, 0.0f, 0.0f, 1.0f};
const GLushort textureData[] = {
- gl::float32ToFloat16(readPixelsData[0]), gl::float32ToFloat16(readPixelsData[1]),
- gl::float32ToFloat16(readPixelsData[2]), gl::float32ToFloat16(readPixelsData[3])};
+ gl::float32ToFloat16(readPixelsData[0]), gl::float32ToFloat16(readPixelsData[1]),
+ gl::float32ToFloat16(readPixelsData[2]), gl::float32ToFloat16(readPixelsData[3])};
for (auto extension : FloatingPointTextureExtensions)
{
@@ -3748,8 +3748,8 @@
constexpr float readPixelsData[] = {7108.0f, -10.0f, 0.0f, 1.0f};
const GLushort textureData[] = {
- gl::float32ToFloat16(readPixelsData[0]), gl::float32ToFloat16(readPixelsData[1]),
- gl::float32ToFloat16(readPixelsData[2]), gl::float32ToFloat16(readPixelsData[3])};
+ gl::float32ToFloat16(readPixelsData[0]), gl::float32ToFloat16(readPixelsData[1]),
+ gl::float32ToFloat16(readPixelsData[2]), gl::float32ToFloat16(readPixelsData[3])};
for (auto extension : FloatingPointTextureExtensions)
{
@@ -3811,8 +3811,8 @@
constexpr float readPixelsData[] = {7000.0f, 100.0f, 33.0f, 1.0f};
const GLushort textureData[] = {
- gl::float32ToFloat16(readPixelsData[0]), gl::float32ToFloat16(readPixelsData[1]),
- gl::float32ToFloat16(readPixelsData[2]), gl::float32ToFloat16(readPixelsData[3])};
+ gl::float32ToFloat16(readPixelsData[0]), gl::float32ToFloat16(readPixelsData[1]),
+ gl::float32ToFloat16(readPixelsData[2]), gl::float32ToFloat16(readPixelsData[3])};
for (auto extension : FloatingPointTextureExtensions)
{
@@ -3874,8 +3874,8 @@
constexpr float readPixelsData[] = {7000.0f, 100.0f, 33.0f, -1.0f};
const GLushort textureData[] = {
- gl::float32ToFloat16(readPixelsData[0]), gl::float32ToFloat16(readPixelsData[1]),
- gl::float32ToFloat16(readPixelsData[2]), gl::float32ToFloat16(readPixelsData[3])};
+ gl::float32ToFloat16(readPixelsData[0]), gl::float32ToFloat16(readPixelsData[1]),
+ gl::float32ToFloat16(readPixelsData[2]), gl::float32ToFloat16(readPixelsData[3])};
for (auto extension : FloatingPointTextureExtensions)
{
@@ -5803,6 +5803,26 @@
}
}
+// Test for a mishandling of instanced vertex attributes with zero-sized buffers bound on Apple
+// OpenGL drivers.
+TEST_P(WebGL2CompatibilityTest, DrawWithZeroSizedBuffer)
+{
+ ANGLE_GL_PROGRAM(program, essl3_shaders::vs::Simple(), essl3_shaders::fs::Red());
+ glUseProgram(program);
+
+ GLBuffer buffer;
+ glBindBuffer(GL_ARRAY_BUFFER, buffer);
+
+ GLint posLocation = glGetAttribLocation(program, essl3_shaders::PositionAttrib());
+ glEnableVertexAttribArray(posLocation);
+
+ glVertexAttribDivisor(posLocation, 1);
+ glVertexAttribPointer(posLocation, 1, GL_UNSIGNED_BYTE, GL_FALSE, 9,
+ reinterpret_cast<void *>(0x41424344));
+
+ glDrawArrays(GL_TRIANGLES, 0, 6);
+}
+
ANGLE_INSTANTIATE_TEST_ES2_AND_ES3(WebGLCompatibilityTest);
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(WebGL2CompatibilityTest);
diff --git a/util/angle_features_autogen.cpp b/util/angle_features_autogen.cpp
index adb9610..a060dd2 100644
--- a/util/angle_features_autogen.cpp
+++ b/util/angle_features_autogen.cpp
@@ -118,6 +118,7 @@
{Feature::EnablePrecisionQualifiers, "enablePrecisionQualifiers"},
{Feature::EnablePreRotateSurfaces, "enablePreRotateSurfaces"},
{Feature::EnableProgramBinaryForCapture, "enableProgramBinaryForCapture"},
+ {Feature::EnsureNonEmptyBufferIsBoundForDraw, "ensureNonEmptyBufferIsBoundForDraw"},
{Feature::ExpandIntegerPowExpressions, "expandIntegerPowExpressions"},
{Feature::ExplicitlyEnablePerSampleShading, "explicitlyEnablePerSampleShading"},
{Feature::ExposeNonConformantExtensionsAndVersions, "exposeNonConformantExtensionsAndVersions"},
diff --git a/util/angle_features_autogen.h b/util/angle_features_autogen.h
index 3d8c47f..4064425 100644
--- a/util/angle_features_autogen.h
+++ b/util/angle_features_autogen.h
@@ -112,6 +112,7 @@
EnablePrecisionQualifiers,
EnablePreRotateSurfaces,
EnableProgramBinaryForCapture,
+ EnsureNonEmptyBufferIsBoundForDraw,
ExpandIntegerPowExpressions,
ExplicitlyEnablePerSampleShading,
ExposeNonConformantExtensionsAndVersions,

View File

@@ -1,208 +0,0 @@
From d0ee0197ddff25fe1a9876511c07542ac483702d Mon Sep 17 00:00:00 2001
From: Shahbaz Youssefi <syoussefi@chromium.org>
Date: Wed, 03 May 2023 13:41:36 -0400
Subject: [PATCH] WebGL: Limit total size of private data
... not just individual arrays.
Bug: chromium:1431761
Change-Id: I721e29aeceeaf12c3f6a67b668abffb8dfbc89b0
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/4503753
Reviewed-by: Kenneth Russell <kbr@chromium.org>
Commit-Queue: Shahbaz Youssefi <syoussefi@chromium.org>
---
diff --git a/src/compiler/translator/ValidateTypeSizeLimitations.cpp b/src/compiler/translator/ValidateTypeSizeLimitations.cpp
index 6097b6d..2a033ad 100644
--- a/src/compiler/translator/ValidateTypeSizeLimitations.cpp
+++ b/src/compiler/translator/ValidateTypeSizeLimitations.cpp
@@ -35,7 +35,9 @@
{
public:
ValidateTypeSizeLimitationsTraverser(TSymbolTable *symbolTable, TDiagnostics *diagnostics)
- : TIntermTraverser(true, false, false, symbolTable), mDiagnostics(diagnostics)
+ : TIntermTraverser(true, false, false, symbolTable),
+ mDiagnostics(diagnostics),
+ mTotalPrivateVariablesSize(0)
{
ASSERT(diagnostics);
}
@@ -93,18 +95,33 @@
const bool isPrivate = variableType.getQualifier() == EvqTemporary ||
variableType.getQualifier() == EvqGlobal ||
variableType.getQualifier() == EvqConst;
- if (layoutEncoder.getCurrentOffset() > kMaxPrivateVariableSizeInBytes && isPrivate)
+ if (isPrivate)
{
- error(asSymbol->getLine(),
- "Size of declared private variable exceeds implementation-defined limit",
- asSymbol->getName());
- return false;
+ if (layoutEncoder.getCurrentOffset() > kMaxPrivateVariableSizeInBytes)
+ {
+ error(asSymbol->getLine(),
+ "Size of declared private variable exceeds implementation-defined limit",
+ asSymbol->getName());
+ return false;
+ }
+ mTotalPrivateVariablesSize += layoutEncoder.getCurrentOffset();
}
}
return true;
}
+ void validateTotalPrivateVariableSize()
+ {
+ if (mTotalPrivateVariablesSize > kMaxPrivateVariableSizeInBytes)
+ {
+ mDiagnostics->error(
+ TSourceLoc{},
+ "Total size of declared private variables exceeds implementation-defined limit",
+ "");
+ }
+ }
+
private:
void error(TSourceLoc loc, const char *reason, const ImmutableString &token)
{
@@ -213,6 +230,8 @@
TDiagnostics *mDiagnostics;
std::vector<int> mLoopSymbolIds;
+
+ size_t mTotalPrivateVariablesSize;
};
} // namespace
@@ -223,6 +242,7 @@
{
ValidateTypeSizeLimitationsTraverser validate(symbolTable, diagnostics);
root->traverse(&validate);
+ validate.validateTotalPrivateVariableSize();
return diagnostics->numErrors() == 0;
}
diff --git a/src/tests/gl_tests/WebGLCompatibilityTest.cpp b/src/tests/gl_tests/WebGLCompatibilityTest.cpp
index e62c8fb..996bad1 100644
--- a/src/tests/gl_tests/WebGLCompatibilityTest.cpp
+++ b/src/tests/gl_tests/WebGLCompatibilityTest.cpp
@@ -5271,11 +5271,12 @@
// fairly small array.
constexpr char kVSArrayOK[] =
R"(varying vec4 color;
-const int array_size = 1000;
+const int array_size = 500;
void main()
{
mat2 array[array_size];
- if (array[0][0][0] == 2.0)
+ mat2 array2[array_size];
+ if (array[0][0][0] + array2[0][0][0] == 2.0)
color = vec4(0.0, 1.0, 0.0, 1.0);
else
color = vec4(1.0, 0.0, 0.0, 1.0);
@@ -5353,6 +5354,103 @@
EXPECT_EQ(0u, program);
}
+// Reject attempts to allocate too much private memory.
+// This is an implementation-defined limit - crbug.com/1431761.
+TEST_P(WebGLCompatibilityTest, ValidateTotalPrivateSize)
+{
+ constexpr char kTooLargeGlobalMemory1[] =
+ R"(precision mediump float;
+
+// 1 MB / 16 bytes per vec4 = 65536
+vec4 array[32768];
+vec4 array2[32769];
+
+void main()
+{
+ if (array[0].x + array[1].x == 0.)
+ gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);
+ else
+ gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
+})";
+
+ constexpr char kTooLargeGlobalMemory2[] =
+ R"(precision mediump float;
+
+// 1 MB / 16 bytes per vec4 = 65536
+vec4 array[32767];
+vec4 array2[32767];
+vec4 x, y, z;
+
+void main()
+{
+ if (array[0].x + array[1].x == x.w + y.w + z.w)
+ gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);
+ else
+ gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
+})";
+
+ constexpr char kTooLargeGlobalAndLocalMemory1[] =
+ R"(precision mediump float;
+
+// 1 MB / 16 bytes per vec4 = 65536
+vec4 array[32768];
+
+void main()
+{
+ vec4 array2[32769];
+ if (array[0].x + array[1].x == 2.0)
+ gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);
+ else
+ gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
+})";
+
+ // Note: The call stack is not taken into account for the purposes of total memory calculation.
+ constexpr char kTooLargeGlobalAndLocalMemory2[] =
+ R"(precision mediump float;
+
+// 1 MB / 16 bytes per vec4 = 65536
+vec4 array[32768];
+
+float f()
+{
+ vec4 array2[16384];
+ return array2[0].x;
+}
+
+float g()
+{
+ vec4 array3[16383];
+ return array3[0].x;
+}
+
+float h()
+{
+ vec4 value;
+ float value2
+ return value.x + value2;
+}
+
+void main()
+{
+ if (array[0].x + f() + g() + h() == 2.0)
+ gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);
+ else
+ gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
+})";
+
+ GLuint program = CompileProgram(essl1_shaders::vs::Simple(), kTooLargeGlobalMemory1);
+ EXPECT_EQ(0u, program);
+
+ program = CompileProgram(essl1_shaders::vs::Simple(), kTooLargeGlobalMemory2);
+ EXPECT_EQ(0u, program);
+
+ program = CompileProgram(essl1_shaders::vs::Simple(), kTooLargeGlobalAndLocalMemory1);
+ EXPECT_EQ(0u, program);
+
+ program = CompileProgram(essl1_shaders::vs::Simple(), kTooLargeGlobalAndLocalMemory2);
+ EXPECT_EQ(0u, program);
+}
+
// Linking should fail when corresponding vertex/fragment uniform blocks have different precision
// qualifiers.
TEST_P(WebGL2CompatibilityTest, UniformBlockPrecisionMismatch)

View File

@@ -1,396 +0,0 @@
From e4669a74888d7f9bd93d79f72829d576776dfb8a Mon Sep 17 00:00:00 2001
From: Charlie Lao <cclao@google.com>
Date: Tue, 08 Aug 2023 10:14:47 -0700
Subject: [PATCH] [M114-LTS] Vulkan: Fix data race with DynamicDescriptorPool
Right now DynamicDescriptorPool::destroyCachedDescriptorSet can be
called from garbage clean up thread, while simultaneously accessed from
context main thread, and data race will happen and cause bugs. This can
only happen when the buffer is not being suballocated. In this case,
suballocation owns the bufferBlock and bufferBlock gets destroyed when
suballocation is destroyed from garbage collection thread. If buffer is
suballocated, the shared group owns pool which owns bufferBlocks and
they gets destroyed from shared group with the share group lock. This CL
avoids this race problem by release the shared cacheKey when the buffer
is released, while we still had the shared group lock.
Bug: chromium:1469542
Change-Id: Ie6235fcfb77dee2a12b2ebde44042c3845fc0aca
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/4790523
(cherry picked from commit b48983ab8c74d2fcd9ef17c80727affb9e690c53)
---
diff --git a/src/libANGLE/renderer/vulkan/BufferVk.cpp b/src/libANGLE/renderer/vulkan/BufferVk.cpp
index 2e07deb..93a1092 100644
--- a/src/libANGLE/renderer/vulkan/BufferVk.cpp
+++ b/src/libANGLE/renderer/vulkan/BufferVk.cpp
@@ -305,7 +305,7 @@
RendererVk *renderer = contextVk->getRenderer();
if (mBuffer.valid())
{
- mBuffer.releaseBufferAndDescriptorSetCache(contextVk);
+ mBuffer.releaseBufferAndDescriptorSetCache(renderer);
}
if (mStagingBuffer.valid())
{
@@ -623,7 +623,7 @@
memcpy(dstMapPtr, srcMapPtr, static_cast<size_t>(mState.getSize()));
}
- src.releaseBufferAndDescriptorSetCache(contextVk);
+ src.releaseBufferAndDescriptorSetCache(contextVk->getRenderer());
// Return the already mapped pointer with the offset adjustment to avoid the call to unmap().
*mapPtr = dstMapPtr + offset;
@@ -1029,7 +1029,7 @@
if (prevBuffer.valid())
{
- prevBuffer.releaseBufferAndDescriptorSetCache(contextVk);
+ prevBuffer.releaseBufferAndDescriptorSetCache(contextVk->getRenderer());
}
return angle::Result::Continue;
@@ -1151,7 +1151,7 @@
if (mBuffer.valid())
{
- mBuffer.releaseBufferAndDescriptorSetCache(contextVk);
+ mBuffer.releaseBufferAndDescriptorSetCache(renderer);
}
// Allocate the buffer directly
diff --git a/src/libANGLE/renderer/vulkan/Suballocation.h b/src/libANGLE/renderer/vulkan/Suballocation.h
index d25481b..276f6b4 100644
--- a/src/libANGLE/renderer/vulkan/Suballocation.h
+++ b/src/libANGLE/renderer/vulkan/Suballocation.h
@@ -86,6 +86,13 @@
{
mDescriptorSetCacheManager.addKey(sharedCacheKey);
}
+ void releaseAllCachedDescriptorSetCacheKeys(RendererVk *renderer)
+ {
+ if (!mDescriptorSetCacheManager.empty())
+ {
+ mDescriptorSetCacheManager.releaseKeys(renderer);
+ }
+ }
private:
mutable std::mutex mVirtualBlockMutex;
diff --git a/src/libANGLE/renderer/vulkan/TextureVk.cpp b/src/libANGLE/renderer/vulkan/TextureVk.cpp
index d43c172..5e6419f 100644
--- a/src/libANGLE/renderer/vulkan/TextureVk.cpp
+++ b/src/libANGLE/renderer/vulkan/TextureVk.cpp
@@ -1623,7 +1623,7 @@
onStateChange(angle::SubjectMessage::SubjectChanged);
}
mRedefinedLevels.reset();
- mDescriptorSetCacheManager.releaseKeys(contextVk);
+ mDescriptorSetCacheManager.releaseKeys(contextVk->getRenderer());
}
void TextureVk::initImageUsageFlags(ContextVk *contextVk, angle::FormatID actualFormatID)
@@ -2857,7 +2857,7 @@
mBufferViews.release(contextVk);
mBufferViews.init(renderer, offset, size);
- mDescriptorSetCacheManager.releaseKeys(contextVk);
+ mDescriptorSetCacheManager.releaseKeys(renderer);
return angle::Result::Continue;
}
@@ -3300,7 +3300,7 @@
{
RendererVk *renderer = contextVk->getRenderer();
- mDescriptorSetCacheManager.releaseKeys(contextVk);
+ mDescriptorSetCacheManager.releaseKeys(renderer);
if (mImage == nullptr)
{
diff --git a/src/libANGLE/renderer/vulkan/vk_cache_utils.cpp b/src/libANGLE/renderer/vulkan/vk_cache_utils.cpp
index f750428..ae86b29 100644
--- a/src/libANGLE/renderer/vulkan/vk_cache_utils.cpp
+++ b/src/libANGLE/renderer/vulkan/vk_cache_utils.cpp
@@ -2589,11 +2589,19 @@
{
contextVk->getShareGroup()->getFramebufferCache().erase(contextVk, desc);
}
+void ReleaseCachedObject(RendererVk *renderer, const FramebufferDesc &desc)
+{
+ UNREACHABLE();
+}
void ReleaseCachedObject(ContextVk *contextVk, const DescriptorSetDescAndPool &descAndPool)
{
+ UNREACHABLE();
+}
+void ReleaseCachedObject(RendererVk *renderer, const DescriptorSetDescAndPool &descAndPool)
+{
ASSERT(descAndPool.mPool != nullptr);
- descAndPool.mPool->releaseCachedDescriptorSet(contextVk, descAndPool.mDesc);
+ descAndPool.mPool->releaseCachedDescriptorSet(renderer, descAndPool.mDesc);
}
void DestroyCachedObject(RendererVk *renderer, const FramebufferDesc &desc)
@@ -6261,6 +6269,22 @@
}
template <class SharedCacheKeyT>
+void SharedCacheKeyManager<SharedCacheKeyT>::releaseKeys(RendererVk *renderer)
+{
+ for (SharedCacheKeyT &sharedCacheKey : mSharedCacheKeys)
+ {
+ if (*sharedCacheKey.get() != nullptr)
+ {
+ // Immediate destroy the cached object and the key itself when first releaseKeys call is
+ // made
+ ReleaseCachedObject(renderer, *(*sharedCacheKey.get()));
+ *sharedCacheKey.get() = nullptr;
+ }
+ }
+ mSharedCacheKeys.clear();
+}
+
+template <class SharedCacheKeyT>
void SharedCacheKeyManager<SharedCacheKeyT>::destroyKeys(RendererVk *renderer)
{
for (SharedCacheKeyT &sharedCacheKey : mSharedCacheKeys)
diff --git a/src/libANGLE/renderer/vulkan/vk_cache_utils.h b/src/libANGLE/renderer/vulkan/vk_cache_utils.h
index 8c9d452..f85459a 100644
--- a/src/libANGLE/renderer/vulkan/vk_cache_utils.h
+++ b/src/libANGLE/renderer/vulkan/vk_cache_utils.h
@@ -1932,6 +1932,7 @@
void addKey(const SharedCacheKeyT &key);
// Iterate over the descriptor array and release the descriptor and cache.
void releaseKeys(ContextVk *contextVk);
+ void releaseKeys(RendererVk *rendererVk);
// Iterate over the descriptor array and destroy the descriptor and cache.
void destroyKeys(RendererVk *renderer);
void clear();
diff --git a/src/libANGLE/renderer/vulkan/vk_helpers.cpp b/src/libANGLE/renderer/vulkan/vk_helpers.cpp
index 9088e09bf..8bc027d 100644
--- a/src/libANGLE/renderer/vulkan/vk_helpers.cpp
+++ b/src/libANGLE/renderer/vulkan/vk_helpers.cpp
@@ -3798,7 +3798,7 @@
return mDescriptorPools[mCurrentPoolIndex]->get().init(context, mPoolSizes, mMaxSetsPerPool);
}
-void DynamicDescriptorPool::releaseCachedDescriptorSet(ContextVk *contextVk,
+void DynamicDescriptorPool::releaseCachedDescriptorSet(RendererVk *renderer,
const DescriptorSetDesc &desc)
{
VkDescriptorSet descriptorSet;
@@ -3812,7 +3812,7 @@
// Wrap it with helper object so that it can be GPU tracked and add it to resource list.
DescriptorSetHelper descriptorSetHelper(poolOut->get().getResourceUse(), descriptorSet);
poolOut->get().addGarbage(std::move(descriptorSetHelper));
- checkAndReleaseUnusedPool(contextVk->getRenderer(), poolOut);
+ checkAndReleaseUnusedPool(renderer, poolOut);
}
}
@@ -5016,6 +5016,12 @@
if (mSuballocation.valid())
{
+ if (!mSuballocation.isSuballocated())
+ {
+ // Destroy cacheKeys now to avoid getting into situation that having to destroy
+ // descriptorSet from garbage collection thread.
+ mSuballocation.getBufferBlock()->releaseAllCachedDescriptorSetCacheKeys(renderer);
+ }
renderer->collectSuballocationGarbage(mUse, std::move(mSuballocation),
std::move(mBufferForVertexArray));
}
@@ -5024,17 +5030,15 @@
ASSERT(!mBufferForVertexArray.valid());
}
-void BufferHelper::releaseBufferAndDescriptorSetCache(ContextVk *contextVk)
+void BufferHelper::releaseBufferAndDescriptorSetCache(RendererVk *renderer)
{
- RendererVk *renderer = contextVk->getRenderer();
-
if (renderer->hasResourceUseFinished(getResourceUse()))
{
mDescriptorSetCacheManager.destroyKeys(renderer);
}
else
{
- mDescriptorSetCacheManager.releaseKeys(contextVk);
+ mDescriptorSetCacheManager.releaseKeys(renderer);
}
release(renderer);
diff --git a/src/libANGLE/renderer/vulkan/vk_helpers.h b/src/libANGLE/renderer/vulkan/vk_helpers.h
index d2405b6..962dfe8 100644
--- a/src/libANGLE/renderer/vulkan/vk_helpers.h
+++ b/src/libANGLE/renderer/vulkan/vk_helpers.h
@@ -252,7 +252,7 @@
VkDescriptorSet *descriptorSetOut,
SharedDescriptorSetCacheKey *sharedCacheKeyOut);
- void releaseCachedDescriptorSet(ContextVk *contextVk, const DescriptorSetDesc &desc);
+ void releaseCachedDescriptorSet(RendererVk *renderer, const DescriptorSetDesc &desc);
void destroyCachedDescriptorSet(RendererVk *renderer, const DescriptorSetDesc &desc);
template <typename Accumulator>
@@ -777,7 +777,7 @@
void destroy(RendererVk *renderer);
void release(RendererVk *renderer);
- void releaseBufferAndDescriptorSetCache(ContextVk *contextVk);
+ void releaseBufferAndDescriptorSetCache(RendererVk *renderer);
BufferSerial getBufferSerial() const { return mSerial; }
BufferSerial getBlockSerial() const
diff --git a/src/tests/gl_tests/TransformFeedbackTest.cpp b/src/tests/gl_tests/TransformFeedbackTest.cpp
index ea3eeea..226eb1f 100644
--- a/src/tests/gl_tests/TransformFeedbackTest.cpp
+++ b/src/tests/gl_tests/TransformFeedbackTest.cpp
@@ -507,8 +507,8 @@
const std::array<uint32_t, 12> kInitialData = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11};
const std::array<uint32_t, 12> kUpdateData = {
- 0x12345678u, 0x9ABCDEF0u, 0x13579BDFu, 0x2468ACE0u, 0x23456781u, 0xABCDEF09u,
- 0x3579BDF1u, 0x468ACE02u, 0x34567812u, 0xBCDEF09Au, 0x579BDF13u, 0x68ACE024u,
+ 0x12345678u, 0x9ABCDEF0u, 0x13579BDFu, 0x2468ACE0u, 0x23456781u, 0xABCDEF09u,
+ 0x3579BDF1u, 0x468ACE02u, 0x34567812u, 0xBCDEF09Au, 0x579BDF13u, 0x68ACE024u,
};
GLBuffer buffer;
@@ -3749,9 +3749,9 @@
constexpr size_t kCapturedVaryingsCount = 3;
constexpr std::array<size_t, kCapturedVaryingsCount> kCaptureSizes = {8, 9, 4};
const std::vector<float> kExpected[kCapturedVaryingsCount] = {
- {0.27, 0.30, 0.33, 0.36, 0.39, 0.42, 0.45, 0.48},
- {0.63, 0.66, 0.69, 0.72, 0.75, 0.78, 0.81, 0.84, 0.87},
- {0.25, 0.5, 0.75, 1.0},
+ {0.27, 0.30, 0.33, 0.36, 0.39, 0.42, 0.45, 0.48},
+ {0.63, 0.66, 0.69, 0.72, 0.75, 0.78, 0.81, 0.84, 0.87},
+ {0.25, 0.5, 0.75, 1.0},
};
ANGLE_GL_PROGRAM_TRANSFORM_FEEDBACK(program, kVS, kFS, tfVaryings, GL_INTERLEAVED_ATTRIBS);
@@ -3848,9 +3848,9 @@
constexpr size_t kCapturedVaryingsCount = 3;
constexpr std::array<size_t, kCapturedVaryingsCount> kCaptureSizes = {1, 2, 1};
const std::vector<float> kExpected[kCapturedVaryingsCount] = {
- {0.25},
- {0.5, 0.75},
- {1.0},
+ {0.25},
+ {0.5, 0.75},
+ {1.0},
};
ANGLE_GL_PROGRAM_TRANSFORM_FEEDBACK(program, kVS, kFS, tfVaryings, GL_SEPARATE_ATTRIBS);
@@ -4392,6 +4392,51 @@
glEndTransformFeedback();
}
+// Test bufferData call and transform feedback.
+TEST_P(TransformFeedbackTest, BufferDataAndTransformFeedback)
+{
+ const char kVS[] = R"(#version 300 es
+flat out highp int var;
+void main() {
+var = 1;
+})";
+
+ const char kFS[] = R"(#version 300 es
+flat in highp int var;
+out highp int color;
+void main() {
+color = var;
+})";
+
+ ANGLE_GL_PROGRAM(program, kVS, kFS);
+
+ GLTexture texture;
+ glBindTexture(GL_TEXTURE_2D, texture);
+ glTexStorage2D(GL_TEXTURE_2D, 1, GL_R32I, 1, 1);
+
+ GLFramebuffer fbo;
+ glBindFramebuffer(GL_FRAMEBUFFER, fbo);
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
+ EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
+
+ constexpr int kClearColor[] = {123, 0, 0, 0};
+ glClearBufferiv(GL_COLOR, 0, kClearColor);
+ glDrawArrays(GL_POINTS, 0, 1);
+
+ const char *kVarying = "var";
+ glTransformFeedbackVaryings(program, 1, &kVarying, GL_INTERLEAVED_ATTRIBS);
+ glLinkProgram(program);
+ ASSERT_GL_NO_ERROR();
+
+ GLBuffer buffer;
+ glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, buffer);
+ glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, 0x7ffc * 10000, nullptr, GL_DYNAMIC_READ);
+ glBeginTransformFeedback(GL_POINTS);
+ glDrawArrays(GL_POINTS, 0, 1);
+ glEndTransformFeedback();
+ glFlush();
+}
+
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(TransformFeedbackTest);
ANGLE_INSTANTIATE_TEST_ES3_AND(TransformFeedbackTest,
ES3_VULKAN()
diff --git a/src/tests/gl_tests/UniformBufferTest.cpp b/src/tests/gl_tests/UniformBufferTest.cpp
index 4d005c0..71b8504 100644
--- a/src/tests/gl_tests/UniformBufferTest.cpp
+++ b/src/tests/gl_tests/UniformBufferTest.cpp
@@ -3422,6 +3422,50 @@
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
}
+// Calling BufferData and use it in a loop to force descriptorSet creation and destroy.
+TEST_P(UniformBufferTest, BufferDataInLoop)
+{
+ glClear(GL_COLOR_BUFFER_BIT);
+
+ // Use large buffer size to get around suballocation, so that we will gets a new buffer with
+ // bufferData call.
+ static constexpr size_t kBufferSize = 4 * 1024 * 1024;
+ std::vector<float> floatData;
+ floatData.resize(kBufferSize / (sizeof(float)), 0.0f);
+ floatData[0] = 0.5f;
+ floatData[1] = 0.75f;
+ floatData[2] = 0.25f;
+ floatData[3] = 1.0f;
+
+ GLTexture textures[2];
+ GLFramebuffer fbos[2];
+ for (int i = 0; i < 2; i++)
+ {
+ glBindTexture(GL_TEXTURE_2D, textures[i]);
+ glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 256, 256);
+
+ glBindFramebuffer(GL_FRAMEBUFFER, fbos[i]);
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textures[i], 0);
+ EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
+ }
+
+ for (int loop = 0; loop < 10; loop++)
+ {
+ int i = loop & 0x1;
+ // Switch FBO to get around deferred flush
+ glBindFramebuffer(GL_FRAMEBUFFER, fbos[i]);
+ glBindBuffer(GL_UNIFORM_BUFFER, mUniformBuffer);
+ glBufferData(GL_UNIFORM_BUFFER, kBufferSize, floatData.data(), GL_STATIC_DRAW);
+
+ glBindBufferBase(GL_UNIFORM_BUFFER, 0, mUniformBuffer);
+ glUniformBlockBinding(mProgram, mUniformBufferIndex, 0);
+ drawQuad(mProgram, essl3_shaders::PositionAttrib(), 0.5f);
+ glFlush();
+ }
+ ASSERT_GL_NO_ERROR();
+ EXPECT_PIXEL_NEAR(0, 0, 128, 191, 64, 255, 1);
+}
+
class WebGL2UniformBufferTest : public UniformBufferTest
{
protected:

View File

@@ -0,0 +1,66 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Milan Burda <milan.burda@gmail.com>
Date: Mon, 10 Oct 2022 15:11:08 +0400
Subject: fix: rename WebSwapCGLLayer to WebSwapCGLLayerChromium
Class WebSwapCGLLayer is implemented in both /System/Library/Frameworks/WebKit.framework/Versions/A/Frameworks/WebCore.framework/Versions/A/Frameworks/libANGLE-shared.dylib (0x23c589b50)
and src/out/testing/Electron.app/Contents/Frameworks/Electron Framework.framework/Versions/A/Libraries/libGLESv2.dylib (0x1123f8488).
One of the two will be used. Which one is undefined.
diff --git a/src/libANGLE/renderer/gl/cgl/WindowSurfaceCGL.h b/src/libANGLE/renderer/gl/cgl/WindowSurfaceCGL.h
index 7101cd271c07e604c6f5241d1a22f59f446c0033..98a89976f87e32a66bd504951698204fad938d57 100644
--- a/src/libANGLE/renderer/gl/cgl/WindowSurfaceCGL.h
+++ b/src/libANGLE/renderer/gl/cgl/WindowSurfaceCGL.h
@@ -18,7 +18,7 @@ struct __IOSurface;
typedef __IOSurface *IOSurfaceRef;
// WebKit's build process requires that every Objective-C class name has the prefix "Web".
-@class WebSwapCGLLayer;
+@class WebSwapCGLLayerChromium;
namespace rx
{
@@ -89,7 +89,7 @@ class WindowSurfaceCGL : public SurfaceGL
gl::Framebuffer *framebuffer) override;
private:
- WebSwapCGLLayer *mSwapLayer;
+ WebSwapCGLLayerChromium *mSwapLayer;
SharedSwapState mSwapState;
uint64_t mCurrentSwapId;
diff --git a/src/libANGLE/renderer/gl/cgl/WindowSurfaceCGL.mm b/src/libANGLE/renderer/gl/cgl/WindowSurfaceCGL.mm
index 27990e9c2facbbe0e30f4b275e0778a6474fb9ce..84f9fa9b6d31fb0e85a4c4270dff4d935f855c26 100644
--- a/src/libANGLE/renderer/gl/cgl/WindowSurfaceCGL.mm
+++ b/src/libANGLE/renderer/gl/cgl/WindowSurfaceCGL.mm
@@ -24,7 +24,7 @@
# include "libANGLE/renderer/gl/StateManagerGL.h"
# include "libANGLE/renderer/gl/cgl/DisplayCGL.h"
-@interface WebSwapCGLLayer : CAOpenGLLayer {
+@interface WebSwapCGLLayerChromium : CAOpenGLLayer {
CGLContextObj mDisplayContext;
bool initialized;
@@ -38,7 +38,7 @@ - (id)initWithSharedState:(rx::SharedSwapState *)swapState
withFunctions:(const rx::FunctionsGL *)functions;
@end
-@implementation WebSwapCGLLayer
+@implementation WebSwapCGLLayerChromium
- (id)initWithSharedState:(rx::SharedSwapState *)swapState
withContext:(CGLContextObj)displayContext
withFunctions:(const rx::FunctionsGL *)functions
@@ -220,9 +220,9 @@ - (void)drawInCGLContext:(CGLContextObj)glContext
mSwapState.lastRendered = &mSwapState.textures[1];
mSwapState.beingPresented = &mSwapState.textures[2];
- mSwapLayer = [[WebSwapCGLLayer alloc] initWithSharedState:&mSwapState
- withContext:mContext
- withFunctions:mFunctions];
+ mSwapLayer = [[WebSwapCGLLayerChromium alloc] initWithSharedState:&mSwapState
+ withContext:mContext
+ withFunctions:mFunctions];
[mLayer addSublayer:mSwapLayer];
[mSwapLayer setContentsScale:[mLayer contentsScale]];

View File

@@ -20,10 +20,10 @@ index 2ca14efae5ea478f43794a81883b00dfdb1a37b0..d73055fbf39334925ef4b4804bbaca57
case ssl_open_record_error:
diff --git a/ssl/ssl_lib.cc b/ssl/ssl_lib.cc
index 6b4549633585f8a65fb7b285a9be4ba83db355db..f9367d3c050f89011a09b847c29df31f321ffd09 100644
index 86e8eb33e2f99b9a6173550027cfd0812a39614e..f2aac85c096bef42a015135b02936e3d4e9a4c56 100644
--- a/ssl/ssl_lib.cc
+++ b/ssl/ssl_lib.cc
@@ -1335,7 +1335,7 @@ int SSL_get_error(const SSL *ssl, int ret_code) {
@@ -1320,7 +1320,7 @@ int SSL_get_error(const SSL *ssl, int ret_code) {
}
if (ret_code == 0) {
@@ -32,7 +32,7 @@ index 6b4549633585f8a65fb7b285a9be4ba83db355db..f9367d3c050f89011a09b847c29df31f
return SSL_ERROR_ZERO_RETURN;
}
// An EOF was observed which violates the protocol, and the underlying
@@ -2624,13 +2624,7 @@ void *SSL_CTX_get_ex_data(const SSL_CTX *ctx, int idx) {
@@ -2597,13 +2597,7 @@ void *SSL_CTX_get_ex_data(const SSL_CTX *ctx, int idx) {
return CRYPTO_get_ex_data(&ctx->ex_data, idx);
}
@@ -48,10 +48,10 @@ index 6b4549633585f8a65fb7b285a9be4ba83db355db..f9367d3c050f89011a09b847c29df31f
void SSL_CTX_set_tmp_rsa_callback(SSL_CTX *ctx,
RSA *(*cb)(SSL *ssl, int is_export,
diff --git a/ssl/ssl_test.cc b/ssl/ssl_test.cc
index 854068f44b2bb8f738e41fab059b62ced9309fce..a080edd8b5ec48e433afa45d6246b30e9f7221f0 100644
index f51c11efc12209377773204808b85c9cbf5d3bff..d19fd1f9643f99fdd56753a942fccefff08728ac 100644
--- a/ssl/ssl_test.cc
+++ b/ssl/ssl_test.cc
@@ -8459,11 +8459,6 @@ TEST(SSLTest, ErrorSyscallAfterCloseNotify) {
@@ -8460,11 +8460,6 @@ TEST(SSLTest, ErrorSyscallAfterCloseNotify) {
EXPECT_EQ(ret, 0);
EXPECT_EQ(SSL_get_error(client.get(), ret), SSL_ERROR_ZERO_RETURN);
@@ -63,7 +63,7 @@ index 854068f44b2bb8f738e41fab059b62ced9309fce..a080edd8b5ec48e433afa45d6246b30e
// Although the client has seen close_notify, it should continue to report
// |SSL_ERROR_SYSCALL| when its writes fail.
ret = SSL_write(client.get(), data, sizeof(data));
@@ -8471,22 +8466,6 @@ TEST(SSLTest, ErrorSyscallAfterCloseNotify) {
@@ -8472,22 +8467,6 @@ TEST(SSLTest, ErrorSyscallAfterCloseNotify) {
EXPECT_EQ(SSL_get_error(client.get(), ret), SSL_ERROR_SYSCALL);
EXPECT_TRUE(write_failed);
write_failed = false;

View File

@@ -124,16 +124,12 @@ chore_introduce_blocking_api_for_electron.patch
chore_patch_out_partition_attribute_dcheck_for_webviews.patch
expose_v8initializer_codegenerationcheckcallbackinmainthread.patch
chore_patch_out_profile_methods_in_profile_selections_cc.patch
add_gin_converter_support_for_arraybufferview.patch
fix_x11_window_restore_minimized_maximized_window.patch
chore_defer_usb_service_getdevices_request_until_usb_service_is.patch
cherry-pick-48a136e77e6d.patch
cherry-pick-e6e23ba00379.patch
fix_crash_on_nativetheme_change_during_context_menu_close.patch
cherry-pick-aa23556ff213.patch
cherry-pick-abb3ebd3d2ef.patch
cherry-pick-83b0bdb696d8.patch
cherry-pick-e40cb330b645.patch
networkcontext_don_t_access_url_loader_factories_during_destruction.patch
cherry-pick-1939f7b78eda.patch
cherry-pick-37447eb52a74.patch
cherry-pick-35c06406a658.patch
revert_x11_keep_windowcache_alive_for_a_time_interval.patch
cherry-pick-ec53103cc72d.patch
cherry-pick-94af9d13a14b.patch
cherry-pick-ea1cd76358e0.patch
m114_merge_fix_a_crash_caused_by_calling_trace_event.patch
mojoipcz_copy_incoming_messages_early.patch
base_do_not_use_va_args_twice_in_asprintf.patch

View File

@@ -10,10 +10,10 @@ Allows Electron to restore WER when ELECTRON_DEFAULT_ERROR_MODE is set.
This should be upstreamed.
diff --git a/content/gpu/gpu_main.cc b/content/gpu/gpu_main.cc
index a399e1ba0e6728aa8d2869864d3c328ba61e779b..b7dd5e0e48af2a88aad11139f5951d917d8d4f9d 100644
index 7bf09dd8870040e74cd1a7653665d0806910378c..ec6d1554075ee5454f79e98d0e2e539395499dbe 100644
--- a/content/gpu/gpu_main.cc
+++ b/content/gpu/gpu_main.cc
@@ -258,6 +258,10 @@ int GpuMain(MainFunctionParams parameters) {
@@ -243,6 +243,10 @@ int GpuMain(MainFunctionParams parameters) {
// to the GpuProcessHost once the GpuServiceImpl has started.
viz::GpuServiceImpl::InstallPreInitializeLogHandler();
@@ -24,7 +24,7 @@ index a399e1ba0e6728aa8d2869864d3c328ba61e779b..b7dd5e0e48af2a88aad11139f5951d91
// We are experiencing what appear to be memory-stomp issues in the GPU
// process. These issues seem to be impacting the task executor and listeners
// registered to it. Create the task executor on the heap to guard against
@@ -342,7 +346,6 @@ int GpuMain(MainFunctionParams parameters) {
@@ -327,7 +331,6 @@ int GpuMain(MainFunctionParams parameters) {
const_cast<base::CommandLine*>(&command_line), gpu_preferences);
const bool dead_on_arrival = !init_success;

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 fef4c8e02067c44ed804c8b53db1007fae2d2a76..b36304ee0a832c5e1e2fd3af6151b7b03fd98ec4 100644
index 6c92a2856e447bdda11c7ed2c64b79b93a0eca26..03dedde2d83e6b09fb7e90be7dfdce246f301d8f 100644
--- a/content/public/renderer/render_frame_observer.h
+++ b/content/public/renderer/render_frame_observer.h
@@ -137,6 +137,8 @@ class CONTENT_EXPORT RenderFrameObserver : public IPC::Listener,
@@ -136,6 +136,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 fef4c8e02067c44ed804c8b53db1007fae2d2a76..b36304ee0a832c5e1e2fd3af6151b7b0
int32_t world_id) {}
virtual void DidClearWindowObject() {}
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc
index 026a6934997f0825c3f2c0a40551ce7784a7b828..5bceb2baec943a2f58416c0ca6093014f9d68d7c 100644
index dab59cd51f1f66ff9e712955a880f73ef9e34fd2..0fa592bd37cfef925a8af9aa8ff19177c8e91ae1 100644
--- a/content/renderer/render_frame_impl.cc
+++ b/content/renderer/render_frame_impl.cc
@@ -4417,6 +4417,12 @@ void RenderFrameImpl::DidCreateScriptContext(v8::Local<v8::Context> context,
@@ -4361,6 +4361,12 @@ void RenderFrameImpl::DidCreateScriptContext(v8::Local<v8::Context> context,
observer.DidCreateScriptContext(context, world_id);
}
@@ -40,10 +40,10 @@ index 026a6934997f0825c3f2c0a40551ce7784a7b828..5bceb2baec943a2f58416c0ca6093014
int world_id) {
for (auto& observer : observers_)
diff --git a/content/renderer/render_frame_impl.h b/content/renderer/render_frame_impl.h
index 516a8140f79cc7f8ffe4b0665184d7d3d6111da9..fce2608070d2bf31b6b02de47102aff870c8229f 100644
index ff1a05ac05d2df7db3ba3579ddf0d2d329d9782c..72806c4947b7187b54c79a1cd05200183e56d4d1 100644
--- a/content/renderer/render_frame_impl.h
+++ b/content/renderer/render_frame_impl.h
@@ -608,6 +608,8 @@ class CONTENT_EXPORT RenderFrameImpl
@@ -605,6 +605,8 @@ class CONTENT_EXPORT RenderFrameImpl
void DidObserveLayoutShift(double score, bool after_input_or_scroll) override;
void DidCreateScriptContext(v8::Local<v8::Context> context,
int world_id) override;
@@ -53,10 +53,10 @@ index 516a8140f79cc7f8ffe4b0665184d7d3d6111da9..fce2608070d2bf31b6b02de47102aff8
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 dfd33eede0a8b0935a06eeb8f505a8d0738afa19..06827403830cb730b2521c715ec06aedbf7339c6 100644
index d6bb89671f9d71baa087d6f5cd2ef8d1b048b5ca..44dd685fa2d97451c3c8c06788d8d7384d554bb8 100644
--- a/third_party/blink/public/web/web_local_frame_client.h
+++ b/third_party/blink/public/web/web_local_frame_client.h
@@ -606,6 +606,9 @@ class BLINK_EXPORT WebLocalFrameClient {
@@ -599,6 +599,9 @@ class BLINK_EXPORT WebLocalFrameClient {
virtual void DidCreateScriptContext(v8::Local<v8::Context>,
int32_t world_id) {}
@@ -67,22 +67,22 @@ index dfd33eede0a8b0935a06eeb8f505a8d0738afa19..06827403830cb730b2521c715ec06aed
virtual void WillReleaseScriptContext(v8::Local<v8::Context>,
int32_t world_id) {}
diff --git a/third_party/blink/renderer/bindings/core/v8/local_window_proxy.cc b/third_party/blink/renderer/bindings/core/v8/local_window_proxy.cc
index e7d4256fa96f5bc8ad71bd13b6b33feef32b443f..0dfeda68a4dbfd6b442f8d8f928c8cb871dd6aa4 100644
index 9736b31c03a32635fb8fde581321cc10ec11b11a..c9fd2170a25a7970648b8210ebe94e225f4ee3aa 100644
--- a/third_party/blink/renderer/bindings/core/v8/local_window_proxy.cc
+++ b/third_party/blink/renderer/bindings/core/v8/local_window_proxy.cc
@@ -198,6 +198,7 @@ void LocalWindowProxy::Initialize() {
@@ -197,6 +197,7 @@ void LocalWindowProxy::Initialize() {
}
InstallConditionalFeatures();
+ GetFrame()->Client()->DidInstallConditionalFeatures(context, world_->GetWorldId());
if (World().IsMainWorld()) {
probe::DidCreateMainWorldContext(GetFrame());
GetFrame()->Loader().DispatchDidClearWindowObjectInMainWorld();
diff --git a/third_party/blink/renderer/core/frame/local_frame_client.h b/third_party/blink/renderer/core/frame/local_frame_client.h
index 2c526726ff1ed7008152086210b25103ce308d5b..c62ab44289bf32ac9d40d3df45f6363409f0dea9 100644
index 553afb55280410392699855f167d51d2831ac3ca..a9a99e669689b433ce4c63b3c549676ee15255a4 100644
--- a/third_party/blink/renderer/core/frame/local_frame_client.h
+++ b/third_party/blink/renderer/core/frame/local_frame_client.h
@@ -315,6 +315,8 @@ class CORE_EXPORT LocalFrameClient : public FrameClient {
@@ -317,6 +317,8 @@ class CORE_EXPORT LocalFrameClient : public FrameClient {
virtual void DidCreateScriptContext(v8::Local<v8::Context>,
int32_t world_id) = 0;
@@ -92,7 +92,7 @@ index 2c526726ff1ed7008152086210b25103ce308d5b..c62ab44289bf32ac9d40d3df45f63634
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 56ad2a8f3fabe03b2c285231d0e99dbcbaf2a9d2..130423e45f17998bf5a28c719115715941ae6620 100644
index c4a593326e3de8b0c2462a54e13304d14dd7b56a..97bec4188d3aee81d6a22d487ce5364c4120d4b8 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
@@ -283,6 +283,13 @@ void LocalFrameClientImpl::DidCreateScriptContext(
@@ -110,10 +110,10 @@ index 56ad2a8f3fabe03b2c285231d0e99dbcbaf2a9d2..130423e45f17998bf5a28c7191157159
v8::Local<v8::Context> context,
int32_t world_id) {
diff --git a/third_party/blink/renderer/core/frame/local_frame_client_impl.h b/third_party/blink/renderer/core/frame/local_frame_client_impl.h
index cd3cc4ea62f8956b87c711362520308f062de76e..75dd52f5eb3e6a06cd6185d590ba20e17b7e4e1d 100644
index 5d2c6425dd568b663ff68a31da510784ecf103ab..f1215d23c679aeec484e6f64c41b6df71a75e805 100644
--- a/third_party/blink/renderer/core/frame/local_frame_client_impl.h
+++ b/third_party/blink/renderer/core/frame/local_frame_client_impl.h
@@ -83,6 +83,8 @@ class CORE_EXPORT LocalFrameClientImpl final : public LocalFrameClient {
@@ -82,6 +82,8 @@ class CORE_EXPORT LocalFrameClientImpl final : public LocalFrameClient {
void DidCreateScriptContext(v8::Local<v8::Context>,
int32_t world_id) override;
@@ -123,10 +123,10 @@ index cd3cc4ea62f8956b87c711362520308f062de76e..75dd52f5eb3e6a06cd6185d590ba20e1
int32_t world_id) override;
diff --git a/third_party/blink/renderer/core/loader/empty_clients.h b/third_party/blink/renderer/core/loader/empty_clients.h
index ca0c223d248a2ae247429059be8a6a139006e55b..20439262e08e74318035460a0f92c981fa6758e1 100644
index 84e9886e4a27b21ee6d25186a2a7e4039bb81e18..33b23b8d913f94022966dc14e6978dc0481ea231 100644
--- a/third_party/blink/renderer/core/loader/empty_clients.h
+++ b/third_party/blink/renderer/core/loader/empty_clients.h
@@ -405,6 +405,8 @@ class CORE_EXPORT EmptyLocalFrameClient : public LocalFrameClient {
@@ -374,6 +374,8 @@ class CORE_EXPORT EmptyLocalFrameClient : public LocalFrameClient {
void DidCreateScriptContext(v8::Local<v8::Context>,
int32_t world_id) override {}

View File

@@ -7,7 +7,7 @@ Ensure that licenses for the dependencies introduced by Electron
are included in `LICENSES.chromium.html`
diff --git a/tools/licenses/licenses.py b/tools/licenses/licenses.py
index d775931a09f38db3eb472d095d461b50c5ef76f0..9d844edc8f7c2f526fa99804e8a072da1f47c656 100755
index e56688f7ab2a8b0ee59d0b7389e4c87370c8fad2..0e09b173574d48a3c7388315fef83f3ec74fe71a 100755
--- a/tools/licenses/licenses.py
+++ b/tools/licenses/licenses.py
@@ -383,6 +383,31 @@ SPECIAL_CASES = {

View File

@@ -1,60 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jeremy Rose <japthorp@slack-corp.com>
Date: Wed, 8 Mar 2023 14:53:17 -0800
Subject: add gin::Converter support for ArrayBufferView
This should be upstreamed.
diff --git a/gin/converter.cc b/gin/converter.cc
index 4eb8c3d8c8392512eeb235bc18012589549b872b..d0432f6fff09cdcebed55ccf03a6524a445ef346 100644
--- a/gin/converter.cc
+++ b/gin/converter.cc
@@ -18,6 +18,7 @@
#include "v8/include/v8-value.h"
using v8::ArrayBuffer;
+using v8::ArrayBufferView;
using v8::External;
using v8::Function;
using v8::Int32;
@@ -244,6 +245,20 @@ bool Converter<Local<ArrayBuffer>>::FromV8(Isolate* isolate,
return true;
}
+Local<Value> Converter<Local<ArrayBufferView>>::ToV8(Isolate* isolate,
+ Local<ArrayBufferView> val) {
+ return val.As<Value>();
+}
+
+bool Converter<Local<ArrayBufferView>>::FromV8(Isolate* isolate,
+ Local<Value> val,
+ Local<ArrayBufferView>* out) {
+ if (!val->IsArrayBufferView())
+ return false;
+ *out = Local<ArrayBufferView>::Cast(val);
+ return true;
+}
+
Local<Value> Converter<Local<External>>::ToV8(Isolate* isolate,
Local<External> val) {
return val.As<Value>();
diff --git a/gin/converter.h b/gin/converter.h
index eb704fcd56dee861e18e9cd64a857d68dea6f415..d32a8c26403cf32f3333ed85c23292915e6f0681 100644
--- a/gin/converter.h
+++ b/gin/converter.h
@@ -180,6 +180,15 @@ struct GIN_EXPORT Converter<v8::Local<v8::ArrayBuffer> > {
v8::Local<v8::ArrayBuffer>* out);
};
+template<>
+struct GIN_EXPORT Converter<v8::Local<v8::ArrayBufferView> > {
+ static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
+ v8::Local<v8::ArrayBufferView> val);
+ static bool FromV8(v8::Isolate* isolate,
+ v8::Local<v8::Value> val,
+ v8::Local<v8::ArrayBufferView>* out);
+};
+
template<>
struct GIN_EXPORT Converter<v8::Local<v8::External> > {
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,

View File

@@ -8,10 +8,10 @@ decorations in maximized mode where needed, preventing empty space caused
by decoration shadows and rounded titlebars around the window while maximized.
diff --git a/ui/gtk/gtk_ui.cc b/ui/gtk/gtk_ui.cc
index 99d3dc38ca60dbdc68bcb679067e8fd64e43b06a..7f5c3b103da21d213aa19fe8a4320bec0b7ebeb5 100644
index 47a773cb11d59f6edfdb9302ce76fcfaab4eb172..5283069de57e3d13e179862f635453bef6d88681 100644
--- a/ui/gtk/gtk_ui.cc
+++ b/ui/gtk/gtk_ui.cc
@@ -480,12 +480,13 @@ std::unique_ptr<ui::NavButtonProvider> GtkUi::CreateNavButtonProvider() {
@@ -480,11 +480,13 @@ std::unique_ptr<ui::NavButtonProvider> GtkUi::CreateNavButtonProvider() {
return std::make_unique<gtk::NavButtonProviderGtk>();
}
@@ -19,19 +19,17 @@ index 99d3dc38ca60dbdc68bcb679067e8fd64e43b06a..7f5c3b103da21d213aa19fe8a4320bec
+ui::WindowFrameProvider* GtkUi::GetWindowFrameProvider(bool solid_frame, bool maximized) {
auto& provider =
- solid_frame ? solid_frame_provider_ : transparent_frame_provider_;
- if (!provider) {
- provider = std::make_unique<gtk::WindowFrameProviderGtk>(solid_frame);
- }
+ maximized
+ ? (solid_frame ? solid_maximized_frame_provider_ : transparent_maximized_frame_provider_)
+ : (solid_frame ? solid_frame_provider_ : transparent_frame_provider_);
+ if (!provider)
if (!provider) {
- provider = std::make_unique<gtk::WindowFrameProviderGtk>(solid_frame);
+ provider = std::make_unique<gtk::WindowFrameProviderGtk>(solid_frame, maximized);
}
return provider.get();
}
diff --git a/ui/gtk/gtk_ui.h b/ui/gtk/gtk_ui.h
index adf91ed69c33c5da4ba8cf55d7cbfc482d0762ba..404fccbbe6957ba9309955ef5e7498cdcd0411f0 100644
index adf91ed69c33c5da4ba8cf55d7cbfc482d0762ba..d2fe3b7f0de0fcf848c2be4abc3728d73ee17f5b 100644
--- a/ui/gtk/gtk_ui.h
+++ b/ui/gtk/gtk_ui.h
@@ -106,7 +106,7 @@ class GtkUi : public ui::LinuxUiAndTheme {
@@ -43,7 +41,7 @@ index adf91ed69c33c5da4ba8cf55d7cbfc482d0762ba..404fccbbe6957ba9309955ef5e7498cd
private:
using TintMap = std::map<int, color_utils::HSL>;
@@ -195,6 +195,8 @@ class GtkUi : public ui::LinuxUiAndTheme {
@@ -195,10 +195,13 @@ class GtkUi : public ui::LinuxUiAndTheme {
// while Chrome is running.
std::unique_ptr<ui::WindowFrameProvider> solid_frame_provider_;
std::unique_ptr<ui::WindowFrameProvider> transparent_frame_provider_;
@@ -52,8 +50,13 @@ index adf91ed69c33c5da4ba8cf55d7cbfc482d0762ba..404fccbbe6957ba9309955ef5e7498cd
// Objects to notify when the window frame button order changes.
base::ObserverList<ui::WindowButtonOrderObserver>::Unchecked
window_button_order_observer_list_;
+
};
} // namespace gtk
diff --git a/ui/gtk/window_frame_provider_gtk.cc b/ui/gtk/window_frame_provider_gtk.cc
index 1925c1a2763b8dd720f5d0a630bc98ec5d16b9a0..a4986477b46aef555d526851cf191650d2972238 100644
index e866f32a06abd8b9ee70f2972822b37756878259..d55229238fed1fedba65a969495c9b5c9f1b94fa 100644
--- a/ui/gtk/window_frame_provider_gtk.cc
+++ b/ui/gtk/window_frame_provider_gtk.cc
@@ -39,16 +39,18 @@ std::string GetThemeName() {
@@ -62,7 +65,7 @@ index 1925c1a2763b8dd720f5d0a630bc98ec5d16b9a0..a4986477b46aef555d526851cf191650
-GtkCssContext WindowContext(bool solid_frame, bool focused) {
+GtkCssContext WindowContext(bool solid_frame, bool maximized, bool focused) {
std::string selector = "window.background.";
std::string selector = "#window.background.";
selector += solid_frame ? "solid-csd" : "csd";
+ if (maximized)
+ selector += ".maximized";
@@ -77,7 +80,7 @@ index 1925c1a2763b8dd720f5d0a630bc98ec5d16b9a0..a4986477b46aef555d526851cf191650
+ auto context = WindowContext(solid_frame, maximized, focused);
// GTK4 renders the decoration directly on the window.
if (!GtkCheckVersion(4))
context = AppendCssNodeToStyleContext(context, "decoration");
context = AppendCssNodeToStyleContext(context, "#decoration");
@@ -65,8 +67,8 @@ GtkCssContext DecorationContext(bool solid_frame, bool focused) {
return context;
}
@@ -87,9 +90,9 @@ index 1925c1a2763b8dd720f5d0a630bc98ec5d16b9a0..a4986477b46aef555d526851cf191650
+GtkCssContext HeaderContext(bool solid_frame, bool maximized, bool focused) {
+ auto context = WindowContext(solid_frame, maximized, focused);
context =
AppendCssNodeToStyleContext(context, "headerbar.header-bar.titlebar");
AppendCssNodeToStyleContext(context, "#headerbar.header-bar.titlebar");
if (!focused)
@@ -121,8 +123,8 @@ int ComputeTopCornerRadius() {
@@ -111,8 +113,8 @@ int ComputeTopCornerRadius() {
// need to experimentally determine the corner radius by rendering a sample.
// Additionally, in GTK4, the headerbar corners get clipped by the window
// rather than the headerbar having its own rounded corners.
@@ -100,16 +103,16 @@ index 1925c1a2763b8dd720f5d0a630bc98ec5d16b9a0..a4986477b46aef555d526851cf191650
ApplyCssToContext(context, R"(window, headerbar {
background-image: none;
background-color: black;
@@ -155,7 +157,7 @@ int ComputeTopCornerRadius() {
@@ -145,7 +147,7 @@ int ComputeTopCornerRadius() {
bool HeaderIsTranslucent() {
// The arbitrary square size to render a sample header.
constexpr int kHeaderSize = 32;
- auto context = HeaderContext(false, false);
+ auto context = HeaderContext(false, false, false);
double opacity = 1.0f;
GtkStyleContextGet(context, "opacity", &opacity, nullptr);
if (opacity < 1.0f)
@@ -211,8 +213,8 @@ void WindowFrameProviderGtk::Asset::CloneFrom(
ApplyCssToContext(context, R"(window, headerbar {
box-shadow: none;
border: none;
@@ -197,8 +199,8 @@ void WindowFrameProviderGtk::Asset::CloneFrom(
unfocused_bitmap = src.unfocused_bitmap;
}
@@ -120,7 +123,7 @@ index 1925c1a2763b8dd720f5d0a630bc98ec5d16b9a0..a4986477b46aef555d526851cf191650
WindowFrameProviderGtk::~WindowFrameProviderGtk() = default;
@@ -319,7 +321,7 @@ void WindowFrameProviderGtk::PaintWindowFrame(
@@ -305,7 +307,7 @@ void WindowFrameProviderGtk::PaintWindowFrame(
top_area_height_dip * scale - effective_frame_thickness_px.top();
auto header = PaintHeaderbar({client_bounds_px.width(), top_area_height_px},
@@ -129,7 +132,7 @@ index 1925c1a2763b8dd720f5d0a630bc98ec5d16b9a0..a4986477b46aef555d526851cf191650
image = gfx::ImageSkia::CreateFrom1xBitmap(header);
// In GTK4, the headerbar gets clipped by the window.
if (GtkCheckVersion(4)) {
@@ -351,7 +353,7 @@ void WindowFrameProviderGtk::MaybeUpdateBitmaps(float scale) {
@@ -337,7 +339,7 @@ void WindowFrameProviderGtk::MaybeUpdateBitmaps(float scale) {
gfx::Rect frame_bounds_dip(kMaxFrameSizeDip, kMaxFrameSizeDip,
2 * kMaxFrameSizeDip, 2 * kMaxFrameSizeDip);
@@ -138,7 +141,7 @@ index 1925c1a2763b8dd720f5d0a630bc98ec5d16b9a0..a4986477b46aef555d526851cf191650
frame_bounds_dip.Inset(-GtkStyleContextGetPadding(focused_context));
frame_bounds_dip.Inset(-GtkStyleContextGetBorder(focused_context));
gfx::Size bitmap_size(BitmapSizePx(asset), BitmapSizePx(asset));
@@ -359,7 +361,7 @@ void WindowFrameProviderGtk::MaybeUpdateBitmaps(float scale) {
@@ -345,7 +347,7 @@ void WindowFrameProviderGtk::MaybeUpdateBitmaps(float scale) {
PaintBitmap(bitmap_size, frame_bounds_dip, focused_context, scale);
asset.unfocused_bitmap =
PaintBitmap(bitmap_size, frame_bounds_dip,
@@ -171,10 +174,10 @@ index 32c3d63ae4598339965c58443a8c2d12b99fb89a..91496d957b8291cd37948e237a1cc4bf
} // namespace gtk
diff --git a/ui/linux/fallback_linux_ui.cc b/ui/linux/fallback_linux_ui.cc
index 5f5abeeb78372785d57315056fa61fc65a3848a9..f52f436d674ad54c9973488eec59e26d02866847 100644
index ee3e7b96eba0ade61e229aea05f5417e7822a5f5..b393cc2fbc039afa062a8b3ab880c7ff9db8b681 100644
--- a/ui/linux/fallback_linux_ui.cc
+++ b/ui/linux/fallback_linux_ui.cc
@@ -136,7 +136,7 @@ FallbackLinuxUi::CreateNavButtonProvider() {
@@ -134,7 +134,7 @@ FallbackLinuxUi::CreateNavButtonProvider() {
}
ui::WindowFrameProvider* FallbackLinuxUi::GetWindowFrameProvider(

View File

@@ -8,10 +8,10 @@ was removed as part of the Raw Clipboard API scrubbing.
https://bugs.chromium.org/p/chromium/issues/detail?id=1217643
diff --git a/ui/base/clipboard/scoped_clipboard_writer.cc b/ui/base/clipboard/scoped_clipboard_writer.cc
index 0aef31c1e881fdcb5bfe09fd5ba47b1c5bd861bc..0864450bdcb5577b3ccdf2b6bd97198f283db295 100644
index 069a4481ca6318215dd8a86b71aa7cacfb635173..605c5b8f8a7e50a22c94c6818cbdd95ced14fc15 100644
--- a/ui/base/clipboard/scoped_clipboard_writer.cc
+++ b/ui/base/clipboard/scoped_clipboard_writer.cc
@@ -249,6 +249,16 @@ void ScopedClipboardWriter::WriteEncodedDataTransferEndpointForTesting(
@@ -232,6 +232,16 @@ void ScopedClipboardWriter::WriteEncodedDataTransferEndpointForTesting(
}
#endif // BUILDFLAG(IS_CHROMEOS_ASH)
@@ -29,10 +29,10 @@ index 0aef31c1e881fdcb5bfe09fd5ba47b1c5bd861bc..0864450bdcb5577b3ccdf2b6bd97198f
objects_.clear();
platform_representations_.clear();
diff --git a/ui/base/clipboard/scoped_clipboard_writer.h b/ui/base/clipboard/scoped_clipboard_writer.h
index 569aa7f3673f16c126e7c0b8ea34cac483c7b38d..e494fcc56d4182175943ce0f4190f23a86b9f3a5 100644
index 2a9964f12a3a17103cd473de74a039d01e117041..873cd66831b7cb4d762d3b7abf5fd08623d3d73b 100644
--- a/ui/base/clipboard/scoped_clipboard_writer.h
+++ b/ui/base/clipboard/scoped_clipboard_writer.h
@@ -91,6 +91,10 @@ class COMPONENT_EXPORT(UI_BASE_CLIPBOARD) ScopedClipboardWriter {
@@ -87,6 +87,10 @@ class COMPONENT_EXPORT(UI_BASE_CLIPBOARD) ScopedClipboardWriter {
// This is only used to write custom format data.
void WriteData(const std::u16string& format, mojo_base::BigBuffer data);

View File

@@ -6,10 +6,10 @@ Subject: allow disabling blink scheduler throttling per RenderView
This allows us to disable throttling for hidden windows.
diff --git a/content/browser/renderer_host/render_view_host_impl.cc b/content/browser/renderer_host/render_view_host_impl.cc
index 43c8a9913c4b3a4fe0c3151d885c5a13a9fdc74b..0cd8005e743d3bb662c2d439b552a17b1db9b0ab 100644
index 39bd6ef7be6ecb0f22692ace3c77845d76a59391..d51a7418fe874102f0458d1aedbca26e85669da6 100644
--- a/content/browser/renderer_host/render_view_host_impl.cc
+++ b/content/browser/renderer_host/render_view_host_impl.cc
@@ -695,6 +695,11 @@ void RenderViewHostImpl::SetBackgroundOpaque(bool opaque) {
@@ -689,6 +689,11 @@ void RenderViewHostImpl::SetBackgroundOpaque(bool opaque) {
GetWidget()->GetAssociatedFrameWidget()->SetBackgroundOpaque(opaque);
}
@@ -22,7 +22,7 @@ index 43c8a9913c4b3a4fe0c3151d885c5a13a9fdc74b..0cd8005e743d3bb662c2d439b552a17b
return is_active();
}
diff --git a/content/browser/renderer_host/render_view_host_impl.h b/content/browser/renderer_host/render_view_host_impl.h
index 180abdc9f983887c83fd9d4a596472222e9ab472..00842717a7570561ee9e3eca11190ab5e1c76fb8 100644
index 574e1f33f7eb9302fc6b64efca23426676821afc..c8509989003da8ca3bbfd13c802f5bd8b81460e5 100644
--- a/content/browser/renderer_host/render_view_host_impl.h
+++ b/content/browser/renderer_host/render_view_host_impl.h
@@ -136,6 +136,7 @@ class CONTENT_EXPORT RenderViewHostImpl
@@ -33,21 +33,6 @@ index 180abdc9f983887c83fd9d4a596472222e9ab472..00842717a7570561ee9e3eca11190ab5
void SendWebPreferencesToRenderer();
void SendRendererPreferencesToRenderer(
const blink::RendererPreferences& preferences);
diff --git a/content/browser/renderer_host/render_widget_host_view_aura.cc b/content/browser/renderer_host/render_widget_host_view_aura.cc
index b69ec986a4d8a96677d785cb6768f0c0d154ff2a..047d1c96a2603fccc3adf645b08575230060d5f7 100644
--- a/content/browser/renderer_host/render_widget_host_view_aura.cc
+++ b/content/browser/renderer_host/render_widget_host_view_aura.cc
@@ -555,8 +555,8 @@ void RenderWidgetHostViewAura::ShowImpl(PageVisibilityState page_visibility) {
// OnShowWithPageVisibility will not call NotifyHostAndDelegateOnWasShown,
// which updates `visibility_`, unless the host is hidden. Make sure no update
// is needed.
- DCHECK(host_->is_hidden() || visibility_ == Visibility::VISIBLE);
- OnShowWithPageVisibility(page_visibility);
+ if (host_->is_hidden() || visibility_ == Visibility::VISIBLE)
+ OnShowWithPageVisibility(page_visibility);
}
void RenderWidgetHostViewAura::NotifyHostAndDelegateOnWasShown(
diff --git a/content/public/browser/render_view_host.h b/content/public/browser/render_view_host.h
index 9979c25ecd57e68331b628a518368635db5c2027..32733bf951af3eff7da5fd5758bbcbaa49ff0e3c 100644
--- a/content/public/browser/render_view_host.h
@@ -63,10 +48,10 @@ index 9979c25ecd57e68331b628a518368635db5c2027..32733bf951af3eff7da5fd5758bbcbaa
// This interface should only be implemented inside content.
friend class RenderViewHostImpl;
diff --git a/third_party/blink/public/mojom/page/page.mojom b/third_party/blink/public/mojom/page/page.mojom
index d18c66114870de83c7eef21578e9e2b8d5606a8b..e1defb3992289427df85963f44a705e3d9257342 100644
index 4f543309beff68f67ca310a968b6c0efefdf28cb..e1f132606d2b8c478207b13fdd1464347486cc0b 100644
--- a/third_party/blink/public/mojom/page/page.mojom
+++ b/third_party/blink/public/mojom/page/page.mojom
@@ -149,4 +149,7 @@ interface PageBroadcast {
@@ -141,4 +141,7 @@ interface PageBroadcast {
mojo_base.mojom.UnguessableToken devtools_frame_token,
RemoteFrameInterfacesFromBrowser remote_frame_interfaces,
RemoteMainFrameInterfaces remote_main_frame_interfaces);
@@ -75,10 +60,10 @@ index d18c66114870de83c7eef21578e9e2b8d5606a8b..e1defb3992289427df85963f44a705e3
+ SetSchedulerThrottling(bool allowed);
};
diff --git a/third_party/blink/public/web/web_view.h b/third_party/blink/public/web/web_view.h
index 2c3930e849719dce3871c12b073966ca370e5e43..990f88a20320a2f6f58cf2e0b4d37e398d5f7fda 100644
index c8655d9270b812df04f27025ff29a2fb6d2a4066..2f83e5ce40f8217ff5d53f7205299ad7ac4d2013 100644
--- a/third_party/blink/public/web/web_view.h
+++ b/third_party/blink/public/web/web_view.h
@@ -369,6 +369,7 @@ class BLINK_EXPORT WebView {
@@ -367,6 +367,7 @@ class BLINK_EXPORT WebView {
// Scheduling -----------------------------------------------------------
virtual PageScheduler* Scheduler() const = 0;
@@ -87,20 +72,10 @@ index 2c3930e849719dce3871c12b073966ca370e5e43..990f88a20320a2f6f58cf2e0b4d37e39
// Visibility -----------------------------------------------------------
diff --git a/third_party/blink/renderer/core/exported/web_view_impl.cc b/third_party/blink/renderer/core/exported/web_view_impl.cc
index 4f99cf1e984cb7411703e3e586203834bf218afe..a7d788610a3611877afe8d0e8b3f3d7507c71aab 100644
index 823d6d2ab3772c29b75e60794862a4e02fc62495..0dd3a74473fc73a75b7bb3dfe8a10844ebc34079 100644
--- a/third_party/blink/renderer/core/exported/web_view_impl.cc
+++ b/third_party/blink/renderer/core/exported/web_view_impl.cc
@@ -2446,6 +2446,9 @@ void WebViewImpl::SetPageLifecycleStateInternal(
TRACE_EVENT2("navigation", "WebViewImpl::SetPageLifecycleStateInternal",
"old_state", old_state, "new_state", new_state);
+ if (!scheduler_throttling_allowed_)
+ new_state->visibility = mojom::blink::PageVisibilityState::kVisible;
+
bool storing_in_bfcache = new_state->is_in_back_forward_cache &&
!old_state->is_in_back_forward_cache;
bool restoring_from_bfcache = !new_state->is_in_back_forward_cache &&
@@ -3895,17 +3898,30 @@ PageScheduler* WebViewImpl::Scheduler() const {
@@ -3875,13 +3875,21 @@ PageScheduler* WebViewImpl::Scheduler() const {
return GetPage()->GetPageScheduler();
}
@@ -115,34 +90,19 @@ index 4f99cf1e984cb7411703e3e586203834bf218afe..a7d788610a3611877afe8d0e8b3f3d75
mojom::blink::PageVisibilityState visibility_state,
bool is_initial_state) {
DCHECK(GetPage());
- GetPage()->SetVisibilityState(visibility_state, is_initial_state);
- GetPage()->GetPageScheduler()->SetPageVisible(
GetPage()->SetVisibilityState(visibility_state, is_initial_state);
GetPage()->GetPageScheduler()->SetPageVisible(
- visibility_state == mojom::blink::PageVisibilityState::kVisible);
- // Notify observers of the change.
- if (!is_initial_state) {
- for (auto& observer : observers_)
- observer.OnPageVisibilityChanged(visibility_state);
+ // If backgroundThrottling is disabled, the page is always visible.
+ if (!scheduler_throttling_allowed_) {
+ GetPage()->SetVisibilityState(mojom::blink::PageVisibilityState::kVisible, is_initial_state);
+ GetPage()->GetPageScheduler()->SetPageVisible(true);
+ } else {
+ bool is_visible = visibility_state == mojom::blink::PageVisibilityState::kVisible;
+ GetPage()->SetVisibilityState(visibility_state, is_initial_state);
+ GetPage()->GetPageScheduler()->SetPageVisible(is_visible);
+ // Notify observers of the change.
+ if (!is_initial_state) {
+ for (auto& observer : observers_)
+ observer.OnPageVisibilityChanged(visibility_state);
+ }
}
}
+ scheduler_throttling_allowed_ ?
+ (visibility_state == mojom::blink::PageVisibilityState::kVisible) : true);
// Notify observers of the change.
if (!is_initial_state) {
for (auto& observer : observers_)
diff --git a/third_party/blink/renderer/core/exported/web_view_impl.h b/third_party/blink/renderer/core/exported/web_view_impl.h
index 421ca0b15eea5958d18e52118613c388aeef7dce..c3751889cc1289f237f9f8e0e22f321e8e793778 100644
index dcd53ce7503b010c3449b70011d701b069286259..ceb78b07455179ec9a7d59940710858d2991b086 100644
--- a/third_party/blink/renderer/core/exported/web_view_impl.h
+++ b/third_party/blink/renderer/core/exported/web_view_impl.h
@@ -441,6 +441,7 @@ class CORE_EXPORT WebViewImpl final : public WebView,
@@ -440,6 +440,7 @@ class CORE_EXPORT WebViewImpl final : public WebView,
LocalDOMWindow* PagePopupWindow() const;
PageScheduler* Scheduler() const override;
@@ -150,7 +110,7 @@ index 421ca0b15eea5958d18e52118613c388aeef7dce..c3751889cc1289f237f9f8e0e22f321e
void SetVisibilityState(mojom::blink::PageVisibilityState visibility_state,
bool is_initial_state) override;
mojom::blink::PageVisibilityState GetVisibilityState() override;
@@ -904,6 +905,8 @@ class CORE_EXPORT WebViewImpl final : public WebView,
@@ -902,6 +903,8 @@ class CORE_EXPORT WebViewImpl final : public WebView,
// If true, we send IPC messages when |preferred_size_| changes.
bool send_preferred_size_changes_ = false;

View File

@@ -8,10 +8,10 @@ WebPreferences of in-process child windows, rather than relying on
process-level command line switches, as before.
diff --git a/third_party/blink/common/web_preferences/web_preferences.cc b/third_party/blink/common/web_preferences/web_preferences.cc
index 0997787979ba293e78211783d8d9993af50ac1c8..2e25e32d0e46470bc4d1a2254fc6737d848791ef 100644
index 8be73a1f7b89613a9d0a0012e9b072efd7d3df95..71d5bf4ddde3d19a89f96a2de0bdce9c7ac8a19e 100644
--- a/third_party/blink/common/web_preferences/web_preferences.cc
+++ b/third_party/blink/common/web_preferences/web_preferences.cc
@@ -144,6 +144,19 @@ WebPreferences::WebPreferences()
@@ -142,6 +142,19 @@ WebPreferences::WebPreferences()
v8_cache_options(blink::mojom::V8CacheOptions::kDefault),
record_whole_document(false),
stylus_handwriting_enabled(false),
@@ -32,10 +32,10 @@ index 0997787979ba293e78211783d8d9993af50ac1c8..2e25e32d0e46470bc4d1a2254fc6737d
accelerated_video_decode_enabled(false),
animation_policy(
diff --git a/third_party/blink/common/web_preferences/web_preferences_mojom_traits.cc b/third_party/blink/common/web_preferences/web_preferences_mojom_traits.cc
index d557c270b484c3152830b0678c90691c983538ad..de0a4e4ab43072d0a815724a772aa42006f63fd5 100644
index 22220de13b6d7b88cfe0b02367836f7bd5e139b5..4aad04688926066c75d07aea9a6d2a5932e37979 100644
--- a/third_party/blink/common/web_preferences/web_preferences_mojom_traits.cc
+++ b/third_party/blink/common/web_preferences/web_preferences_mojom_traits.cc
@@ -152,6 +152,19 @@ bool StructTraits<blink::mojom::WebPreferencesDataView,
@@ -148,6 +148,19 @@ bool StructTraits<blink::mojom::WebPreferencesDataView,
out->v8_cache_options = data.v8_cache_options();
out->record_whole_document = data.record_whole_document();
out->stylus_handwriting_enabled = data.stylus_handwriting_enabled();
@@ -56,7 +56,7 @@ index d557c270b484c3152830b0678c90691c983538ad..de0a4e4ab43072d0a815724a772aa420
out->accelerated_video_decode_enabled =
data.accelerated_video_decode_enabled();
diff --git a/third_party/blink/public/common/web_preferences/web_preferences.h b/third_party/blink/public/common/web_preferences/web_preferences.h
index 2ab2f3af95aaa1b1ed8f0530c6e13b8d62ed9ded..72c03d606d5c5ef0e5a699bc9380d573631f5518 100644
index 418233a0c46fa0837c9bd11e360d5279c1b1ff6d..b47ba60ec901460db3b1a8a2f81f5b7a9006c647 100644
--- a/third_party/blink/public/common/web_preferences/web_preferences.h
+++ b/third_party/blink/public/common/web_preferences/web_preferences.h
@@ -10,6 +10,7 @@
@@ -67,7 +67,7 @@ index 2ab2f3af95aaa1b1ed8f0530c6e13b8d62ed9ded..72c03d606d5c5ef0e5a699bc9380d573
#include "net/nqe/effective_connection_type.h"
#include "third_party/blink/public/common/common_export.h"
#include "third_party/blink/public/mojom/css/preferred_color_scheme.mojom-shared.h"
@@ -159,6 +160,19 @@ struct BLINK_COMMON_EXPORT WebPreferences {
@@ -158,6 +159,19 @@ struct BLINK_COMMON_EXPORT WebPreferences {
// If true, stylus handwriting recognition to text input will be available in
// editable input fields which are non-password type.
bool stylus_handwriting_enabled;
@@ -88,7 +88,7 @@ index 2ab2f3af95aaa1b1ed8f0530c6e13b8d62ed9ded..72c03d606d5c5ef0e5a699bc9380d573
// This flags corresponds to a Page's Settings' setCookieEnabled state. It
// only controls whether or not the "document.cookie" field is properly
diff --git a/third_party/blink/public/common/web_preferences/web_preferences_mojom_traits.h b/third_party/blink/public/common/web_preferences/web_preferences_mojom_traits.h
index 0222f3671842c3a707e2dd9aeaec72a6f94afe7c..882556b4bdea1dc9cb418e0e9f3cc32966111a67 100644
index 625db31846992c54083b30b2990fb359e6a3b3cd..1ccf341ecce1cf2ca17e3d4f7d5c42b8309caf96 100644
--- a/third_party/blink/public/common/web_preferences/web_preferences_mojom_traits.h
+++ b/third_party/blink/public/common/web_preferences/web_preferences_mojom_traits.h
@@ -6,6 +6,7 @@
@@ -99,7 +99,7 @@ index 0222f3671842c3a707e2dd9aeaec72a6f94afe7c..882556b4bdea1dc9cb418e0e9f3cc329
#include "mojo/public/cpp/bindings/struct_traits.h"
#include "net/nqe/effective_connection_type.h"
#include "third_party/blink/public/common/common_export.h"
@@ -439,6 +440,52 @@ struct BLINK_COMMON_EXPORT StructTraits<blink::mojom::WebPreferencesDataView,
@@ -434,6 +435,52 @@ struct BLINK_COMMON_EXPORT StructTraits<blink::mojom::WebPreferencesDataView,
return r.stylus_handwriting_enabled;
}
@@ -153,7 +153,7 @@ index 0222f3671842c3a707e2dd9aeaec72a6f94afe7c..882556b4bdea1dc9cb418e0e9f3cc329
return r.cookie_enabled;
}
diff --git a/third_party/blink/public/mojom/webpreferences/web_preferences.mojom b/third_party/blink/public/mojom/webpreferences/web_preferences.mojom
index 1e04b372e8a7839a05b2304ead80a04689cd850c..ead0401600b38d362aec21ee77b3c71f1d13649f 100644
index 5d764552d3f8bc30b6d6efa83ca3ff120dba4b54..cbd2f58730c107eafba6358b12517e7d55bbdf0c 100644
--- a/third_party/blink/public/mojom/webpreferences/web_preferences.mojom
+++ b/third_party/blink/public/mojom/webpreferences/web_preferences.mojom
@@ -9,6 +9,7 @@ import "third_party/blink/public/mojom/css/preferred_contrast.mojom";
@@ -164,7 +164,7 @@ index 1e04b372e8a7839a05b2304ead80a04689cd850c..ead0401600b38d362aec21ee77b3c71f
enum PointerType {
kPointerNone = 1, // 1 << 0
@@ -218,6 +219,19 @@ struct WebPreferences {
@@ -208,6 +209,19 @@ struct WebPreferences {
// If true, stylus handwriting recognition to text input will be available in
// editable input fields which are non-password type.
bool stylus_handwriting_enabled;

View File

@@ -0,0 +1,96 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Benoit Lize <lizeb@chromium.org>
Date: Fri, 9 Jun 2023 17:59:08 +0000
Subject: Do not use va_args twice in asprintf()
(cherry picked from commit 3cff0cb19a6d01cbdd9932f43dabaaeda9c0330a)
Bug: 1450536
Change-Id: Ib34d96935278869a63897f9a1c66afc98865d90f
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4579347
Reviewed-by: Egor Pasko <pasko@chromium.org>
Commit-Queue: Benoit Lize <lizeb@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#1151796}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4604070
Reviewed-by: Michael Thiessen <mthiesse@chromium.org>
Cr-Commit-Position: refs/branch-heads/5735@{#1224}
Cr-Branched-From: 2f562e4ddbaf79a3f3cb338b4d1bd4398d49eb67-refs/heads/main@{#1135570}
diff --git a/base/allocator/partition_allocator/shim/allocator_shim_override_linker_wrapped_symbols.h b/base/allocator/partition_allocator/shim/allocator_shim_override_linker_wrapped_symbols.h
index 621873126602463a09efca1bf1548ed10910d323..de2af6d7d54e254b9e7b8264b53d30a338fb13e8 100644
--- a/base/allocator/partition_allocator/shim/allocator_shim_override_linker_wrapped_symbols.h
+++ b/base/allocator/partition_allocator/shim/allocator_shim_override_linker_wrapped_symbols.h
@@ -123,13 +123,21 @@ SHIM_ALWAYS_EXPORT char* __wrap_getcwd(char* buffer, size_t size) {
SHIM_ALWAYS_EXPORT int __wrap_vasprintf(char** strp,
const char* fmt,
va_list va_args) {
+ // There are cases where we need to use the list of arguments twice, namely
+ // when the original buffer is too small. It is not allowed to walk the list
+ // twice, so make a copy for the second invocation of vsnprintf().
+ va_list va_args_copy;
+ va_copy(va_args_copy, va_args);
+
constexpr int kInitialSize = 128;
*strp = static_cast<char*>(
malloc(kInitialSize)); // Our malloc() doesn't return nullptr.
int actual_size = vsnprintf(*strp, kInitialSize, fmt, va_args);
- if (actual_size < 0)
+ if (actual_size < 0) {
+ va_end(va_args_copy);
return actual_size;
+ }
*strp =
static_cast<char*>(realloc(*strp, static_cast<size_t>(actual_size + 1)));
@@ -139,9 +147,14 @@ SHIM_ALWAYS_EXPORT int __wrap_vasprintf(char** strp,
//
// This is very lightly used in Chromium in practice, see crbug.com/116558 for
// details.
- if (actual_size >= kInitialSize)
- return vsnprintf(*strp, static_cast<size_t>(actual_size + 1), fmt, va_args);
-
+ if (actual_size >= kInitialSize) {
+ int ret = vsnprintf(*strp, static_cast<size_t>(actual_size + 1), fmt,
+ va_args_copy);
+ va_end(va_args_copy);
+ return ret;
+ }
+
+ va_end(va_args_copy);
return actual_size;
}
diff --git a/base/allocator/partition_allocator/shim/allocator_shim_unittest.cc b/base/allocator/partition_allocator/shim/allocator_shim_unittest.cc
index dcf26fa5fc6d51de6276aa6fdcc4691f781c4bfd..fd46a15799864acaf58ef57315606bf515b48b15 100644
--- a/base/allocator/partition_allocator/shim/allocator_shim_unittest.cc
+++ b/base/allocator/partition_allocator/shim/allocator_shim_unittest.cc
@@ -734,6 +734,28 @@ TEST_F(AllocatorShimTest, InterceptVasprintf) {
// Should not crash.
}
+TEST_F(AllocatorShimTest, InterceptLongVasprintf) {
+ char* str = nullptr;
+ const char* lorem_ipsum =
+ "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed non risus. "
+ "Suspendisse lectus tortor, dignissim sit amet, adipiscing nec, "
+ "ultricies sed, dolor. Cras elementum ultrices diam. Maecenas ligula "
+ "massa, varius a, semper congue, euismod non, mi. Proin porttitor, orci "
+ "nec nonummy molestie, enim est eleifend mi, non fermentum diam nisl sit "
+ "amet erat. Duis semper. Duis arcu massa, scelerisque vitae, consequat "
+ "in, pretium a, enim. Pellentesque congue. Ut in risus volutpat libero "
+ "pharetra tempor. Cras vestibulum bibendum augue. Praesent egestas leo "
+ "in pede. Praesent blandit odio eu enim. Pellentesque sed dui ut augue "
+ "blandit sodales. Vestibulum ante ipsum primis in faucibus orci luctus "
+ "et ultrices posuere cubilia Curae; Aliquam nibh. Mauris ac mauris sed "
+ "pede pellentesque fermentum. Maecenas adipiscing ante non diam sodales "
+ "hendrerit.";
+ int err = asprintf(&str, "%s", lorem_ipsum);
+ EXPECT_EQ(err, static_cast<int>(strlen(lorem_ipsum)));
+ EXPECT_TRUE(str);
+ free(str);
+}
+
#endif // BUILDFLAG(USE_PARTITION_ALLOC_AS_MALLOC)
#endif // BUILDFLAG(IS_ANDROID)

View File

@@ -15,10 +15,10 @@ Refs changes in:
This patch reverts the changes to fix associated crashes in Electron.
diff --git a/third_party/blink/renderer/core/frame/frame.cc b/third_party/blink/renderer/core/frame/frame.cc
index 22c4d4e9718a503d9c7ca26a40c97149b0f8986a..6bdc2757c96a28022fda9e6f5e3b74a08332a4ce 100644
index b2115232fe81f47d3fe3441bcab53d09543d0a84..c836a400dfaccd276e90549a8cae38346e88909f 100644
--- a/third_party/blink/renderer/core/frame/frame.cc
+++ b/third_party/blink/renderer/core/frame/frame.cc
@@ -125,14 +125,6 @@ bool Frame::Detach(FrameDetachType type) {
@@ -124,14 +124,6 @@ bool Frame::Detach(FrameDetachType type) {
DCHECK(!IsDetached());
@@ -33,7 +33,7 @@ index 22c4d4e9718a503d9c7ca26a40c97149b0f8986a..6bdc2757c96a28022fda9e6f5e3b74a0
if (type == FrameDetachType::kRemove) {
if (provisional_frame_) {
provisional_frame_->Detach(FrameDetachType::kRemove);
@@ -156,6 +148,14 @@ bool Frame::Detach(FrameDetachType type) {
@@ -155,6 +147,14 @@ bool Frame::Detach(FrameDetachType type) {
GetWindowProxyManager()->ClearForSwap();
}
@@ -49,10 +49,10 @@ index 22c4d4e9718a503d9c7ca26a40c97149b0f8986a..6bdc2757c96a28022fda9e6f5e3b74a0
// 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 b2e5817c437c16705a74ea3d5094e9626fe3814f..d76f9ea410a2e6dd7a38bd4a17ca409b6ff87b84 100644
index d3a43f5675bc3e8937c6f7d689be8e1b470ac9f7..d2391ca06d31ac96313cf3383fa2e550a78ece18 100644
--- a/third_party/blink/renderer/core/frame/local_frame.cc
+++ b/third_party/blink/renderer/core/frame/local_frame.cc
@@ -625,10 +625,6 @@ bool LocalFrame::DetachImpl(FrameDetachType type) {
@@ -630,10 +630,6 @@ bool LocalFrame::DetachImpl(FrameDetachType type) {
}
DCHECK(!view_ || !view_->IsAttached());
@@ -63,7 +63,7 @@ index b2e5817c437c16705a74ea3d5094e9626fe3814f..d76f9ea410a2e6dd7a38bd4a17ca409b
if (!Client())
return false;
@@ -676,6 +672,11 @@ bool LocalFrame::DetachImpl(FrameDetachType type) {
@@ -681,6 +677,11 @@ bool LocalFrame::DetachImpl(FrameDetachType type) {
DCHECK(!view_->IsAttached());
Client()->WillBeDetached();

View File

@@ -6,10 +6,10 @@ Subject: boringssl BUILD.gn
Build BoringSSL with some extra functions that nodejs needs.
diff --git a/third_party/boringssl/BUILD.gn b/third_party/boringssl/BUILD.gn
index 6fb13437c6bcca2aff102b04f3a46d2ad6a791c5..c61c60c7cb968c2b730a14de9ac0629aaceb73d3 100644
index 40073723173388015f0c78899214ba155e7cdc53..72978c43a522e5716ba06e8b989710cc99bd8773 100644
--- a/third_party/boringssl/BUILD.gn
+++ b/third_party/boringssl/BUILD.gn
@@ -49,6 +49,20 @@ config("no_asm_config") {
@@ -44,6 +44,20 @@ config("no_asm_config") {
all_sources = crypto_sources + ssl_sources
all_headers = crypto_headers + ssl_headers
@@ -28,5 +28,5 @@ index 6fb13437c6bcca2aff102b04f3a46d2ad6a791c5..c61c60c7cb968c2b730a14de9ac0629a
+ ]
+}
if (enable_rust_boringssl) {
rust_bindgen("raw_bssl_sys_bindings") {
# Windows' assembly is built with NASM. The other platforms use the platform
# assembler. Exclude Windows ARM64 because NASM targets x86 and x64 only.

View File

@@ -8,10 +8,10 @@ categories in use are known / declared. This patch is required for us
to introduce a new Electron category for Electron-specific tracing.
diff --git a/base/trace_event/builtin_categories.h b/base/trace_event/builtin_categories.h
index 3c8faea2c2391a0172504d524129702cb3c43cf0..b561f3e09d294e74b41a22ab22e8bbe5be05a116 100644
index ee17e77330c498864c710eb6e0b2d8d67722bda9..6c7d1b40bd53337df4ce0bb92fb6bd610bd11c1b 100644
--- a/base/trace_event/builtin_categories.h
+++ b/base/trace_event/builtin_categories.h
@@ -80,6 +80,7 @@
@@ -81,6 +81,7 @@
X("drmcursor") \
X("dwrite") \
X("DXVA_Decoding") \

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