Browse Source

Merge branch 'main' into replace-browserview

Keeley Hammond 1 year ago
parent
commit
15202aeb44
100 changed files with 2102 additions and 1275 deletions
  1. 1 1
      .circleci/config.yml
  2. 128 151
      .circleci/config/base.yml
  3. 3 2
      .circleci/fix-known-hosts.sh
  4. 4 0
      .clang-tidy
  5. 32 31
      .devcontainer/devcontainer.json
  6. 10 4
      .devcontainer/on-create-command.sh
  7. 1 9
      .eslintrc.json
  8. 20 5
      .gitattributes
  9. 0 1
      .github/CODEOWNERS
  10. 1 0
      .github/ISSUE_TEMPLATE/bug_report.yml
  11. 166 0
      .github/workflows/branch-created.yml
  12. 24 0
      .github/workflows/issue-commented.yml
  13. 43 5
      .github/workflows/issue-labeled.yml
  14. 42 0
      .github/workflows/issue-unlabeled.yml
  15. 33 0
      .github/workflows/pull-request-labeled.yml
  16. 0 33
      .github/workflows/release_dependency_versions.yml
  17. 2 1
      .github/workflows/stale.yml
  18. 3 1
      .github/workflows/update_appveyor_image.yml
  19. 1 25
      .markdownlint.json
  20. 83 71
      BUILD.gn
  21. 4 0
      CONTRIBUTING.md
  22. 13 4
      DEPS
  23. 1 1
      README.md
  24. 58 15
      appveyor-woa.yml
  25. 56 13
      appveyor.yml
  26. 8 0
      build/.eslintrc.json
  27. 12 1
      build/args/all.gn
  28. 0 8
      build/fake_v8_context_snapshot_generator.py
  29. 3 3
      build/generate_node_defines.py
  30. 2 10
      build/webpack/webpack.config.base.js
  31. 1 1
      build/zip_libcxx.py
  32. 0 6
      buildflags/BUILD.gn
  33. 0 13
      buildflags/buildflags.gni
  34. 55 63
      chromium_src/BUILD.gn
  35. 8 0
      default_app/.eslintrc.json
  36. 2 2
      default_app/default_app.ts
  37. 6 6
      default_app/main.ts
  38. 1 1
      docs/api/accelerator.md
  39. 64 42
      docs/api/app.md
  40. 1 1
      docs/api/auto-updater.md
  41. 1 1
      docs/api/browser-view.md
  42. 37 319
      docs/api/browser-window.md
  43. 4 4
      docs/api/client-request.md
  44. 1 4
      docs/api/clipboard.md
  45. 44 7
      docs/api/command-line-switches.md
  46. 2 2
      docs/api/context-bridge.md
  47. 2 2
      docs/api/cookies.md
  48. 1 1
      docs/api/crash-reporter.md
  49. 5 3
      docs/api/desktop-capturer.md
  50. 10 10
      docs/api/dialog.md
  51. 62 13
      docs/api/extensions.md
  52. 2 2
      docs/api/incoming-message.md
  53. 5 16
      docs/api/ipc-main.md
  54. 4 16
      docs/api/ipc-renderer.md
  55. 3 2
      docs/api/menu-item.md
  56. 51 41
      docs/api/menu.md
  57. 4 3
      docs/api/message-channel-main.md
  58. 1 1
      docs/api/native-image.md
  59. 1 1
      docs/api/net-log.md
  60. 39 0
      docs/api/net.md
  61. 29 1
      docs/api/power-monitor.md
  62. 2 0
      docs/api/power-save-blocker.md
  63. 9 9
      docs/api/protocol.md
  64. 25 0
      docs/api/safe-storage.md
  65. 118 51
      docs/api/session.md
  66. 164 0
      docs/api/structures/browser-window-options.md
  67. 0 2
      docs/api/structures/ipc-renderer-event.md
  68. 0 2
      docs/api/structures/product.md
  69. 13 0
      docs/api/structures/render-process-gone-details.md
  70. 6 6
      docs/api/structures/serial-port.md
  71. 144 0
      docs/api/structures/web-preferences.md
  72. 5 41
      docs/api/system-preferences.md
  73. 4 4
      docs/api/touch-bar.md
  74. 137 55
      docs/api/web-contents.md
  75. 2 1
      docs/api/web-frame-main.md
  76. 1 2
      docs/api/web-frame.md
  77. 54 13
      docs/api/webview-tag.md
  78. 5 5
      docs/api/window-open.md
  79. 164 1
      docs/breaking-changes.md
  80. 0 62
      docs/development/azure-vm-setup.md
  81. 1 1
      docs/development/build-instructions-gn.md
  82. 2 2
      docs/development/build-instructions-windows.md
  83. 1 1
      docs/development/coding-style.md
  84. 3 3
      docs/development/creating-api.md
  85. 1 1
      docs/development/debugging-on-windows.md
  86. 1 1
      docs/development/issues.md
  87. 1 1
      docs/development/testing.md
  88. 2 2
      docs/fiddles/features/dark-mode/main.js
  89. 1 1
      docs/fiddles/features/dark-mode/preload.js
  90. 4 4
      docs/fiddles/features/drag-and-drop/main.js
  91. 2 4
      docs/fiddles/features/drag-and-drop/preload.js
  92. 1 1
      docs/fiddles/features/keyboard-shortcuts/global/main.js
  93. 1 1
      docs/fiddles/features/keyboard-shortcuts/interception-from-main/main.js
  94. 1 1
      docs/fiddles/features/keyboard-shortcuts/local/main.js
  95. 1 1
      docs/fiddles/features/keyboard-shortcuts/web-apis/main.js
  96. 1 1
      docs/fiddles/features/macos-dock-menu/main.js
  97. 1 1
      docs/fiddles/features/notifications/main/main.js
  98. 1 1
      docs/fiddles/features/notifications/renderer/main.js
  99. 2 2
      docs/fiddles/features/notifications/renderer/renderer.js
  100. 21 12
      docs/fiddles/features/offscreen-rendering/main.js

+ 1 - 1
.circleci/config.yml

@@ -62,7 +62,7 @@ jobs:
             cd .circleci/config
             yarn
             export CIRCLECI_BINARY="$HOME/circleci"
-            curl -fLSs https://raw.githubusercontent.com/CircleCI-Public/circleci-cli/master/install.sh | DESTDIR=$CIRCLECI_BINARY bash
+            curl -fLSs https://raw.githubusercontent.com/CircleCI-Public/circleci-cli/main/install.sh | DESTDIR=$CIRCLECI_BINARY bash
             node build.js
           name: Pack config.yml
       - continuation/continue:

+ 128 - 151
.circleci/config/base.yml

@@ -42,7 +42,9 @@ executors:
       size:
         description: "Docker executor size"
         type: enum
-        enum: ["medium", "xlarge", "2xlarge"]
+        # aks-linux-medium === 8 core (32 core host, shared with other builds)
+        # aks-linux-large === 32 core
+        enum: ["medium", "xlarge", "electronjs/aks-linux-medium", "electronjs/aks-linux-large"]
     docker:
       - image: ghcr.io/electron/build:e6bebd08a51a0d78ec23e5b3fd7e7c0846412328
     resource_class: << parameters.size >>
@@ -52,9 +54,14 @@ executors:
       size:
         description: "macOS executor size"
         type: enum
-        enum: ["macos.x86.medium.gen2", "large"]
+        enum: ["macos.x86.medium.gen2", "macos.m1.large.gen1", "macos.m1.medium.gen1"]
+      version:
+        description: "xcode version"
+        type: enum
+        enum: ["14.3.0", "14.0.0"]
+        default: 14.3.0
     macos:
-      xcode: 14.0.0
+      xcode: << parameters.version >>
     resource_class: << parameters.size >>
 
   # Electron Runners
@@ -114,9 +121,8 @@ env-arm: &env-arm
   TARGET_ARCH: arm
 
 env-apple-silicon: &env-apple-silicon
-  GN_EXTRA_ARGS: 'target_cpu = "arm64" use_prebuilt_v8_context_snapshot = true'
+  GN_EXTRA_ARGS: 'target_cpu = "arm64"'
   TARGET_ARCH: arm64
-  USE_PREBUILT_V8_CONTEXT_SNAPSHOT: 1
   npm_config_arch: arm64
 
 env-runner: &env-runner
@@ -133,10 +139,9 @@ env-mas: &env-mas
   MAS_BUILD: 'true'
 
 env-mas-apple-silicon: &env-mas-apple-silicon
-  GN_EXTRA_ARGS: 'target_cpu = "arm64" is_mas_build = true use_prebuilt_v8_context_snapshot = true'
+  GN_EXTRA_ARGS: 'target_cpu = "arm64" is_mas_build = true'
   MAS_BUILD: 'true'
   TARGET_ARCH: arm64
-  USE_PREBUILT_V8_CONTEXT_SNAPSHOT: 1
   npm_config_arch: arm64
 
 env-send-slack-notifications: &env-send-slack-notifications
@@ -172,9 +177,6 @@ env-mac-large-release: &env-mac-large-release
 env-ninja-status: &env-ninja-status
   NINJA_STATUS: "[%r processes, %f/%t @ %o/s : %es] "
 
-env-disable-run-as-node: &env-disable-run-as-node
-  GN_BUILDFLAG_ARGS: 'enable_run_as_node = false'
-
 env-32bit-release: &env-32bit-release
   # Set symbol level to 1 for 32 bit releases because of https://crbug.com/648948
   GN_BUILDFLAG_ARGS: 'symbol_level = 1'
@@ -245,14 +247,27 @@ step-depot-tools-get: &step-depot-tools-get
         sed -i '/ninjalog_uploader_wrapper.py/d' ./depot_tools/autoninja
         # Remove swift-format dep from cipd on macOS until we send a patch upstream.
         cd depot_tools
-        patch gclient.py -R \<<'EOF'
-      676,677c676
-      <         packages = dep_value.get('packages', [])
-      <         for package in (x for x in packages if "infra/3pp/tools/swift-format" not in x.get('package')):
-      ---
-      >         for package in dep_value.get('packages', []):
+        cat > gclient.diff \<< 'EOF'
+      diff --git a/gclient.py b/gclient.py
+      index 3a9c5c6..f222043 100755
+      --- a/gclient.py
+      +++ b/gclient.py
+      @@ -712,7 +712,8 @@ class Dependency(gclient_utils.WorkItem, DependencySettings):
+
+             if dep_type == 'cipd':
+               cipd_root = self.GetCipdRoot()
+      -        for package in dep_value.get('packages', []):
+      +        packages = dep_value.get('packages', [])
+      +        for package in (x for x in packages if "infra/3pp/tools/swift-format" not in x.get('package')):
+                 deps_to_add.append(
+                     CipdDependency(
+                         parent=self,
       EOF
+        git apply --3way gclient.diff
       fi
+      # Ensure depot_tools does not update.
+      test -d depot_tools && cd depot_tools
+      touch .disable_auto_update
 
 step-depot-tools-add-to-path: &step-depot-tools-add-to-path
   run:
@@ -274,7 +289,7 @@ step-gclient-sync: &step-gclient-sync
         ELECTRON_USE_THREE_WAY_MERGE_FOR_PATCHES=1 gclient sync --with_branch_heads --with_tags
         if [ "$IS_RELEASE" != "true" ]; then
           # Re-export all the patches to check if there were changes.
-          python src/electron/script/export_all_patches.py src/electron/patches/config.json
+          python3 src/electron/script/export_all_patches.py src/electron/patches/config.json
           cd src/electron
           git update-index --refresh || true
           if ! git diff-index --quiet HEAD --; then
@@ -357,14 +372,14 @@ step-restore-brew-cache: &step-restore-brew-cache
       - /usr/local/Cellar/gnu-tar
       - /usr/local/bin/gtar
     keys:
-      - v5-brew-cache-{{ arch }}
+      - v6-brew-cache-{{ arch }}
 
 step-save-brew-cache: &step-save-brew-cache
   save_cache:
     paths:
       - /usr/local/Cellar/gnu-tar
       - /usr/local/bin/gtar
-    key: v5-brew-cache-{{ arch }}
+    key: v6-brew-cache-{{ arch }}
     name: Persisting brew cache
 
 step-get-more-space-on-mac: &step-get-more-space-on-mac
@@ -380,18 +395,24 @@ step-get-more-space-on-mac: &step-get-more-space-on-mac
           fi
         }
 
-        strip_arm_deep() {
+        strip_universal_deep() {
           opwd=$(pwd)
           cd $1
           f=$(find . -perm +111 -type f)
           for fp in $f
           do
             if [[ $(file "$fp") == *"universal binary"* ]]; then
-              if [[ $(file "$fp") == *"arm64e)"* ]]; then
-                sudo lipo -remove arm64e "$fp" -o "$fp" || true
-              fi
-              if [[ $(file "$fp") == *"arm64)"* ]]; then
-                sudo lipo -remove arm64 "$fp" -o "$fp" || true
+              if [ "`arch`" == "arm64" ]; then
+                if [[ $(file "$fp") == *"x86_64"* ]]; then
+                  sudo lipo -remove x86_64 "$fp" -o "$fp" || true
+                fi
+              else
+                if [[ $(file "$fp") == *"arm64e)"* ]]; then
+                  sudo lipo -remove arm64e "$fp" -o "$fp" || true
+                fi
+                if [[ $(file "$fp") == *"arm64)"* ]]; then
+                  sudo lipo -remove arm64 "$fp" -o "$fp" || true
+                fi
               fi
             fi
           done
@@ -447,12 +468,12 @@ step-get-more-space-on-mac: &step-get-more-space-on-mac
         sudo rm -rf ~/project/src/third_party/angle/third_party/VK-GL-CTS
 
         # lipo off some huge binaries arm64 versions to save space
-        strip_arm_deep $(xcode-select -p)/../SharedFrameworks
+        strip_universal_deep $(xcode-select -p)/../SharedFrameworks
         # strip_arm_deep /System/Volumes/Data/Library/Developer/CommandLineTools/usr
       fi
     background: true
 
-# On macOS delete all .git directories under src/ expect for
+# On macOS delete all .git directories under src/ except for
 # third_party/angle/ and third_party/dawn/ because of build time generation of files
 # gen/angle/commit.h depends on third_party/angle/.git/HEAD
 # https://chromium-review.googlesource.com/c/angle/angle/+/2074924
@@ -506,6 +527,24 @@ step-fix-sync: &step-fix-sync
         # Remove extra output from calling gclient getdep which always calls update_depot_tools
         sed -i '' "s/Updating depot_tools... //g" esbuild_ensure_file
         cipd ensure --root src/third_party/devtools-frontend/src/third_party/esbuild -ensure-file esbuild_ensure_file
+
+        # Fix rustc (wrong binary)
+        rm -rf src/third_party/rust-toolchain
+        python3 src/tools/rust/update_rust.py
+        
+        # Fix gn (wrong binary)
+        echo 'gn/gn/mac-${arch}' `gclient getdep --deps-file=src/DEPS -r 'src/buildtools/mac:gn/gn/mac-${arch}'` > gn_ensure_file
+        # Remove extra output from calling gclient getdep which always calls update_depot_tools
+        sed -i '' "s/Updating depot_tools... //g" gn_ensure_file
+        cipd ensure --root src/buildtools/mac -ensure-file gn_ensure_file
+
+        # Fix dsymutil (wrong binary)
+        if  [ "$TARGET_ARCH" == "arm64" ]; then
+          export DSYM_SHA_FILE=src/tools/clang/dsymutil/bin/dsymutil.arm64.sha1
+        else
+          export DSYM_SHA_FILE=src/tools/clang/dsymutil/bin/dsymutil.x64.sha1
+        fi
+        python3 src/third_party/depot_tools/download_from_google_storage.py --no_resume --no_auth --bucket chromium-browser-clang -s $DSYM_SHA_FILE -o src/tools/clang/dsymutil/bin/dsymutil
       fi
 
       # Make sure we are using the right ninja
@@ -586,7 +625,7 @@ step-electron-chromedriver-build: &step-electron-chromedriver-build
     name: Build chromedriver.zip
     command: |
       cd src
-      if [ "$TARGET_ARCH" == "arm" ] || [ "$TARGET_ARCH" == "arm64" ]; then
+      if [ "`uname`" != "Darwin" ] && ([ "$TARGET_ARCH" == "arm" ] || [ "$TARGET_ARCH" == "arm64" ]); then
         gn gen out/chromedriver --args="import(\"$GN_CONFIG\") import(\"$GN_GOMA_FILE\") is_component_ffmpeg=false proprietary_codecs=false $GN_EXTRA_ARGS $GN_BUILDFLAG_ARGS"
         export CHROMEDRIVER_DIR="out/chromedriver"
       else
@@ -597,7 +636,7 @@ step-electron-chromedriver-build: &step-electron-chromedriver-build
         electron/script/strip-binaries.py --target-cpu="$TARGET_ARCH" --file $PWD/$CHROMEDRIVER_DIR/chromedriver
       fi
       ninja -C $CHROMEDRIVER_DIR electron:electron_chromedriver_zip
-      if [ "$TARGET_ARCH" == "arm" ] || [ "$TARGET_ARCH" == "arm64" ]; then
+      if [ "`uname`" != "Darwin" ] && ([ "$TARGET_ARCH" == "arm" ] || [ "$TARGET_ARCH" == "arm64" ]); then
         cp out/chromedriver/chromedriver.zip out/Default
       fi
 
@@ -606,7 +645,7 @@ step-nodejs-headers-build: &step-nodejs-headers-build
     name: Build Node.js headers
     command: |
       cd src
-      ninja -C out/Default third_party/electron_node:headers
+      ninja -C out/Default electron:node_headers
 
 step-electron-publish: &step-electron-publish
   run:
@@ -674,10 +713,10 @@ step-verify-mksnapshot: &step-verify-mksnapshot
     command: |
       if [ "$IS_ASAN" != "1" ]; then
         cd src
-        if [ "$TARGET_ARCH" == "arm" ] || [ "$TARGET_ARCH" == "arm64" ]; then
-          python electron/script/verify-mksnapshot.py --source-root "$PWD" --build-dir out/Default --snapshot-files-dir $PWD/cross-arch-snapshots
+        if [ "`uname`" != "Darwin" ] && ([ "$TARGET_ARCH" == "arm" ] || [ "$TARGET_ARCH" == "arm64" ]); then
+          python3 electron/script/verify-mksnapshot.py --source-root "$PWD" --build-dir out/Default --snapshot-files-dir $PWD/cross-arch-snapshots
         else
-          python electron/script/verify-mksnapshot.py --source-root "$PWD" --build-dir out/Default
+          python3 electron/script/verify-mksnapshot.py --source-root "$PWD" --build-dir out/Default
         fi
       fi
 
@@ -687,7 +726,7 @@ step-verify-chromedriver: &step-verify-chromedriver
     command: |
       if [ "$IS_ASAN" != "1" ]; then
         cd src
-        python electron/script/verify-chromedriver.py --source-root "$PWD" --build-dir out/Default
+        python3 electron/script/verify-chromedriver.py --source-root "$PWD" --build-dir out/Default
       fi
 
 step-setup-linux-for-headless-testing: &step-setup-linux-for-headless-testing
@@ -717,17 +756,15 @@ step-mksnapshot-build: &step-mksnapshot-build
     no_output_timeout: 30m
     command: |
       cd src
-      if [ "$USE_PREBUILT_V8_CONTEXT_SNAPSHOT" != "1" ]; then
-        ninja -C out/Default electron:electron_mksnapshot -j $NUMBER_OF_NINJA_PROCESSES
-        gn desc out/Default v8:run_mksnapshot_default args > out/Default/mksnapshot_args
-        # Remove unused args from mksnapshot_args
-        SEDOPTION="-i"
-        if [ "`uname`" == "Darwin" ]; then
-          SEDOPTION="-i ''"
-        fi
-        sed $SEDOPTION '/.*builtins-pgo/d' out/Default/mksnapshot_args
-        sed $SEDOPTION '/--turbo-profiling-input/d' out/Default/mksnapshot_args
+      ninja -C out/Default electron:electron_mksnapshot -j $NUMBER_OF_NINJA_PROCESSES
+      gn desc out/Default v8:run_mksnapshot_default args > out/Default/mksnapshot_args
+      # Remove unused args from mksnapshot_args
+      SEDOPTION="-i"
+      if [ "`uname`" == "Darwin" ]; then
+        SEDOPTION="-i ''"
       fi
+      sed $SEDOPTION '/.*builtins-pgo/d' out/Default/mksnapshot_args
+      sed $SEDOPTION '/--turbo-profiling-input/d' out/Default/mksnapshot_args
       if [ "`uname`" != "Darwin" ]; then
         if [ "$TARGET_ARCH" == "arm" ]; then
           electron/script/strip-binaries.py --file $PWD/out/Default/clang_x86_v8_arm/mksnapshot
@@ -740,7 +777,7 @@ step-mksnapshot-build: &step-mksnapshot-build
           electron/script/strip-binaries.py --file $PWD/out/Default/v8_context_snapshot_generator
         fi
       fi
-      if [ "$USE_PREBUILT_V8_CONTEXT_SNAPSHOT" != "1" ] && [ "$SKIP_DIST_ZIP" != "1" ]; then
+      if [ "$SKIP_DIST_ZIP" != "1" ]; then
         ninja -C out/Default electron:electron_mksnapshot_zip -j $NUMBER_OF_NINJA_PROCESSES
         (cd out/Default; zip mksnapshot.zip mksnapshot_args gen/v8/embedded.S)
       fi
@@ -813,7 +850,7 @@ step-maybe-cross-arch-snapshot: &step-maybe-cross-arch-snapshot
         elif [ "`uname`" == "Darwin" ]; then
           cp "out/Default/$MKSNAPSHOT_PATH/libffmpeg.dylib" out/Default
         fi
-        python electron/script/verify-mksnapshot.py --source-root "$PWD" --build-dir out/Default --create-snapshot-only
+        python3 electron/script/verify-mksnapshot.py --source-root "$PWD" --build-dir out/Default --create-snapshot-only
         mkdir cross-arch-snapshots
         cp out/Default-mksnapshot-test/*.bin cross-arch-snapshots
         # Clean up so that ninja does not get confused
@@ -970,7 +1007,6 @@ step-ts-compile: &step-ts-compile
 # List of all steps.
 steps-electron-gn-check: &steps-electron-gn-check
   steps:
-    - install-python2-mac
     - *step-setup-goma-for-build
     - checkout-from-cache
     - *step-setup-env-for-build
@@ -989,31 +1025,6 @@ steps-electron-ts-compile-for-doc-change: &steps-electron-ts-compile-for-doc-cha
 
 # Command Aliases
 commands:
-  install-python2-mac:
-    steps:
-      - restore_cache:
-          keys:
-            - v2.7.18-python-cache-{{ arch }}
-          name: Restore python cache
-      - run:
-          name: Install python2 on macos
-          command: |
-            if [ "`uname`" == "Darwin" ] && [ "$IS_ELECTRON_RUNNER" != "1" ]; then
-              if [ ! -f "python-downloads/python-2.7.18-macosx10.9.pkg" ]; then
-                mkdir python-downloads
-                echo 'Downloading Python 2.7.18'
-                curl -O https://dev-cdn.electronjs.org/python/python-2.7.18-macosx10.9.pkg
-                mv python-2.7.18-macosx10.9.pkg python-downloads
-              else
-                echo 'Using Python install from cache'
-              fi
-              sudo installer -pkg python-downloads/python-2.7.18-macosx10.9.pkg -target /
-            fi
-      - save_cache:
-          paths:
-            - python-downloads
-          key: v2.7.18-python-cache-{{ arch }}
-          name: Persisting python cache
   maybe-restore-portaled-src-cache:
     parameters:
       halt-if-successful:
@@ -1050,7 +1061,7 @@ commands:
       artifact-key:
         type: string
       build-type:
-        type: string      
+        type: string
       build-nonproprietary-ffmpeg:
         type: boolean
         default: true
@@ -1061,7 +1072,7 @@ commands:
           build-type: << parameters.build-type >>
       - *step-maybe-electron-dist-strip
       - step-electron-dist-build:
-          additional-targets: shell_browser_ui_unittests third_party/electron_node:headers third_party/electron_node:overlapped-checker electron:hunspell_dictionaries_zip
+          additional-targets: shell_browser_ui_unittests electron:node_headers third_party/electron_node:overlapped-checker electron:hunspell_dictionaries_zip
 
       - *step-show-goma-stats
 
@@ -1229,32 +1240,6 @@ commands:
           no_output_timeout: 60m
           command: |
             cd src
-
-            # Lets generate a snapshot and mksnapshot and then delete all the x-compiled generated files to save space
-            if [ "$USE_PREBUILT_V8_CONTEXT_SNAPSHOT" == "1" ]; then
-              ninja -C out/Default electron:electron_mksnapshot_zip -j $NUMBER_OF_NINJA_PROCESSES
-              ninja -C out/Default tools/v8_context_snapshot -j $NUMBER_OF_NINJA_PROCESSES
-              gn desc out/Default v8:run_mksnapshot_default args > out/Default/mksnapshot_args
-              # Remove unused args from mksnapshot_args
-              SEDOPTION="-i"
-              if [ "`uname`" == "Darwin" ]; then
-                SEDOPTION="-i ''"
-              fi
-              sed $SEDOPTION '/.*builtins-pgo/d' out/Default/mksnapshot_args
-              sed $SEDOPTION '/--turbo-profiling-input/d' out/Default/mksnapshot_args
-              (cd out/Default; zip mksnapshot.zip mksnapshot_args clang_x64_v8_arm64/gen/v8/embedded.S)
-              if [ "<< parameters.clean-prebuilt-snapshot >>" == "true" ]; then
-                rm -rf out/Default/clang_x64_v8_arm64/gen
-                rm -rf out/Default/clang_x64_v8_arm64/obj
-                rm -rf out/Default/clang_x64_v8_arm64/thinlto-cache
-                rm -rf out/Default/clang_x64/obj
-                # Regenerate because we just deleted some ninja files
-                gn gen out/Default --args="import(\"$GN_CONFIG\") import(\"$GN_GOMA_FILE\") $GN_EXTRA_ARGS $GN_BUILDFLAG_ARGS"
-              fi
-              # For x-compiles this will be built to the wrong arch after the context snapshot build
-              # so we wipe it before re-linking it below
-              rm -rf out/Default/libffmpeg.dylib
-            fi
             NINJA_SUMMARIZE_BUILD=1 autoninja -C out/Default electron -j $NUMBER_OF_NINJA_PROCESSES
             cp out/Default/.ninja_log out/electron_ninja_log
             node electron/script/check-symlinks.js
@@ -1294,7 +1279,7 @@ commands:
       artifact-key:
         type: string
       build-type:
-        type: string        
+        type: string
       after-build-and-save:
         type: steps
         default: []
@@ -1310,7 +1295,6 @@ commands:
             - run: rm -rf src/electron
       - *step-restore-brew-cache
       - *step-install-gnutar-on-mac
-      - install-python2-mac
       - *step-save-brew-cache
       - when:
           condition: << parameters.build >>
@@ -1448,6 +1432,8 @@ commands:
                         - src/build/linux
                         - src/buildtools/third_party/libc++
                         - src/buildtools/third_party/libc++abi
+                        - src/third_party/libc++
+                        - src/third_party/libc++abi
                         - src/out/Default/obj/buildtools/third_party
                         - src/v8/tools/builtins-pgo
                   - steps: << parameters.after-persist >>
@@ -1471,7 +1457,6 @@ commands:
       - *step-setup-linux-for-headless-testing
       - *step-restore-brew-cache
       - *step-fix-known-hosts-linux
-      - install-python2-mac
       - *step-install-signing-cert-on-mac
 
       - run:
@@ -1492,7 +1477,7 @@ commands:
               export LLVM_SYMBOLIZER_PATH=$PWD/third_party/llvm-build/Release+Asserts/bin/llvm-symbolizer
               export MOCHA_TIMEOUT=180000
               echo "Piping output to ASAN_SYMBOLIZE ($ASAN_SYMBOLIZE)"
-              (cd electron && node script/yarn test --runners=main --trace-uncaught --enable-logging --files $(circleci tests glob spec/*-spec.ts | circleci tests split --split-by=timings)) 2>&1 | $ASAN_SYMBOLIZE
+              (cd electron && (circleci tests glob "spec/*-spec.ts" | circleci tests run --command="xargs node script/yarn test --runners=main --trace-uncaught --enable-logging --files" --split-by=timings 2>&1)) | $ASAN_SYMBOLIZE
             else
               if [ "$TARGET_ARCH" == "arm" ] || [ "$TARGET_ARCH" == "arm64" ]; then
                 export ELECTRON_SKIP_NATIVE_MODULE_TESTS=true
@@ -1501,18 +1486,9 @@ commands:
                 if [ "$TARGET_ARCH" == "ia32" ]; then
                   npm_config_arch=x64 node electron/node_modules/dugite/script/download-git.js
                 fi
-                (cd electron && node script/yarn test --runners=main --trace-uncaught --enable-logging --files $(circleci tests glob spec/*-spec.ts | circleci tests split --split-by=timings))
+                (cd electron && (circleci tests glob "spec/*-spec.ts" | circleci tests run --command="xargs node script/yarn test --runners=main --trace-uncaught --enable-logging --files" --split-by=timings))
               fi
             fi
-      - run:
-          name: Check test results existence
-          command: |
-            cd src
-
-            # Check if test results exist and are not empty.
-            if [ ! -s "junit/test-results-main.xml" ]; then
-              exit 1
-            fi
       - store_test_results:
           path: src/junit
 
@@ -1581,7 +1557,6 @@ commands:
             - *step-depot-tools-get
       - *step-depot-tools-add-to-path
       - *step-restore-brew-cache
-      - install-python2-mac
       - *step-get-more-space-on-mac
       - when:
           condition: << parameters.checkout >>
@@ -1595,6 +1570,7 @@ commands:
             - *step-minimize-workspace-size-from-checkout
       - *step-fix-sync
       - *step-setup-env-for-build
+      - *step-fix-known-hosts-linux
       - *step-setup-goma-for-build
       - *step-wait-for-goma
       - *step-gn-gen-default
@@ -1685,7 +1661,7 @@ jobs:
           artifact-key: 'nil'
           build-type: 'nil'
 
-  mac-make-src-cache:
+  mac-make-src-cache-x64:
     executor:
       name: linux-docker
       size: xlarge
@@ -1704,11 +1680,30 @@ jobs:
           artifact-key: 'nil'
           build-type: 'nil'
 
+  mac-make-src-cache-arm64:
+    executor:
+      name: linux-docker
+      size: xlarge
+    environment:
+      <<: *env-linux-2xlarge
+      <<: *env-testing-build
+      <<: *env-macos-build
+      GCLIENT_EXTRA_ARGS: '--custom-var=checkout_mac=True --custom-var=host_os=mac --custom-var=host_cpu=arm64'
+    steps:
+      - electron-build:
+          persist: false
+          build: false
+          checkout: true
+          save-git-cache: true
+          checkout-to-create-src-cache: true
+          artifact-key: 'nil'
+          build-type: 'nil'
+
   # Layer 2: Builds.
   linux-x64-testing:
     executor:
       name: linux-docker
-      size: xlarge
+      size: electronjs/aks-linux-large
     environment:
       <<: *env-global
       <<: *env-testing-build
@@ -1725,7 +1720,7 @@ jobs:
   linux-x64-testing-asan:
     executor:
       name: linux-docker
-      size: 2xlarge
+      size: electronjs/aks-linux-large
     environment:
       <<: *env-global
       <<: *env-testing-build
@@ -1741,23 +1736,6 @@ jobs:
           artifact-key: 'linux-x64-asan'
           build-type: 'Linux'
 
-  linux-x64-testing-no-run-as-node:
-    executor:
-      name: linux-docker
-      size: xlarge
-    environment:
-      <<: *env-linux-2xlarge
-      <<: *env-testing-build
-      <<: *env-ninja-status
-      <<: *env-disable-run-as-node
-      GCLIENT_EXTRA_ARGS: '--custom-var=checkout_arm=True --custom-var=checkout_arm64=True'
-    steps:
-      - electron-build:
-          persist: false
-          checkout: true
-          artifact-key: 'linux-x64-no-run-as-node'
-          build-type: 'Linux'
-
   linux-x64-testing-gn-check:
     executor:
       name: linux-docker
@@ -1771,7 +1749,7 @@ jobs:
   linux-x64-publish:
     executor:
       name: linux-docker
-      size: 2xlarge
+      size: electronjs/aks-linux-large
     environment:
       <<: *env-linux-2xlarge-release
       <<: *env-release-build
@@ -1794,7 +1772,7 @@ jobs:
   linux-arm-testing:
     executor:
       name: linux-docker
-      size: 2xlarge
+      size: electronjs/aks-linux-large
     environment:
       <<: *env-global
       <<: *env-arm
@@ -1814,7 +1792,7 @@ jobs:
   linux-arm-publish:
     executor:
       name: linux-docker
-      size: 2xlarge
+      size: electronjs/aks-linux-large
     environment:
       <<: *env-linux-2xlarge-release
       <<: *env-arm
@@ -1839,7 +1817,7 @@ jobs:
   linux-arm64-testing:
     executor:
       name: linux-docker
-      size: 2xlarge
+      size: electronjs/aks-linux-large
     environment:
       <<: *env-global
       <<: *env-arm64
@@ -1870,7 +1848,7 @@ jobs:
   linux-arm64-publish:
     executor:
       name: linux-docker
-      size: 2xlarge
+      size: electronjs/aks-linux-large
     environment:
       <<: *env-linux-2xlarge-release
       <<: *env-arm64
@@ -1961,7 +1939,7 @@ jobs:
   osx-publish-arm64:
     executor:
       name: macos
-      size: macos.x86.medium.gen2
+      size: macos.m1.large.gen1
     environment:
       <<: *env-mac-large-release
       <<: *env-release-build
@@ -1984,7 +1962,7 @@ jobs:
   osx-testing-arm64:
     executor:
       name: macos
-      size: macos.x86.medium.gen2
+      size: macos.m1.medium.gen1
     environment:
       <<: *env-mac-large
       <<: *env-testing-build
@@ -1992,7 +1970,6 @@ jobs:
       <<: *env-macos-build
       <<: *env-apple-silicon
       GCLIENT_EXTRA_ARGS: '--custom-var=checkout_mac=True --custom-var=host_os=mac'
-      GENERATE_CROSS_ARCH_SNAPSHOT: true
     steps:
       - electron-build:
           persist: true
@@ -2043,7 +2020,7 @@ jobs:
   mas-publish-arm64:
     executor:
       name: macos
-      size: macos.x86.medium.gen2
+      size: macos.m1.large.gen1
     environment:
       <<: *env-mac-large-release
       <<: *env-mas-apple-silicon
@@ -2142,6 +2119,7 @@ jobs:
     executor:
       name: macos
       size: macos.x86.medium.gen2
+      version: 14.0.0
     environment:
       <<: *env-mac-large
       <<: *env-stack-dumping
@@ -2165,6 +2143,7 @@ jobs:
     executor:
       name: macos
       size: macos.x86.medium.gen2
+      version: 14.0.0
     environment:
       <<: *env-mac-large
       <<: *env-stack-dumping
@@ -2240,9 +2219,6 @@ workflows:
       - linux-x64-testing-asan:
           requires:
             - linux-make-src-cache
-      - linux-x64-testing-no-run-as-node:
-          requires:
-            - linux-make-src-cache
       - linux-x64-testing-gn-check:
           requires:
             - linux-make-src-cache
@@ -2289,19 +2265,20 @@ workflows:
         - equal: [false, << pipeline.parameters.run-linux-publish >>]
         - equal: [true, << pipeline.parameters.run-build-mac >>]
     jobs:
-      - mac-make-src-cache
+      - mac-make-src-cache-x64
+      - mac-make-src-cache-arm64
       - osx-testing-x64:
           requires:
-            - mac-make-src-cache
+            - mac-make-src-cache-x64
       - osx-testing-x64-gn-check:
           requires:
-            - mac-make-src-cache
+            - mac-make-src-cache-x64
       - darwin-testing-x64-tests:
           requires:
             - osx-testing-x64
       - osx-testing-arm64:
           requires:
-            - mac-make-src-cache
+            - mac-make-src-cache-arm64
       - darwin-testing-arm64-tests:
           filters:
             branches:

+ 3 - 2
.circleci/fix-known-hosts.sh

@@ -3,5 +3,6 @@
 set -e
 
 mkdir -p ~/.ssh
-echo "|1|B3r+7aO0/x90IdefihIjxIoJrrk=|OJddGDfhbuLFc1bUyy84hhIw57M= ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ==
-|1|rGlEvW55DtzNZp+pzw9gvyOyKi4=|LLWr+7qlkAlw3YGGVfLHHxB/kR0= ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ==" >> ~/.ssh/known_hosts
+echo "github.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOMqqnkVzrm0SdG6UOoqKLsabgH5C9okWi0dh2l9GKJl
+github.com ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBEmKSENjQEezOmxkZMy7opKgwFB9nkt5YRrYMjNuG5N87uRgg6CLrbo5wAdT/y6v0mKV0U2w0WZ2YB/++Tpockg=
+github.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCj7ndNxQowgcQnjshcLrqPEiiphnt+VTTvDP6mHBL9j1aNUkY4Ue1gvwnGLVlOhGeYrnZaMgRK6+PKCUXaDbC7qtbW8gIkhL7aGCsOr/C56SJMy/BCZfxd1nWzAOxSDPgVsmerOBYfNqltV9/hWCqBywINIR+5dIg6JTJ72pcEpEjcYgXkE2YEFXV1JHnsKgbLWNlhScqb2UmyRkQyytRLtL+38TGxkxCflmO+5Z8CSSNY7GidjMIZ7Q4zMjA2n1nGrlTDkzwDCsw+wqFPGQA179cnfGWOWRVruj16z6XyvxvjJwbz0wQZ75XK5tKSb7FNyeIEs4TT4jk+S4dhPeAUC5y+bDYirYgM4GC7uEnztnZyaVWQ7B381AK4Qdrwt51ZqExKbQpTUNn+EjqoTwvqNj4kqx5QUCI0ThS/YkOxJCXmPUWZbhjpCg56i+2aB6CmK2JGhn57K5mj0MNdBXA4/WnwH6XoPWJzK5Nyu2zB3nAZp+S5hpQs+p1vN1/wsjk=" >> ~/.ssh/known_hosts

+ 4 - 0
.clang-tidy

@@ -0,0 +1,4 @@
+---
+Checks: '-modernize-use-nullptr'
+InheritParentConfig: true
+...

+ 32 - 31
.devcontainer/devcontainer.json

@@ -4,37 +4,6 @@
 	"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": {
@@ -60,6 +29,38 @@
 			"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"
+			}
 		}
 	}
 }

+ 10 - 4
.devcontainer/on-create-command.sh

@@ -16,6 +16,8 @@ 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\",
@@ -32,6 +34,8 @@ 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 "
         {
@@ -41,7 +45,7 @@ if [ ! -f $buildtools/configs/evm.testing.json ]; then
                 \"electron\": {
                     \"origin\": \"https://github.com/electron/electron.git\"
                 }
-            }
+            },
             \"gen\": {
                 \"args\": [
                     \"import(\\\"//electron/build/args/testing.gn\\\")\",
@@ -53,7 +57,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
   }
@@ -67,10 +71,12 @@ 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
-  # Even if the config file existed we still need to re-auth with the goma
-  # cluster
+  echo "build-tools testing config already exists"
+
+  # Re-auth with the goma cluster regardless.
   NOTGOMA_CODESPACES_TOKEN=$GITHUB_TOKEN e d goma_auth login || true
 fi

+ 1 - 9
.eslintrc.json

@@ -10,7 +10,6 @@
     "semi": ["error", "always"],
     "no-var": "error",
     "no-unused-vars": "off",
-    "no-global-assign": "off",
     "guard-for-in": "error",
     "@typescript-eslint/no-unused-vars": ["error", {
       "vars": "all",
@@ -20,20 +19,13 @@
     "prefer-const": ["error", {
       "destructuring": "all"
     }],
-    "standard/no-callback-literal": "off",
-    "node/no-deprecated-api": "off"
+    "standard/no-callback-literal": "off"
   },
   "parserOptions": {
     "ecmaVersion": 6,
     "sourceType": "module"
   },
   "overrides": [
-    {
-      "files": "*.js",
-      "rules": {
-        "@typescript-eslint/no-unused-vars": "off"
-      }
-    },
     {
       "files": "*.ts",
       "rules": {

+ 20 - 5
.gitattributes

@@ -4,12 +4,27 @@
 patches/**/.patches merge=union
 
 # Source code and markdown files should always use LF as line ending.
+*.c text eol=lf
 *.cc text eol=lf
-*.mm text eol=lf
+*.cpp text eol=lf
+*.csv text eol=lf
+*.grd   text eol=lf
+*.grdp   text eol=lf
+*.gn text eol=lf
+*.gni text eol=lf
 *.h text eol=lf
-*.js text eol=lf
-*.ts text eol=lf
+*.html   text eol=lf
+*.idl text eol=lf
+*.in   text eol=lf
+*.js   text eol=lf
+*.json   text eol=lf
+*.json5 text eol=lf
+*.md text eol=lf
+*.mm text eol=lf
+*.mojom text eol=lf
+*.proto text eol=lf
 *.py text eol=lf
 *.ps1 text eol=lf
-*.html text eol=lf
-*.md text eol=lf
+*.sh text eol=lf
+*.ts text eol=lf
+*.txt   text eol=lf

+ 0 - 1
.github/CODEOWNERS

@@ -15,6 +15,5 @@ DEPS                                    @electron/wg-upgrades
 # Security WG
 /lib/browser/devtools.ts                @electron/wg-security
 /lib/browser/guest-view-manager.ts      @electron/wg-security
-/lib/browser/guest-window-proxy.ts      @electron/wg-security
 /lib/browser/rpc-server.ts              @electron/wg-security
 /lib/renderer/security-warnings.ts      @electron/wg-security

+ 1 - 0
.github/ISSUE_TEMPLATE/bug_report.yml

@@ -2,6 +2,7 @@ name: Bug Report
 description: Report an Electron bug
 title: "[Bug]: "
 labels: "bug :beetle:"
+projects: ["electron/90"]
 body:
 - type: checkboxes
   attributes:

+ 166 - 0
.github/workflows/branch-created.yml

@@ -0,0 +1,166 @@
+name: Branch Created
+
+on:
+  create:
+
+permissions: {}
+
+jobs:
+  release-branch-created:
+    name: Release Branch Created
+    if: ${{ github.event.ref_type == 'branch' && endsWith(github.event.ref, '-x-y') }}
+    permissions:
+      contents: read
+      pull-requests: write
+      repository-projects: write  # Required for labels
+    runs-on: ubuntu-latest
+    steps:
+      - name: Determine Major Version
+        id: check-major-version
+        run: |
+          if [[ ${{ github.event.ref }} =~ ^([0-9]+)-x-y$ ]]; then
+            echo "MAJOR=${BASH_REMATCH[1]}" >> "$GITHUB_OUTPUT"
+          else
+            echo "Not a release branch: ${{ github.event.ref }}"
+          fi
+      - name: New Release Branch Tasks
+        if: ${{ steps.check-major-version.outputs.MAJOR }}
+        env:
+          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+          GH_REPO: electron/electron
+          MAJOR: ${{ steps.check-major-version.outputs.MAJOR }}
+          NUM_SUPPORTED_VERSIONS: 3
+        run: |
+          PREVIOUS_MAJOR=$((MAJOR - 1))
+          UNSUPPORTED_MAJOR=$((MAJOR - NUM_SUPPORTED_VERSIONS - 1))
+
+          # Create new labels
+          gh label create $MAJOR-x-y --color 8d9ee8 || true
+          gh label create target/$MAJOR-x-y --color ad244f --description "PR should also be added to the \"${MAJOR}-x-y\" branch." || true
+          gh label create merged/$MAJOR-x-y --color 61a3c6 --description "PR was merged to the \"${MAJOR}-x-y\" branch." || true
+          gh label create in-flight/$MAJOR-x-y --color db69a6 || true
+          gh label create needs-manual-bp/$MAJOR-x-y --color 8b5dba || true
+
+          # Change color of old labels
+          gh label edit $UNSUPPORTED_MAJOR-x-y --color ededed || true
+          gh label edit target/$UNSUPPORTED_MAJOR-x-y --color ededed || true
+          gh label edit merged/$UNSUPPORTED_MAJOR-x-y --color ededed || true
+          gh label edit in-flight/$UNSUPPORTED_MAJOR-x-y --color ededed || true
+          gh label edit needs-manual-bp/$UNSUPPORTED_MAJOR-x-y --color ededed || true
+
+          # Add the new target label to any PRs which:
+          #   * target the previous major
+          #   * are in-flight for the previous major
+          #   * need manual backport for the previous major
+          for PREVIOUS_MAJOR_LABEL in target/$PREVIOUS_MAJOR-x-y in-flight/$PREVIOUS_MAJOR-x-y needs-manual-bp/$PREVIOUS_MAJOR-x-y; do
+            PULL_REQUESTS=$(gh pr list --label $PREVIOUS_MAJOR_LABEL --jq .[].number --json number --limit 500)
+            if [[ $PULL_REQUESTS ]]; then
+              echo $PULL_REQUESTS | xargs -n 1 gh pr edit --add-label target/$MAJOR-x-y || true
+            fi
+          done
+      - name: Generate GitHub App token
+        if: ${{ steps.check-major-version.outputs.MAJOR }}
+        id: generate-token
+        env:
+          RELEASE_BOARD_GH_APP_CREDS: ${{ secrets.RELEASE_BOARD_GH_APP_CREDS }}
+        run: |
+          TOKEN=$(npx @electron/github-app-auth --creds=$RELEASE_BOARD_GH_APP_CREDS --org=electron)
+          echo "TOKEN=$TOKEN" >> "$GITHUB_OUTPUT"
+      - name: Create Release Project Board
+        if: ${{ steps.check-major-version.outputs.MAJOR }}
+        env:
+          GITHUB_TOKEN: ${{ steps.generate-token.outputs.TOKEN }}
+          MAJOR: ${{ steps.check-major-version.outputs.MAJOR }}
+          ELECTRON_ORG_ID: "O_kgDOAMybxg"
+          ELECTRON_REPO_ID: "R_kgDOAI8xSw"
+          TEMPLATE_PROJECT_ID: "PVT_kwDOAMybxs4AQvib"
+        run: |
+          # Copy template to create new project board
+          PROJECT_ID=$(gh api graphql -f query='mutation ($ownerId: ID!, $projectId: ID!, $title: String!) {  
+            copyProjectV2(input: {
+              includeDraftIssues: true,
+              ownerId: $ownerId,
+              projectId: $projectId,
+              title: $title
+            }) {
+              projectV2 {
+                id
+              }
+            }
+          }' -f ownerId=$ELECTRON_ORG_ID -f projectId=$TEMPLATE_PROJECT_ID -f title="${MAJOR}-x-y" | jq -r '.data.copyProjectV2.projectV2.id')
+
+          # Make the new project public
+          gh api graphql -f query='mutation ($projectId: ID!) {                                                                                             
+            updateProjectV2(input: {
+              projectId: $projectId,
+              public: true,
+            }) {
+              projectV2 {
+                id
+              }
+            }
+          }' -f projectId=$PROJECT_ID
+
+          # Link the new project to the Electron repository
+          gh api graphql -f query='mutation ($projectId: ID!, $repositoryId: ID!) {                                                                                             
+            linkProjectV2ToRepository(input: {
+              projectId: $projectId,
+              repositoryId: $repositoryId
+            }) {
+              clientMutationId
+            }
+          }' -f projectId=$PROJECT_ID -f repositoryId=$ELECTRON_REPO_ID
+
+          # Get all draft issues on the new project board
+          gh api graphql -f query='query ($id: ID!) {
+            node(id: $id) {
+              ... on ProjectV2 {
+                items(first: 100) {
+                  nodes {
+                    ... on ProjectV2Item {
+                      id
+                      content {
+                        ... on DraftIssue { id title
+                          body
+                        }
+                      }
+                    }
+                  }
+                }
+              }
+            }
+          }' -f id=$PROJECT_ID > issues.json
+          PROJECT_ITEMS=$(jq '.data.node.items.nodes[] | select(.content.id != null) | .id' issues.json)
+
+          #
+          # Do template replacement for draft issues
+          #
+          echo "{\"major\": $MAJOR, \"next-major\": $((MAJOR + 1)), \"prev-major\": $((MAJOR - 1))}" > variables.json
+
+          # npx mustache is annoyingly slow, so install mustache directly
+          yarn add -D mustache
+
+          for PROJECT_ITEM_ID in $PROJECT_ITEMS; do
+            # These are done with the raw output flag and sent to file to better retain formatting
+            jq -r ".data.node.items.nodes[] | select(.id == $PROJECT_ITEM_ID) | .content.title" issues.json > title.txt
+            jq -r ".data.node.items.nodes[] | select(.id == $PROJECT_ITEM_ID) | .content.body" issues.json > body.txt
+
+            ./node_modules/.bin/mustache variables.json title.txt new_title.txt
+            ./node_modules/.bin/mustache variables.json body.txt new_body.txt
+
+            # Only update draft issues which had content change when interpolated
+            if ! cmp --silent -- new_title.txt title.txt || ! cmp --silent -- new_body.txt body.txt; then
+              DRAFT_ISSUE_ID=$(jq ".data.node.items.nodes[] | select(.id == $PROJECT_ITEM_ID) | .content.id" issues.json)
+              gh api graphql -f query='mutation ($draftIssueId: ID!, $title: String!, $body: String!) {                                                                                             
+                updateProjectV2DraftIssue(input: {
+                  draftIssueId: $draftIssueId,
+                  title: $title,
+                  body: $body
+                }) {
+                  draftIssue {
+                    id
+                  }
+                }
+              }' -f draftIssueId=$DRAFT_ISSUE_ID -f title="$(cat new_title.txt)" -f body="$(cat new_body.txt)"
+            fi
+          done

+ 24 - 0
.github/workflows/issue-commented.yml

@@ -0,0 +1,24 @@
+name: Issue Commented
+
+on:
+  issue_comment:
+    types:
+      - created
+
+permissions:
+  contents: read
+
+jobs:
+  issue-commented:
+    name: Remove blocked/need-repro on comment
+    if: ${{ contains(github.event.issue.labels.*.name, 'blocked/need-repro') && !contains(fromJSON('["MEMBER", "OWNER"]'), github.event.comment.author_association) }}
+    permissions:
+      issues: write
+    runs-on: ubuntu-latest
+    steps:
+      - name: Remove label
+        env:
+          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+          ISSUE_URL: ${{ github.event.issue.html_url }}
+        run: |
+          gh issue edit $ISSUE_URL --remove-label 'blocked/need-repro'

+ 43 - 5
.github/workflows/issue-labeled.yml

@@ -8,21 +8,59 @@ permissions:  # added using https://github.com/step-security/secure-workflows
   contents: read
 
 jobs:
-  issue-labeled:
+  issue-labeled-blocked:
+    name: blocked/* label added
+    if: startsWith(github.event.label.name, 'blocked/')
+    runs-on: ubuntu-latest
+    steps:
+      - name: Generate GitHub App token
+        id: generate-token
+        env:
+          RELEASE_BOARD_GH_APP_CREDS: ${{ secrets.RELEASE_BOARD_GH_APP_CREDS }}
+        run: |
+          set -eo pipefail
+          TOKEN=$(npx @electron/github-app-auth --creds=$RELEASE_BOARD_GH_APP_CREDS --org=electron)
+          echo "TOKEN=$TOKEN" >> "$GITHUB_OUTPUT"
+      - name: Set status
+        if: ${{ steps.generate-token.outputs.TOKEN }}
+        uses: github/update-project-action@2d475e08804f11f4022df7e21f5816531e97cb64 # v2
+        with:
+          github_token: ${{ steps.generate-token.outputs.TOKEN }}
+          organization: electron
+          project_number: 90
+          content_id: ${{ github.event.issue.node_id }}
+          field: Status
+          value: 🛑 Blocked
+  issue-labeled-blocked-need-repro:
+    name: blocked/need-repro label added
+    if: github.event.label.name == 'blocked/need-repro'
     permissions:
       issues: write  # for actions-cool/issues-helper to update issues
     runs-on: ubuntu-latest
     steps:
-      - name: blocked/need-repro label added
-        if: github.event.label.name == 'blocked/need-repro'
-        uses: actions-cool/issues-helper@dad28fdb88da5f082c04659b7373d85790f9b135 # v3.3.0
+      - name: Check if comment needed
+        id: check-for-comment
+        env:
+          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+          GH_REPO: electron/electron
+        run: |
+          set -eo pipefail
+          COMMENT_COUNT=$(gh issue view ${{ github.event.issue.number }} --comments --json comments | jq '[ .comments[] | select(.author.login == "github-actions" or .authorAssociation == "OWNER" or .authorAssociation == "MEMBER") | select(.body | startswith("<!-- blocked/need-repro -->")) ] | length')
+          if [[ $COMMENT_COUNT -eq 0 ]]; then
+            echo "SHOULD_COMMENT=1" >> "$GITHUB_OUTPUT"
+          fi
+      - name: Create comment
+        if: ${{ steps.check-for-comment.outputs.SHOULD_COMMENT }}
+        uses: actions-cool/issues-helper@275328970dbc3bfc3bc43f5fe741bf3638300c0a # v3.3.3
         with:
           actions: 'create-comment'
           body: |
+            <!-- blocked/need-repro -->
+
             Hello @${{ github.event.issue.user.login }}. Thanks for reporting this and helping to make Electron better!
 
             Would it be possible for you to make a standalone testcase with only the code necessary to reproduce the issue? For example, [Electron Fiddle](https://www.electronjs.org/fiddle) is a great tool for making small test cases and makes it easy to publish your test case to a [gist](https://gist.github.com) that Electron maintainers can use.
 
             Stand-alone test cases make fixing issues go more smoothly: it ensure everyone's looking at the same issue, it removes all unnecessary variables from the equation, and it can also provide the basis for automated regression tests.
 
-            Now adding the `blocked/need-repro` label for this reason. After you make a test case, please link to it in a followup comment. This issue will be closed in 10 days if the above is not addressed.
+            Now adding the https://github.com/electron/electron/labels/blocked%2Fneed-repro label for this reason. After you make a test case, please link to it in a followup comment. This issue will be closed in 10 days if the above is not addressed.

+ 42 - 0
.github/workflows/issue-unlabeled.yml

@@ -0,0 +1,42 @@
+name: Issue Unlabeled
+
+on:
+  issues:
+    types: [unlabeled]
+
+permissions:
+  contents: read
+
+jobs:
+  issue-unlabeled-blocked:
+    name: All blocked/* labels removed
+    if: startsWith(github.event.label.name, 'blocked/')
+    runs-on: ubuntu-latest
+    steps:
+      - name: Check for any blocked labels
+        id: check-for-blocked-labels
+        run: |
+          set -eo pipefail
+          BLOCKED_LABEL_COUNT=$(echo '${{ toJSON(github.event.issue.labels.*.name) }}' | jq '[ .[] | select(startswith("blocked/")) ] | length')
+          if [[ $BLOCKED_LABEL_COUNT -eq 0 ]]; then
+            echo "NOT_BLOCKED=1" >> "$GITHUB_OUTPUT"
+          fi
+      - name: Generate GitHub App token
+        if: ${{ steps.check-for-blocked-labels.outputs.NOT_BLOCKED }}
+        id: generate-token
+        env:
+          RELEASE_BOARD_GH_APP_CREDS: ${{ secrets.RELEASE_BOARD_GH_APP_CREDS }}
+        run: |
+          set -eo pipefail
+          TOKEN=$(npx @electron/github-app-auth --creds=$RELEASE_BOARD_GH_APP_CREDS --org=electron)
+          echo "TOKEN=$TOKEN" >> "$GITHUB_OUTPUT"
+      - name: Set status
+        if: ${{ steps.generate-token.outputs.TOKEN }}
+        uses: github/update-project-action@2d475e08804f11f4022df7e21f5816531e97cb64 # v2
+        with:
+          github_token: ${{ steps.generate-token.outputs.TOKEN }}
+          organization: electron
+          project_number: 90
+          content_id: ${{ github.event.issue.node_id }}
+          field: Status
+          value: 📥 Was Blocked

+ 33 - 0
.github/workflows/pull-request-labeled.yml

@@ -0,0 +1,33 @@
+name: Pull Request Labeled
+
+on:
+  pull_request:
+    types: [labeled]
+
+permissions:
+  contents: read
+
+jobs:
+  pull-request-labeled-deprecation-review-complete:
+    name: deprecation-review/complete label added
+    if: github.event.label.name == 'deprecation-review/complete ✅'
+    runs-on: ubuntu-latest
+    steps:
+      - name: Generate GitHub App token
+        id: generate-token
+        env:
+          RELEASE_BOARD_GH_APP_CREDS: ${{ secrets.RELEASE_BOARD_GH_APP_CREDS }}
+        run: |
+          set -eo pipefail
+          TOKEN=$(npx @electron/github-app-auth --creds=$RELEASE_BOARD_GH_APP_CREDS --org=electron)
+          echo "TOKEN=$TOKEN" >> "$GITHUB_OUTPUT"
+      - name: Set status
+        if: ${{ steps.generate-token.outputs.TOKEN }}
+        uses: dsanders11/update-project-action@7ade91760df70df76770a238abee7a4869e01cf8
+        with:
+          github_token: ${{ steps.generate-token.outputs.TOKEN }}
+          organization: electron
+          project_number: 94
+          content_id: ${{ github.event.pull_request.node_id }}
+          field: Status
+          value: ✅ Reviewed

+ 0 - 33
.github/workflows/release_dependency_versions.yml

@@ -1,33 +0,0 @@
-name: Trigger Major Release Dependency Updates
-
-on:
-  release:
-    types: [published]
-
-env:
-  GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
-
-jobs:
-  trigger_chromedriver:
-    runs-on: ubuntu-latest
-    steps:
-    - uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 # tag: v3
-    - name: Trigger New chromedriver Release
-      run: |
-        if [[ ${{ github.event.release.tag_name }} =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
-          gh api /repos/:owner/chromedriver/actions/workflows/release.yml/dispatches --input - <<< '{"ref":"main","inputs":{"version":"${{ github.event.release.tag_name }}"}}'
-        else
-          echo "Not releasing for version ${{ github.event.release.tag_name }}"
-        fi
-
-  trigger_mksnapshot:
-    runs-on: ubuntu-latest
-    steps:
-      - uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 # tag: v3
-      - name: Trigger New mksnapshot Release
-        run: |
-          if [[ ${{ github.event.release.tag_name }} =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
-            gh api /repos/:owner/mksnapshot/actions/workflows/release.yml/dispatches --input - <<< '{"ref":"main","inputs":{"version":"${{ github.event.release.tag_name }}"}}'
-          else
-            echo "Not releasing for version ${{ github.event.release.tag_name }}"
-          fi

+ 2 - 1
.github/workflows/stale.yml

@@ -22,7 +22,7 @@ jobs:
             This issue has been automatically marked as stale. **If this issue is still affecting you, please leave any comment** (for example, "bump"), and we'll keep it open. If you have any new additional information—in particular, if this is still reproducible in the [latest version of Electron](https://www.electronjs.org/releases/stable) or in the [beta](https://www.electronjs.org/releases/beta)—please include it with your comment!
           close-issue-message: >
             This issue has been closed due to inactivity, and will not be monitored.  If this is a bug and you can reproduce this issue on a [supported version of Electron](https://www.electronjs.org/docs/latest/tutorial/electron-timelines#timeline) please open a new issue and include instructions for reproducing the issue.
-          exempt-issue-labels: "discussion,security \U0001F512,enhancement :sparkles:"
+          exempt-issue-labels: "discussion,security \U0001F512,enhancement :sparkles:,status/confirmed"
           only-pr-labels: not-a-real-label
   pending-repro:
     runs-on: ubuntu-latest
@@ -33,6 +33,7 @@ jobs:
         with:
           days-before-stale: -1
           days-before-close: 10
+          remove-stale-when-updated: false
           stale-issue-label: blocked/need-repro
           stale-pr-label: not-a-real-label
           operations-per-run: 1750

+ 3 - 1
.github/workflows/update_appveyor_image.yml

@@ -66,7 +66,9 @@ jobs:
         signoff: false
         branch: bump-appveyor-image
         delete-branch: true
+        reviewers: electron/wg-releases
         title: 'build: update appveyor image to latest version'
+        labels: semver/none,no-backport
         body: |
           This PR updates appveyor.yml to the latest baked image, ${{ env.APPVEYOR_IMAGE_VERSION }}.
-          Notes: none
+          Notes: none

+ 1 - 25
.markdownlint.json

@@ -1,27 +1,3 @@
 {
-  "commands-show-output": false,
-  "first-line-h1": false,
-  "header-increment": false,
-  "line-length": {
-    "code_blocks": false,
-    "tables": false,
-    "stern": true,
-    "line_length": -1
-  },
-  "no-bare-urls": false,
-  "no-blanks-blockquote": false,
-  "no-duplicate-header": {
-    "allow_different_nesting": true
-  },
-  "no-emphasis-as-header": false,
-  "no-hard-tabs": {
-    "code_blocks": false
-  },
-  "no-space-in-emphasis": false,
-  "no-trailing-punctuation": false,
-  "no-trailing-spaces": {
-    "br_spaces": 0
-  },
-  "single-h1": false,
-  "no-inline-html": false
+  "extends": "@electron/lint-roller/configs/markdownlint.json"
 }

+ 83 - 71
BUILD.gn

@@ -9,6 +9,7 @@ import("//pdf/features.gni")
 import("//ppapi/buildflags/buildflags.gni")
 import("//printing/buildflags/buildflags.gni")
 import("//testing/test.gni")
+import("//third_party/electron_node/node.gni")
 import("//third_party/ffmpeg/ffmpeg_options.gni")
 import("//tools/generate_library_loader/generate_library_loader.gni")
 import("//tools/grit/grit_rule.gni")
@@ -37,7 +38,7 @@ if (is_mac) {
   import("build/rules.gni")
 
   assert(
-      mac_deployment_target == "10.13",
+      mac_deployment_target == "10.15",
       "Chromium has updated the mac_deployment_target, please update this assert, update the supported versions documentation (docs/tutorial/support.md) and flag this as a breaking change")
 }
 
@@ -99,10 +100,6 @@ if (is_linux) {
   }
 }
 
-declare_args() {
-  use_prebuilt_v8_context_snapshot = false
-}
-
 branding = read_file("shell/app/BRANDING.json", "json")
 electron_project_name = branding.project_name
 electron_product_name = branding.product_name
@@ -461,6 +458,7 @@ source_set("electron_lib") {
     "//services/proxy_resolver:lib",
     "//services/video_capture/public/mojom:constants",
     "//services/viz/privileged/mojom/compositing",
+    "//services/viz/public/mojom",
     "//skia",
     "//third_party/blink/public:blink",
     "//third_party/blink/public:blink_devtools_inspector_resources",
@@ -474,6 +472,7 @@ source_set("electron_lib") {
     "//third_party/widevine/cdm:headers",
     "//third_party/zlib/google:zip",
     "//ui/base/idle",
+    "//ui/compositor",
     "//ui/events:dom_keycode_converter",
     "//ui/gl",
     "//ui/native_theme",
@@ -555,6 +554,7 @@ source_set("electron_lib") {
     }
 
     frameworks = [
+      "AuthenticationServices.framework",
       "AVFoundation.framework",
       "Carbon.framework",
       "LocalAuthentication.framework",
@@ -671,46 +671,6 @@ source_set("electron_lib") {
     ]
   }
 
-  if (enable_run_as_node) {
-    sources += [
-      "shell/app/node_main.cc",
-      "shell/app/node_main.h",
-    ]
-  }
-
-  if (enable_osr) {
-    sources += [
-      "shell/browser/osr/osr_host_display_client.cc",
-      "shell/browser/osr/osr_host_display_client.h",
-      "shell/browser/osr/osr_render_widget_host_view.cc",
-      "shell/browser/osr/osr_render_widget_host_view.h",
-      "shell/browser/osr/osr_video_consumer.cc",
-      "shell/browser/osr/osr_video_consumer.h",
-      "shell/browser/osr/osr_view_proxy.cc",
-      "shell/browser/osr/osr_view_proxy.h",
-      "shell/browser/osr/osr_web_contents_view.cc",
-      "shell/browser/osr/osr_web_contents_view.h",
-    ]
-    if (is_mac) {
-      sources += [
-        "shell/browser/osr/osr_host_display_client_mac.mm",
-        "shell/browser/osr/osr_web_contents_view_mac.mm",
-      ]
-    }
-    deps += [
-      "//components/viz/service",
-      "//services/viz/public/mojom",
-      "//ui/compositor",
-    ]
-  }
-
-  if (enable_desktop_capturer) {
-    sources += [
-      "shell/browser/api/electron_api_desktop_capturer.cc",
-      "shell/browser/api/electron_api_desktop_capturer.h",
-    ]
-  }
-
   if (enable_printing) {
     sources += [
       "shell/browser/printing/print_view_manager_electron.cc",
@@ -765,6 +725,8 @@ 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",
     ]
   }
 
@@ -794,15 +756,6 @@ if (is_mac) {
     sources = [ "shell/common/resources/mac/MainMenu.xib" ]
   }
 
-  action("fake_v8_context_snapshot_generator") {
-    script = "build/fake_v8_context_snapshot_generator.py"
-    args = [
-      rebase_path("$root_out_dir/$v8_context_snapshot_filename"),
-      rebase_path("$root_out_dir/fake/$v8_context_snapshot_filename"),
-    ]
-    outputs = [ "$root_out_dir/fake/$v8_context_snapshot_filename" ]
-  }
-
   bundle_data("electron_framework_resources") {
     public_deps = [ ":packed_resources" ]
     sources = []
@@ -813,13 +766,8 @@ if (is_mac) {
     if (v8_use_external_startup_data) {
       public_deps += [ "//v8" ]
       if (use_v8_context_snapshot) {
-        if (use_prebuilt_v8_context_snapshot) {
-          sources += [ "$root_out_dir/fake/$v8_context_snapshot_filename" ]
-          public_deps += [ ":fake_v8_context_snapshot_generator" ]
-        } else {
-          sources += [ "$root_out_dir/$v8_context_snapshot_filename" ]
-          public_deps += [ "//tools/v8_context_snapshot" ]
-        }
+        sources += [ "$root_out_dir/$v8_context_snapshot_filename" ]
+        public_deps += [ "//tools/v8_context_snapshot" ]
       } else {
         sources += [ "$root_out_dir/snapshot_blob.bin" ]
       }
@@ -919,11 +867,7 @@ if (is_mac) {
 
     include_dirs = [ "." ]
     sources = filenames.framework_sources
-    frameworks = []
-
-    if (enable_osr) {
-      frameworks += [ "IOSurface.framework" ]
-    }
+    frameworks = [ "IOSurface.framework" ]
 
     ldflags = [
       "-Wl,-install_name,@rpath/$output_name.framework/$output_name",
@@ -961,7 +905,7 @@ if (is_mac) {
         deps += [ "//sandbox/mac:seatbelt" ]
       }
       defines = [ "HELPER_EXECUTABLE" ]
-      extra_configs = [ "//electron/build/config:mas_build" ]
+      configs += [ "//electron/build/config:mas_build" ]
       sources = [
         "shell/app/electron_main_mac.cc",
         "shell/app/uv_stdio_fix.cc",
@@ -1132,7 +1076,7 @@ if (is_mac) {
       "-rpath",
       "@executable_path/../Frameworks",
     ]
-    extra_configs = [ "//electron/build/config:mas_build" ]
+    configs += [ "//electron/build/config:mas_build" ]
   }
 
   if (enable_dsyms) {
@@ -1526,8 +1470,9 @@ dist_zip("libcxx_headers_zip") {
   data_deps = [ ":libcxx_headers" ]
   deps = data_deps
   flatten = true
-  flatten_relative_to = rebase_path(
-          "$target_gen_dir/electron_libcxx_include/buildtools/third_party/libc++/trunk",
+  flatten_relative_to =
+      rebase_path(
+          "$target_gen_dir/electron_libcxx_include/third_party/libc++/src",
           "$root_out_dir")
 
   outputs = [ "$root_build_dir/libcxx_headers.zip" ]
@@ -1543,7 +1488,7 @@ dist_zip("libcxxabi_headers_zip") {
   deps = data_deps
   flatten = true
   flatten_relative_to = rebase_path(
-          "$target_gen_dir/electron_libcxxabi_include/buildtools/third_party/libc++abi/trunk",
+          "$target_gen_dir/electron_libcxxabi_include/third_party/libc++abi/src",
           "$root_out_dir")
 
   outputs = [ "$root_build_dir/libcxxabi_headers.zip" ]
@@ -1559,3 +1504,70 @@ action("libcxx_objects_zip") {
 group("electron") {
   public_deps = [ ":electron_app" ]
 }
+
+##### node_headers
+
+node_dir = "../third_party/electron_node"
+node_files = read_file("$node_dir/filenames.json", "json")
+node_headers_dir = "$root_gen_dir/node_headers"
+
+header_group_index = 0
+header_groups = []
+foreach(header_group, node_files.headers) {
+  copy("node_headers_${header_group_index}") {
+    sources = rebase_path(header_group.files, ".", node_dir)
+    outputs =
+        [ "$node_headers_dir/${header_group.dest_dir}/{{source_file_part}}" ]
+  }
+  header_groups += [ ":node_headers_${header_group_index}" ]
+  header_group_index += 1
+}
+
+copy("zlib_headers") {
+  sources = [
+    "$node_dir/deps/zlib/zconf.h",
+    "$node_dir/deps/zlib/zlib.h",
+  ]
+  outputs = [ "$node_headers_dir/include/node/{{source_file_part}}" ]
+}
+
+copy("node_gypi_headers") {
+  deps = [ ":generate_config_gypi" ]
+  sources = [
+    "$node_dir/common.gypi",
+    "$root_gen_dir/config.gypi",
+  ]
+  outputs = [ "$node_headers_dir/include/node/{{source_file_part}}" ]
+}
+
+action("node_version_header") {
+  inputs = [ "$node_dir/src/node_version.h" ]
+  outputs = [ "$node_headers_dir/include/node/node_version.h" ]
+  script = "script/generate_node_version_header.py"
+  args = rebase_path(inputs) + rebase_path(outputs)
+  if (node_module_version != "") {
+    args += [ "$node_module_version" ]
+  }
+}
+
+action("tar_node_headers") {
+  deps = [ ":copy_node_headers" ]
+  outputs = [ "$root_gen_dir/node_headers.tar.gz" ]
+  script = "script/tar.py"
+  args = [
+    rebase_path("$root_gen_dir/node_headers"),
+    rebase_path(outputs[0]),
+  ]
+}
+
+group("copy_node_headers") {
+  public_deps = header_groups + [
+                  ":node_gypi_headers",
+                  ":node_version_header",
+                  ":zlib_headers",
+                ]
+}
+
+group("node_headers") {
+  public_deps = [ ":tar_node_headers" ]
+}

+ 4 - 0
CONTRIBUTING.md

@@ -60,6 +60,10 @@ dependencies, and tools contained in the `electron/electron` repository.
   * [Step 11: Landing](https://electronjs.org/docs/development/pull-requests#step-11-landing)
   * [Continuous Integration Testing](https://electronjs.org/docs/development/pull-requests#continuous-integration-testing)
 
+### Dependencies Upgrades Policy
+
+Dependencies in Electron's `package.json` or `yarn.lock` files should only be altered by maintainers. For security reasons, we will not accept PRs that alter our `package.json` or `yarn.lock` files. We invite contributors to make requests updating these files in our issue tracker. If the change is significantly complicated, draft PRs are welcome, with the understanding that these PRs will be closed in favor of a duplicate PR submitted by an Electron maintainer.
+
 ## Style Guides
 
 See [Coding Style](https://electronjs.org/docs/development/coding-style) for information about which standards Electron adheres to in different parts of its codebase.

+ 13 - 4
DEPS

@@ -2,13 +2,17 @@ gclient_gn_args_from = 'src'
 
 vars = {
   'chromium_version':
-    '114.0.5694.0',
+    '118.0.5949.0',
   'node_version':
-    'v18.15.0',
+    'v18.17.1',
   'nan_version':
     '16fa32231e2ccd89d2804b3f765319128b20c4ac',
   'squirrel.mac_version':
     '0e5d146ba13101a1302d59ea6e6e0b3cace4ae38',
+  'reactiveobjc_version':
+    '74ab5baccc6f7202c8ac69a8d1e152c29dc1ea76',
+  'mantle_version':
+    '78d3966b3c331292ea29ec38661b25df0a245948',
 
   'pyyaml_version': '3.12',
 
@@ -17,6 +21,11 @@ vars = {
   'nodejs_git': 'https://github.com/nodejs',
   'yaml_git': 'https://github.com/yaml',
   'squirrel_git': 'https://github.com/Squirrel',
+  'reactiveobjc_git': 'https://github.com/ReactiveCocoa',
+  'mantle_git': 'https://github.com/Mantle',
+  
+  # The path of the sysroots.json file.
+  'sysroots_json_path': 'electron/script/sysroots.json',
 
   # KEEP IN SYNC WITH utils.js FILE
   'yarn_version': '1.15.2',
@@ -87,11 +96,11 @@ deps = {
     'condition': 'process_deps',
   },
   'src/third_party/squirrel.mac/vendor/ReactiveObjC': {
-    'url': 'https://github.com/ReactiveCocoa/ReactiveObjC.git@74ab5baccc6f7202c8ac69a8d1e152c29dc1ea76',
+    'url': Var("reactiveobjc_git") + '/ReactiveObjC.git@' + Var("reactiveobjc_version"),
     'condition': 'process_deps'
   },
   'src/third_party/squirrel.mac/vendor/Mantle': {
-    'url': 'https://github.com/Mantle/Mantle.git@78d3966b3c331292ea29ec38661b25df0a245948',
+    'url':  Var("mantle_git") + '/Mantle.git@' + Var("mantle_version"),
     'condition': 'process_deps',
   }
 }

+ 1 - 1
README.md

@@ -38,7 +38,7 @@ For more installation options and troubleshooting tips, see
 
 Each Electron release provides binaries for macOS, Windows, and Linux.
 
-* macOS (High Sierra and up): Electron provides 64-bit Intel and ARM binaries for macOS. Apple Silicon support was added in Electron 11.
+* macOS (Catalina and up): Electron provides 64-bit Intel and ARM binaries for macOS. Apple Silicon support was added in Electron 11.
 * Windows (Windows 10 and up): Electron provides `ia32` (`x86`), `x64` (`amd64`), and `arm64` binaries for Windows. Windows on ARM support was added in Electron 5.0.8. Support for Windows 7, 8 and 8.1 was [removed in Electron 23, in line with Chromium's Windows deprecation policy](https://www.electronjs.org/blog/windows-7-to-8-1-deprecation-notice).
 * Linux: The prebuilt binaries of Electron are built on Ubuntu 20.04. They have also been verified to work on:
   * Ubuntu 14.04 and newer

+ 58 - 15
appveyor-woa.yml

@@ -29,7 +29,7 @@
 
 version: 1.0.{build}
 build_cloud: electronhq-16-core
-image: e-114.0.5684.0
+image: e-118.0.5949.0
 environment:
   GIT_CACHE_PATH: C:\Users\appveyor\libcc_cache
   ELECTRON_OUT_DIR: Default
@@ -38,7 +38,9 @@ environment:
   MOCHA_REPORTER: mocha-multi-reporters
   MOCHA_MULTI_REPORTERS: "@marshallofsound/mocha-appveyor-reporter, tap"
   GOMA_FALLBACK_ON_AUTH_FAILURE: true
-  DEPOT_TOOLS_WIN_TOOLCHAIN: 0
+  DEPOT_TOOLS_WIN_TOOLCHAIN: 1
+  DEPOT_TOOLS_WIN_TOOLCHAIN_BASE_URL: "https://dev-cdn.electronjs.org/windows-toolchains/_"
+  GYP_MSVS_HASH_27370823e7: 28622d16b1
   PYTHONIOENCODING: UTF-8
 
   matrix:
@@ -49,6 +51,11 @@ 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
@@ -66,11 +73,15 @@ for:
     build_script:
       - ps: |
           node script/yarn.js install --frozen-lockfile
-          node script/doc-only-change.js --prNumber=$env:APPVEYOR_PULL_REQUEST_NUMBER --prBranch=$env:APPVEYOR_REPO_BRANCH
+          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"; Exit-AppveyorBuild
+            Write-warning "Skipping build for doc-only change"
+            $env:SHOULD_SKIP_ARTIFACT_VALIDATION = "true"
+            Exit-AppveyorBuild
+          } else {
+            $global:LASTEXITCODE = 0
           }
-          $global:LASTEXITCODE = 0
       - cd ..
       - ps: Write-Host "Building $env:GN_CONFIG build"
       - git config --global core.longpaths true
@@ -83,6 +94,8 @@ 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") {
@@ -105,7 +118,7 @@ for:
       - ps: .\src\electron\script\start-goma.ps1 -gomaDir $env:LOCAL_GOMA_DIR
       - ps: >-
           if (Test-Path 'env:RAW_GOMA_AUTH') {
-            $goma_login = python $env:LOCAL_GOMA_DIR\goma_auth.py info
+            $goma_login = python3 $env:LOCAL_GOMA_DIR\goma_auth.py info
             if ($goma_login -eq 'Login as Fermi Planck') {
               Write-warning "Goma authentication is correct";
             } else {
@@ -154,8 +167,8 @@ for:
       - cd ..\..
       - 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
-      - python %LOCAL_GOMA_DIR%\goma_ctl.py stat
+      - ninja -C out/Default electron:node_headers
+      - python3 %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
@@ -176,6 +189,31 @@ 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 $env:APPVEYOR_PROJECT_NAME"
+          } 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
@@ -201,7 +239,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
@@ -220,11 +258,13 @@ for:
     build_script:
       - ps: |
           node script/yarn.js install --frozen-lockfile
-          node script/doc-only-change.js --prNumber=$env:APPVEYOR_PULL_REQUEST_NUMBER --prBranch=$env:APPVEYOR_REPO_BRANCH
+          node script/doc-only-change.js --prNumber=$env:APPVEYOR_PULL_REQUEST_NUMBER
           if ($LASTEXITCODE -eq 0) {
-            Write-warning "Skipping build for doc only change"; Exit-AppveyorBuild
+            Write-warning "Skipping build for doc only change"
+            Exit-AppveyorBuild
+          } else {
+            $global:LASTEXITCODE = 0
           }
-          $global:LASTEXITCODE = 0
       - cd ..
       - mkdir out\Default
       - cd ..
@@ -232,7 +272,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','pdb.zip','electron.lib')
+          $artifacts_to_download = @('dist.zip','ffmpeg.zip','node_headers.zip','electron.lib')
           foreach ($job in $build_info.build.jobs) {
             if ($job.name -eq "Build Arm on X64 Windows") {
               $jobId = $job.jobId
@@ -244,10 +284,13 @@ 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','pdb.zip')
+          $out_default_zips = @('dist.zip')
           foreach($zip_name in $out_default_zips) {
             7z x -y -osrc\out\Default $zip_name
           }
@@ -276,4 +319,4 @@ for:
     on_finish:
       # Uncomment these lines to enable RDP
       # - ps: $blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1'))
-      - if exist electron\electron.log ( appveyor-retry appveyor PushArtifact electron\electron.log )
+      - if exist electron\electron.log ( appveyor-retry appveyor PushArtifact electron\electron.log )

+ 56 - 13
appveyor.yml

@@ -29,7 +29,7 @@
 
 version: 1.0.{build}
 build_cloud: electronhq-16-core
-image: e-114.0.5684.0
+image: e-118.0.5949.0
 environment:
   GIT_CACHE_PATH: C:\Users\appveyor\libcc_cache
   ELECTRON_OUT_DIR: Default
@@ -38,7 +38,9 @@ environment:
   MOCHA_REPORTER: mocha-multi-reporters
   MOCHA_MULTI_REPORTERS: "@marshallofsound/mocha-appveyor-reporter, tap"
   GOMA_FALLBACK_ON_AUTH_FAILURE: true
-  DEPOT_TOOLS_WIN_TOOLCHAIN: 0
+  DEPOT_TOOLS_WIN_TOOLCHAIN: 1
+  DEPOT_TOOLS_WIN_TOOLCHAIN_BASE_URL: "https://dev-cdn.electronjs.org/windows-toolchains/_"
+  GYP_MSVS_HASH_27370823e7: 28622d16b1
   PYTHONIOENCODING: UTF-8
 
   matrix:
@@ -47,6 +49,11 @@ 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
@@ -64,11 +71,15 @@ for:
     build_script:
       - ps: |
           node script/yarn.js install --frozen-lockfile
-          node script/doc-only-change.js --prNumber=$env:APPVEYOR_PULL_REQUEST_NUMBER --prBranch=$env:APPVEYOR_REPO_BRANCH
+          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"; Exit-AppveyorBuild
+            Write-warning "Skipping build for doc-only change"
+            $env:SHOULD_SKIP_ARTIFACT_VALIDATION = "true"
+            Exit-AppveyorBuild
+          } else {
+            $global:LASTEXITCODE = 0
           }
-          $global:LASTEXITCODE = 0
       - cd ..
       - ps: Write-Host "Building $env:GN_CONFIG build"
       - git config --global core.longpaths true
@@ -81,6 +92,8 @@ 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") {
@@ -103,7 +116,7 @@ for:
       - ps: .\src\electron\script\start-goma.ps1 -gomaDir $env:LOCAL_GOMA_DIR
       - ps: >-
           if (Test-Path 'env:RAW_GOMA_AUTH') {
-            $goma_login = python $env:LOCAL_GOMA_DIR\goma_auth.py info
+            $goma_login = python3 $env:LOCAL_GOMA_DIR\goma_auth.py info
             if ($goma_login -eq 'Login as Fermi Planck') {
               Write-warning "Goma authentication is correct";
             } else {
@@ -152,8 +165,8 @@ for:
       - cd ..\..
       - 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
-      - python %LOCAL_GOMA_DIR%\goma_ctl.py stat
+      - ninja -C out/Default electron:node_headers
+      - python3 %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
@@ -174,6 +187,31 @@ 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 $env:APPVEYOR_PROJECT_NAME"
+          } 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
@@ -199,7 +237,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
@@ -216,11 +254,13 @@ for:
     build_script:
       - ps: |
           node script/yarn.js install --frozen-lockfile
-          node script/doc-only-change.js --prNumber=$env:APPVEYOR_PULL_REQUEST_NUMBER --prBranch=$env:APPVEYOR_REPO_BRANCH
+          node script/doc-only-change.js --prNumber=$env:APPVEYOR_PULL_REQUEST_NUMBER
           if ($LASTEXITCODE -eq 0) {
-            Write-warning "Skipping build for doc only change"; Exit-AppveyorBuild
+            Write-warning "Skipping build for doc only change"
+            Exit-AppveyorBuild
+          } else {
+            $global:LASTEXITCODE = 0
           }
-          $global:LASTEXITCODE = 0
       - cd ..
       - mkdir out\Default
       - cd ..
@@ -240,6 +280,9 @@ 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: |
@@ -276,4 +319,4 @@ for:
     on_finish:
       # Uncomment these lines to enable RDP
       # - ps: $blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1'))
-      - if exist electron\electron.log ( appveyor-retry appveyor PushArtifact electron\electron.log )
+      - if exist electron\electron.log ( appveyor-retry appveyor PushArtifact electron\electron.log )

+ 8 - 0
build/.eslintrc.json

@@ -0,0 +1,8 @@
+{
+  "plugins": [
+    "unicorn"
+  ],
+  "rules": {
+    "unicorn/prefer-node-protocol": "error"
+  }
+}

+ 12 - 1
build/args/all.gn

@@ -2,7 +2,7 @@ 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
+node_module_version = 118
 
 v8_promise_internal_field_count = 1
 v8_embedder_string = "-electron.0"
@@ -49,3 +49,14 @@ 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
+
+# Disables the builtins PGO for V8
+v8_builtins_profiling_log_file = ""
+
+# https://chromium.googlesource.com/chromium/src/+/main/docs/dangling_ptr.md
+# TODO(vertedinde): hunt down dangling pointers on Linux
+enable_dangling_raw_ptr_checks = false
+
+# This flag speeds up the performance of fork/execve on linux systems.
+# Ref: https://chromium-review.googlesource.com/c/v8/v8/+/4602858
+v8_enable_private_mapping_fork_optimization = true

+ 0 - 8
build/fake_v8_context_snapshot_generator.py

@@ -1,8 +0,0 @@
-import os
-import shutil
-import sys
-
-if os.path.exists(sys.argv[2]):
-  os.remove(sys.argv[2])
-
-shutil.copy(sys.argv[1], sys.argv[2])

+ 3 - 3
build/generate_node_defines.py

@@ -4,7 +4,7 @@ import sys
 
 DEFINE_EXTRACT_REGEX = re.compile('^ *# *define (\w*)', re.MULTILINE)
 
-def main(outDir, headers):
+def main(out_dir, headers):
   defines = []
   for filename in headers:
     with open(filename, 'r') as f:
@@ -15,13 +15,13 @@ def main(outDir, headers):
   for define in defines:
     push_and_undef += '#pragma push_macro("%s")\n' % define
     push_and_undef += '#undef %s\n' % define
-  with open(os.path.join(outDir, 'push_and_undef_node_defines.h'), 'w') as o:
+  with open(os.path.join(out_dir, 'push_and_undef_node_defines.h'), 'w') as o:
     o.write(push_and_undef)
 
   pop = ''
   for define in defines:
     pop += '#pragma pop_macro("%s")\n' % define
-  with open(os.path.join(outDir, 'pop_node_defines.h'), 'w') as o:
+  with open(os.path.join(out_dir, 'pop_node_defines.h'), 'w') as o:
     o.write(pop)
 
 def read_defines(content):

+ 2 - 10
build/webpack/webpack.config.base.js

@@ -1,5 +1,5 @@
-const fs = require('fs');
-const path = require('path');
+const fs = require('node:fs');
+const path = require('node:path');
 const webpack = require('webpack');
 const TerserPlugin = require('terser-webpack-plugin');
 const WrapperPlugin = require('wrapper-webpack-plugin');
@@ -53,14 +53,6 @@ module.exports = ({
 
     const ignoredModules = [];
 
-    if (defines.ENABLE_DESKTOP_CAPTURER === 'false') {
-      ignoredModules.push(
-        '@electron/internal/browser/desktop-capturer',
-        '@electron/internal/browser/api/desktop-capturer',
-        '@electron/internal/renderer/api/desktop-capturer'
-      );
-    }
-
     const plugins = [];
 
     if (onlyPrintingGraph) {

+ 1 - 1
build/zip_libcxx.py

@@ -44,4 +44,4 @@ def main(argv):
         z.write(object_file, os.path.relpath(object_file, base_path_libcxxabi))
 
 if __name__ == '__main__':
-  sys.exit(main(sys.argv[1:]))
+  sys.exit(main(sys.argv[1:]))

+ 0 - 6
buildflags/BUILD.gn

@@ -9,15 +9,9 @@ buildflag_header("buildflags") {
   header = "buildflags.h"
 
   flags = [
-    "ENABLE_DESKTOP_CAPTURER=$enable_desktop_capturer",
-    "ENABLE_RUN_AS_NODE=$enable_run_as_node",
-    "ENABLE_OSR=$enable_osr",
     "ENABLE_PDF_VIEWER=$enable_pdf_viewer",
-    "ENABLE_TTS=$enable_tts",
-    "ENABLE_COLOR_CHOOSER=$enable_color_chooser",
     "ENABLE_ELECTRON_EXTENSIONS=$enable_electron_extensions",
     "ENABLE_BUILTIN_SPELLCHECKER=$enable_builtin_spellchecker",
-    "ENABLE_PICTURE_IN_PICTURE=$enable_picture_in_picture",
     "OVERRIDE_LOCATION_PROVIDER=$enable_fake_location_provider",
   ]
 }

+ 0 - 13
buildflags/buildflags.gni

@@ -3,21 +3,8 @@
 # found in the LICENSE file.
 
 declare_args() {
-  enable_desktop_capturer = true
-
-  # Allow running Electron as a node binary.
-  enable_run_as_node = true
-
-  enable_osr = true
-
   enable_pdf_viewer = true
 
-  enable_tts = true
-
-  enable_color_chooser = true
-
-  enable_picture_in_picture = true
-
   # Provide a fake location provider for mocking
   # the geolocation responses. Disable it if you
   # need to test with chromium's location provider.

+ 55 - 63
chromium_src/BUILD.gn

@@ -37,12 +37,22 @@ static_library("chrome") {
     "//chrome/browser/icon_loader.h",
     "//chrome/browser/icon_manager.cc",
     "//chrome/browser/icon_manager.h",
+    "//chrome/browser/media/webrtc/desktop_media_list.cc",
+    "//chrome/browser/media/webrtc/desktop_media_list.h",
+    "//chrome/browser/media/webrtc/desktop_media_list_base.cc",
+    "//chrome/browser/media/webrtc/desktop_media_list_base.h",
+    "//chrome/browser/media/webrtc/desktop_media_list_observer.h",
+    "//chrome/browser/media/webrtc/native_desktop_media_list.cc",
+    "//chrome/browser/media/webrtc/native_desktop_media_list.h",
+    "//chrome/browser/media/webrtc/window_icon_util.h",
     "//chrome/browser/net/chrome_mojo_proxy_resolver_factory.cc",
     "//chrome/browser/net/chrome_mojo_proxy_resolver_factory.h",
     "//chrome/browser/net/proxy_config_monitor.cc",
     "//chrome/browser/net/proxy_config_monitor.h",
     "//chrome/browser/net/proxy_service_factory.cc",
     "//chrome/browser/net/proxy_service_factory.h",
+    "//chrome/browser/picture_in_picture/picture_in_picture_window_manager.cc",
+    "//chrome/browser/picture_in_picture/picture_in_picture_window_manager.h",
     "//chrome/browser/platform_util.cc",
     "//chrome/browser/platform_util.h",
     "//chrome/browser/predictors/preconnect_manager.cc",
@@ -86,6 +96,28 @@ static_library("chrome") {
     "//chrome/browser/ui/views/eye_dropper/eye_dropper.h",
     "//chrome/browser/ui/views/eye_dropper/eye_dropper_view.cc",
     "//chrome/browser/ui/views/eye_dropper/eye_dropper_view.h",
+    "//chrome/browser/ui/views/overlay/back_to_tab_label_button.cc",
+    "//chrome/browser/ui/views/overlay/close_image_button.cc",
+    "//chrome/browser/ui/views/overlay/close_image_button.h",
+    "//chrome/browser/ui/views/overlay/constants.h",
+    "//chrome/browser/ui/views/overlay/hang_up_button.cc",
+    "//chrome/browser/ui/views/overlay/hang_up_button.h",
+    "//chrome/browser/ui/views/overlay/overlay_window_image_button.cc",
+    "//chrome/browser/ui/views/overlay/overlay_window_image_button.h",
+    "//chrome/browser/ui/views/overlay/playback_image_button.cc",
+    "//chrome/browser/ui/views/overlay/playback_image_button.h",
+    "//chrome/browser/ui/views/overlay/resize_handle_button.cc",
+    "//chrome/browser/ui/views/overlay/resize_handle_button.h",
+    "//chrome/browser/ui/views/overlay/simple_overlay_window_image_button.cc",
+    "//chrome/browser/ui/views/overlay/simple_overlay_window_image_button.h",
+    "//chrome/browser/ui/views/overlay/skip_ad_label_button.cc",
+    "//chrome/browser/ui/views/overlay/skip_ad_label_button.h",
+    "//chrome/browser/ui/views/overlay/toggle_camera_button.cc",
+    "//chrome/browser/ui/views/overlay/toggle_camera_button.h",
+    "//chrome/browser/ui/views/overlay/toggle_microphone_button.cc",
+    "//chrome/browser/ui/views/overlay/toggle_microphone_button.h",
+    "//chrome/browser/ui/views/overlay/video_overlay_window_views.cc",
+    "//chrome/browser/ui/views/overlay/video_overlay_window_views.h",
     "//extensions/browser/app_window/size_constraints.cc",
     "//extensions/browser/app_window/size_constraints.h",
     "//ui/views/native_window_tracker.h",
@@ -95,23 +127,6 @@ static_library("chrome") {
     sources += [ "//chrome/browser/process_singleton_posix.cc" ]
   }
 
-  if (is_mac) {
-    sources += [
-      "//chrome/browser/extensions/global_shortcut_listener_mac.h",
-      "//chrome/browser/extensions/global_shortcut_listener_mac.mm",
-      "//chrome/browser/icon_loader_mac.mm",
-      "//chrome/browser/media/webrtc/system_media_capture_permissions_mac.h",
-      "//chrome/browser/media/webrtc/system_media_capture_permissions_mac.mm",
-      "//chrome/browser/media/webrtc/system_media_capture_permissions_stats_mac.h",
-      "//chrome/browser/media/webrtc/system_media_capture_permissions_stats_mac.mm",
-      "//chrome/browser/media/webrtc/window_icon_util_mac.mm",
-      "//chrome/browser/platform_util_mac.mm",
-      "//chrome/browser/process_singleton_mac.mm",
-      "//chrome/browser/ui/views/eye_dropper/eye_dropper_view_mac.h",
-      "//chrome/browser/ui/views/eye_dropper/eye_dropper_view_mac.mm",
-    ]
-  }
-
   if (is_win) {
     sources += [
       "//chrome/browser/extensions/global_shortcut_listener_win.cc",
@@ -146,6 +161,7 @@ static_library("chrome") {
 
   public_deps = [
     "//chrome/browser:dev_ui_browser_resources",
+    "//chrome/browser/resources/accessibility:resources",
     "//chrome/browser/ui/color:mixers",
     "//chrome/common",
     "//chrome/common:version_header",
@@ -157,7 +173,15 @@ static_library("chrome") {
     "//services/strings",
   ]
 
-  deps = [ "//chrome/browser:resource_prefetch_predictor_proto" ]
+  deps = [
+    "//chrome/app/vector_icons",
+    "//chrome/browser:resource_prefetch_predictor_proto",
+    "//chrome/browser/resource_coordinator:mojo_bindings",
+    "//chrome/browser/web_applications/mojom:mojom_web_apps_enum",
+    "//components/vector_icons:vector_icons",
+    "//ui/snapshot",
+    "//ui/views/controls/webview",
+  ]
 
   if (is_linux) {
     sources += [ "//chrome/browser/icon_loader_auralinux.cc" ]
@@ -188,18 +212,21 @@ static_library("chrome") {
     public_deps += [ "//chrome/services/util_win:lib" ]
   }
 
-  if (enable_desktop_capturer) {
+  if (is_mac) {
     sources += [
-      "//chrome/browser/media/webrtc/desktop_media_list.cc",
-      "//chrome/browser/media/webrtc/desktop_media_list.h",
-      "//chrome/browser/media/webrtc/desktop_media_list_base.cc",
-      "//chrome/browser/media/webrtc/desktop_media_list_base.h",
-      "//chrome/browser/media/webrtc/desktop_media_list_observer.h",
-      "//chrome/browser/media/webrtc/native_desktop_media_list.cc",
-      "//chrome/browser/media/webrtc/native_desktop_media_list.h",
-      "//chrome/browser/media/webrtc/window_icon_util.h",
+      "//chrome/browser/extensions/global_shortcut_listener_mac.h",
+      "//chrome/browser/extensions/global_shortcut_listener_mac.mm",
+      "//chrome/browser/icon_loader_mac.mm",
+      "//chrome/browser/media/webrtc/system_media_capture_permissions_mac.h",
+      "//chrome/browser/media/webrtc/system_media_capture_permissions_mac.mm",
+      "//chrome/browser/media/webrtc/system_media_capture_permissions_stats_mac.h",
+      "//chrome/browser/media/webrtc/system_media_capture_permissions_stats_mac.mm",
+      "//chrome/browser/media/webrtc/window_icon_util_mac.mm",
+      "//chrome/browser/platform_util_mac.mm",
+      "//chrome/browser/process_singleton_mac.mm",
+      "//chrome/browser/ui/views/eye_dropper/eye_dropper_view_mac.h",
+      "//chrome/browser/ui/views/eye_dropper/eye_dropper_view_mac.mm",
     ]
-    deps += [ "//ui/snapshot" ]
   }
 
   if (enable_widevine) {
@@ -273,41 +300,6 @@ static_library("chrome") {
     }
   }
 
-  if (enable_picture_in_picture) {
-    sources += [
-      "//chrome/browser/picture_in_picture/picture_in_picture_window_manager.cc",
-      "//chrome/browser/picture_in_picture/picture_in_picture_window_manager.h",
-      "//chrome/browser/ui/views/overlay/back_to_tab_label_button.cc",
-      "//chrome/browser/ui/views/overlay/close_image_button.cc",
-      "//chrome/browser/ui/views/overlay/close_image_button.h",
-      "//chrome/browser/ui/views/overlay/constants.h",
-      "//chrome/browser/ui/views/overlay/hang_up_button.cc",
-      "//chrome/browser/ui/views/overlay/hang_up_button.h",
-      "//chrome/browser/ui/views/overlay/overlay_window_image_button.cc",
-      "//chrome/browser/ui/views/overlay/overlay_window_image_button.h",
-      "//chrome/browser/ui/views/overlay/playback_image_button.cc",
-      "//chrome/browser/ui/views/overlay/playback_image_button.h",
-      "//chrome/browser/ui/views/overlay/resize_handle_button.cc",
-      "//chrome/browser/ui/views/overlay/resize_handle_button.h",
-      "//chrome/browser/ui/views/overlay/simple_overlay_window_image_button.cc",
-      "//chrome/browser/ui/views/overlay/simple_overlay_window_image_button.h",
-      "//chrome/browser/ui/views/overlay/skip_ad_label_button.cc",
-      "//chrome/browser/ui/views/overlay/skip_ad_label_button.h",
-      "//chrome/browser/ui/views/overlay/toggle_camera_button.cc",
-      "//chrome/browser/ui/views/overlay/toggle_camera_button.h",
-      "//chrome/browser/ui/views/overlay/toggle_microphone_button.cc",
-      "//chrome/browser/ui/views/overlay/toggle_microphone_button.h",
-      "//chrome/browser/ui/views/overlay/video_overlay_window_views.cc",
-      "//chrome/browser/ui/views/overlay/video_overlay_window_views.h",
-    ]
-
-    deps += [
-      "//chrome/app/vector_icons",
-      "//components/vector_icons:vector_icons",
-      "//ui/views/controls/webview",
-    ]
-  }
-
   if (enable_electron_extensions) {
     sources += [
       "//chrome/browser/extensions/chrome_url_request_util.cc",

+ 8 - 0
default_app/.eslintrc.json

@@ -0,0 +1,8 @@
+{
+  "plugins": [
+    "unicorn"
+  ],
+  "rules": {
+    "unicorn/prefer-node-protocol": "error"
+  }
+}

+ 2 - 2
default_app/default_app.ts

@@ -1,7 +1,7 @@
 import { shell } from 'electron/common';
 import { app, dialog, BrowserWindow, ipcMain } from 'electron/main';
-import * as path from 'path';
-import * as url from 'url';
+import * as path from 'node:path';
+import * as url from 'node:url';
 
 let mainWindow: BrowserWindow | null = null;
 

+ 6 - 6
default_app/main.ts

@@ -1,8 +1,8 @@
 import * as electron from 'electron/main';
 
-import * as fs from 'fs';
-import * as path from 'path';
-import * as url from 'url';
+import * as fs from 'node:fs';
+import * as path from 'node:path';
+import * as url from 'node:url';
 const { app, dialog } = electron;
 
 type DefaultAppOptions = {
@@ -15,7 +15,7 @@ type DefaultAppOptions = {
   modules: string[];
 }
 
-const Module = require('module');
+const Module = require('node:module');
 
 // Parse command line options.
 const argv = process.argv.slice(1);
@@ -112,7 +112,7 @@ function loadApplicationPackage (packagePath: string) {
       // Set v8 flags, deliberately lazy load so that apps that do not use this
       // feature do not pay the price
       if (packageJson.v8Flags) {
-        require('v8').setFlagsFromString(packageJson.v8Flags);
+        require('node:v8').setFlagsFromString(packageJson.v8Flags);
       }
       appPath = packagePath;
     }
@@ -171,7 +171,7 @@ function startRepl () {
     Using: Node.js ${nodeVersion} and Electron.js ${electronVersion}
   `);
 
-  const { REPLServer } = require('repl');
+  const { REPLServer } = require('node:repl');
   const repl = new REPLServer({
     prompt: '> '
   }).on('exit', () => {

+ 1 - 1
docs/api/accelerator.md

@@ -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`
-* Punctuation like `~`, `!`, `@`, `#`, `$`, etc.
+* Various Punctuation: `)`, `!`, `@`, `#`, `$`, `%`, `^`, `&`, `*`, `(`, `:`, `;`, `:`, `+`, `=`, `<`, `,`, `_`, `-`, `>`, `.`, `?`, `/`, `~`, `` ` ``, `{`, `]`, `[`, `|`, `\`, `}`, `"`
 * `Plus`
 * `Space`
 * `Tab`

+ 64 - 42
docs/api/app.md

@@ -7,7 +7,7 @@ Process: [Main](../glossary.md#main-process)
 The following example shows how to quit the application when the last window is
 closed:
 
-```javascript
+```js
 const { app } = require('electron')
 app.on('window-all-closed', () => {
   app.quit()
@@ -128,9 +128,8 @@ Emitted when the user wants to open a URL with the application. Your application
 set `NSPrincipalClass` to `AtomApplication`.
 
 As with the `open-file` event, be sure to register a listener for the `open-url`
-event early in your application startup to detect if the the application being
-is being opened to handle a URL. If you register the listener in response to a
-`ready` event, you'll miss URLs that trigger the launch of your application.
+event early in your application startup to detect if the application is being opened to handle a URL.
+If you register the listener in response to a `ready` event, you'll miss URLs that trigger the launch of your application.
 
 ### Event: 'activate' _macOS_
 
@@ -150,9 +149,20 @@ Returns:
 
 * `event` Event
 
-Emitted when mac application become active. Difference from `activate` event is
+Emitted when the application becomes active. This differs from the `activate` event in
 that `did-become-active` is emitted every time the app becomes active, not only
-when Dock icon is clicked or application is re-launched.
+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 doesn’t 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.
 
 ### Event: 'continue-activity' _macOS_
 
@@ -285,7 +295,7 @@ Emitted when failed to verify the `certificate` for `url`, to trust the
 certificate you should prevent the default behavior with
 `event.preventDefault()` and call `callback(true)`.
 
-```javascript
+```js
 const { app } = require('electron')
 
 app.on('certificate-error', (event, webContents, url, error, certificate, callback) => {
@@ -317,7 +327,7 @@ and `callback` can be called with an entry filtered from the list. Using
 `event.preventDefault()` prevents the application from using the first
 certificate from the store.
 
-```javascript
+```js
 const { app } = require('electron')
 
 app.on('select-client-certificate', (event, webContents, url, list, callback) => {
@@ -350,7 +360,7 @@ The default behavior is to cancel all authentications. To override this you
 should prevent the default behavior with `event.preventDefault()` and call
 `callback(username, password)` with the credentials.
 
-```javascript
+```js
 const { app } = require('electron')
 
 app.on('login', (event, webContents, details, authInfo, callback) => {
@@ -402,18 +412,7 @@ Returns:
 
 * `event` Event
 * `webContents` [WebContents](web-contents.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.
+* `details` [RenderProcessGoneDetails](structures/render-process-gone-details.md)
 
 Emitted when the renderer process unexpectedly disappears.  This is normally
 because it was crashed or killed.
@@ -470,7 +469,7 @@ Returns:
 
 Emitted when Electron has created a new `session`.
 
-```javascript
+```js
 const { app } = require('electron')
 
 app.on('session-created', (session) => {
@@ -555,7 +554,7 @@ started after current instance exited.
 An example of restarting current instance immediately and adding a new command
 line argument to the new instance:
 
-```javascript
+```js
 const { app } = require('electron')
 
 app.relaunch({ args: process.argv.slice(1).concat(['--relaunch']) })
@@ -940,7 +939,7 @@ List, nor will it be displayed.
 
 Here's a very simple example of creating a custom Jump List:
 
-```javascript
+```js
 const { app } = require('electron')
 
 app.setJumpList([
@@ -960,7 +959,7 @@ app.setJumpList([
         title: 'Tool A',
         program: process.execPath,
         args: '--run-tool-a',
-        icon: process.execPath,
+        iconPath: process.execPath,
         iconIndex: 0,
         description: 'Runs Tool A'
       },
@@ -969,7 +968,7 @@ app.setJumpList([
         title: 'Tool B',
         program: process.execPath,
         args: '--run-tool-b',
-        icon: process.execPath,
+        iconPath: process.execPath,
         iconIndex: 0,
         description: 'Runs Tool B'
       }
@@ -1023,8 +1022,8 @@ use this method to ensure single instance.
 An example of activating the window of primary instance when a second instance
 starts:
 
-```javascript
-const { app } = require('electron')
+```js
+const { app, BrowserWindow } = require('electron')
 let myWindow = null
 
 const additionalData = { myKey: 'myValue' }
@@ -1044,9 +1043,9 @@ if (!gotTheLock) {
     }
   })
 
-  // Create myWindow, load the rest of the app, etc...
   app.whenReady().then(() => {
-    myWindow = createWindow()
+    myWindow = new BrowserWindow({})
+    myWindow.loadURL('https://electronjs.org')
   })
 }
 ```
@@ -1169,11 +1168,15 @@ case the user's DNS configuration does not include a provider that supports
 DoH.
 
 ```js
-app.configureHostResolver({
-  secureDnsMode: 'secure',
-  secureDnsServers: [
-    'https://cloudflare-dns.com/dns-query'
-  ]
+const { app } = require('electron')
+
+app.whenReady().then(() => {
+  app.configureHostResolver({
+    secureDnsMode: 'secure',
+    secureDnsServers: [
+      'https://cloudflare-dns.com/dns-query'
+    ]
+  })
 })
 ```
 
@@ -1261,6 +1264,9 @@ On macOS, it shows on the dock icon. On Linux, it only works for Unity launcher.
 **Note:** Unity launcher requires a `.desktop` file to work. For more information,
 please read the [Unity integration documentation][unity-requirement].
 
+**Note:** On macOS, you need to ensure that your application has the permission
+to display notifications for this method to work.
+
 ### `app.getBadgeCount()` _Linux_ _macOS_
 
 Returns `Integer` - The current value displayed in the counter badge.
@@ -1325,7 +1331,10 @@ To work with Electron's `autoUpdater` on Windows, which uses [Squirrel][Squirrel
 you'll want to set the launch path to Update.exe, and pass arguments that specify your
 application name. For example:
 
-``` javascript
+``` js
+const { app } = require('electron')
+const path = require('path')
+
 const appFolder = path.dirname(process.execPath)
 const updateExe = path.resolve(appFolder, '..', 'Update.exe')
 const exeName = path.basename(process.execPath)
@@ -1335,7 +1344,7 @@ app.setLoginItemSettings({
   path: updateExe,
   args: [
     '--processStart', `"${exeName}"`,
-    '--process-start-args', `"--hidden"`
+    '--process-start-args', '"--hidden"'
   ]
 })
 ```
@@ -1394,11 +1403,22 @@ Show the platform's native emoji picker.
 Returns `Function` - This function **must** be called once you have finished accessing the security scoped file. If you do not remember to stop accessing the bookmark, [kernel resources will be leaked](https://developer.apple.com/reference/foundation/nsurl/1417051-startaccessingsecurityscopedreso?language=objc) and your app will lose its ability to reach outside the sandbox completely, until your app is restarted.
 
 ```js
-// Start accessing the file.
-const stopAccessingSecurityScopedResource = app.startAccessingSecurityScopedResource(data)
-// You can now access the file outside of the sandbox 🎉
+const { app, dialog } = require('electron')
+const fs = require('fs')
+
+let filepath
+let bookmark
 
-// Remember to stop accessing the file once you've finished with it.
+dialog.showOpenDialog(null, { securityScopedBookmarks: true }).then(({ filePaths, bookmarks }) => {
+  filepath = filePaths[0]
+  bookmark = bookmarks[0]
+  fs.readFileSync(filepath)
+})
+
+// ... restart app ...
+
+const stopAccessingSecurityScopedResource = app.startAccessingSecurityScopedResource(bookmark)
+fs.readFileSync(filepath)
 stopAccessingSecurityScopedResource()
 ```
 
@@ -1406,7 +1426,7 @@ Start accessing a security scoped resource. With this method Electron applicatio
 
 ### `app.enableSandbox()`
 
-Enables full sandbox mode on the app. This means that all renderers will be launched sandboxed, regardless of the value of the `sandbox` flag in WebPreferences.
+Enables full sandbox mode on the app. This means that all renderers will be launched sandboxed, regardless of the value of the `sandbox` flag in [`WebPreferences`](structures/web-preferences.md).
 
 This method can only be called before app is ready.
 
@@ -1439,6 +1459,8 @@ By default, if an app of the same name as the one being moved exists in the Appl
 For example:
 
 ```js
+const { app, dialog } = require('electron')
+
 app.moveToApplicationsFolder({
   conflictHandler: (conflictType) => {
     if (conflictType === 'exists') {

+ 1 - 1
docs/api/auto-updater.md

@@ -137,7 +137,7 @@ application starts.
 [squirrel-mac]: https://github.com/Squirrel/Squirrel.Mac
 [server-support]: https://github.com/Squirrel/Squirrel.Mac#server-support
 [squirrel-windows]: https://github.com/Squirrel/Squirrel.Windows
-[installer]: https://github.com/electron/grunt-electron-installer
+[installer]: https://github.com/electron-archive/grunt-electron-installer
 [installer-lib]: https://github.com/electron/windows-installer
 [electron-forge-lib]: https://github.com/electron/forge
 [app-user-model-id]: https://learn.microsoft.com/en-us/windows/win32/shell/appids

+ 1 - 1
docs/api/browser-view.md

@@ -41,7 +41,7 @@ app.whenReady().then(() => {
 ### `new BrowserView([options])` _Experimental_ _Deprecated_
 
 * `options` Object (optional)
-  * `webPreferences` Object (optional) - See [BrowserWindow](browser-window.md).
+  * `webPreferences` [WebPreferences](structures/web-preferences.md?inline) (optional) - Settings of web page's features.
 
 ### Instance Properties
 

+ 37 - 319
docs/api/browser-window.md

@@ -104,6 +104,7 @@ window, you have to set both `parent` and `modal` options:
 ```javascript
 const { BrowserWindow } = require('electron')
 
+const top = new BrowserWindow()
 const child = new BrowserWindow({ parent: top, modal: true, show: false })
 child.loadURL('https://github.com')
 child.once('ready-to-show', () => {
@@ -151,294 +152,7 @@ It creates a new `BrowserWindow` with native properties as set by the `options`.
 
 ### `new BrowserWindow([options])`
 
-* `options` Object (optional)
-  * `width` Integer (optional) - Window's width in pixels. Default is `800`.
-  * `height` Integer (optional) - Window's height in pixels. Default is `600`.
-  * `x` Integer (optional) - (**required** if y is used) Window's left offset from screen.
-    Default is to center the window.
-  * `y` Integer (optional) - (**required** if x is used) Window's top offset from screen.
-    Default is to center the window.
-  * `useContentSize` boolean (optional) - The `width` and `height` would be used as web
-    page's size, which means the actual window's size will include window
-    frame's size and be slightly larger. Default is `false`.
-  * `center` boolean (optional) - Show window in the center of the screen. Default is `false`.
-  * `minWidth` Integer (optional) - Window's minimum width. Default is `0`.
-  * `minHeight` Integer (optional) - Window's minimum height. Default is `0`.
-  * `maxWidth` Integer (optional) - Window's maximum width. Default is no limit.
-  * `maxHeight` Integer (optional) - Window's maximum height. Default is no limit.
-  * `resizable` boolean (optional) - Whether window is resizable. Default is `true`.
-  * `movable` boolean (optional) _macOS_ _Windows_ - Whether window is
-    movable. This is not implemented on Linux. Default is `true`.
-  * `minimizable` boolean (optional) _macOS_ _Windows_ - Whether window is
-    minimizable. This is not implemented on Linux. Default is `true`.
-  * `maximizable` boolean (optional) _macOS_ _Windows_ - Whether window is
-    maximizable. This is not implemented on Linux. Default is `true`.
-  * `closable` boolean (optional) _macOS_ _Windows_ - Whether window is
-    closable. This is not implemented on Linux. Default is `true`.
-  * `focusable` boolean (optional) - Whether the window can be focused. Default is
-    `true`. On Windows setting `focusable: false` also implies setting
-    `skipTaskbar: true`. On Linux setting `focusable: false` makes the window
-    stop interacting with wm, so the window will always stay on top in all
-    workspaces.
-  * `alwaysOnTop` boolean (optional) - Whether the window should always stay on top of
-    other windows. Default is `false`.
-  * `fullscreen` boolean (optional) - Whether the window should show in fullscreen. When
-    explicitly set to `false` the fullscreen button will be hidden or disabled
-    on macOS. Default is `false`.
-  * `fullscreenable` boolean (optional) - Whether the window can be put into fullscreen
-    mode. On macOS, also whether the maximize/zoom button should toggle full
-    screen mode or maximize window. Default is `true`.
-  * `simpleFullscreen` boolean (optional) _macOS_ - Use pre-Lion fullscreen on
-    macOS. Default is `false`.
-  * `skipTaskbar` boolean (optional) _macOS_ _Windows_ - Whether to show the window in taskbar.
-    Default is `false`.
-  * `hiddenInMissionControl` boolean (optional) _macOS_ - Whether window should be hidden when the user toggles into mission control.
-  * `kiosk` boolean (optional) - Whether the window is in kiosk mode. Default is `false`.
-  * `title` string (optional) - Default window title. Default is `"Electron"`. If the HTML tag `<title>` is defined in the HTML file loaded by `loadURL()`, this property will be ignored.
-  * `icon` ([NativeImage](native-image.md) | string) (optional) - The window icon. On Windows it is
-    recommended to use `ICO` icons to get best visual effects, you can also
-    leave it undefined so the executable's icon will be used.
-  * `show` boolean (optional) - Whether window should be shown when created. Default is
-    `true`.
-  * `paintWhenInitiallyHidden` boolean (optional) - Whether the renderer should be active when `show` is `false` and it has just been created.  In order for `document.visibilityState` to work correctly on first load with `show: false` you should set this to `false`.  Setting this to `false` will cause the `ready-to-show` event to not fire.  Default is `true`.
-  * `frame` boolean (optional) - Specify `false` to create a
-    [frameless window](../tutorial/window-customization.md#create-frameless-windows). Default is `true`.
-  * `parent` BrowserWindow (optional) - Specify parent window. Default is `null`.
-  * `modal` boolean (optional) - Whether this is a modal window. This only works when the
-    window is a child window. Default is `false`.
-  * `acceptFirstMouse` boolean (optional) _macOS_ - Whether clicking an
-    inactive window will also click through to the web contents. Default is
-    `false` on macOS. This option is not configurable on other platforms.
-  * `disableAutoHideCursor` boolean (optional) - Whether to hide cursor when typing.
-    Default is `false`.
-  * `autoHideMenuBar` boolean (optional) - Auto hide the menu bar unless the `Alt`
-    key is pressed. Default is `false`.
-  * `enableLargerThanScreen` boolean (optional) _macOS_ - Enable the window to
-    be resized larger than screen. Only relevant for macOS, as other OSes
-    allow larger-than-screen windows by default. Default is `false`.
-  * `backgroundColor` string (optional) - The window's background color in Hex, RGB, RGBA, HSL, HSLA or named CSS color format. Alpha in #AARRGGBB format is supported if `transparent` is set to `true`. Default is `#FFF` (white). See [win.setBackgroundColor](browser-window.md#winsetbackgroundcolorbackgroundcolor) for more information.
-  * `hasShadow` boolean (optional) - Whether window should have a shadow. Default is `true`.
-  * `opacity` number (optional) _macOS_ _Windows_ - Set the initial opacity of
-    the window, between 0.0 (fully transparent) and 1.0 (fully opaque). This
-    is only implemented on Windows and macOS.
-  * `darkTheme` boolean (optional) - Forces using dark theme for the window, only works on
-    some GTK+3 desktop environments. Default is `false`.
-  * `transparent` boolean (optional) - Makes the window [transparent](../tutorial/window-customization.md#create-transparent-windows).
-    Default is `false`. On Windows, does not work unless the window is frameless.
-  * `type` string (optional) - The type of window, default is normal window. See more about
-    this below.
-  * `visualEffectState` string (optional) _macOS_ - Specify how the material
-    appearance should reflect window activity state on macOS. Must be used
-    with the `vibrancy` property. Possible values are:
-    * `followWindow` - The backdrop should automatically appear active when the window is active, and inactive when it is not. This is the default.
-    * `active` - The backdrop should always appear active.
-    * `inactive` - The backdrop should always appear inactive.
-  * `titleBarStyle` string (optional) _macOS_ _Windows_ - The style of window title bar.
-    Default is `default`. Possible values are:
-    * `default` - Results in the standard title bar for macOS or Windows respectively.
-    * `hidden` - Results in a hidden title bar and a full size content window. On macOS, the window still has the standard window controls (“traffic lights”) in the top left. On Windows, when combined with `titleBarOverlay: true` it will activate the Window Controls Overlay (see `titleBarOverlay` for more information), otherwise no window controls will be shown.
-    * `hiddenInset` _macOS_ - Only on macOS, results in a hidden title bar
-      with an alternative look where the traffic light buttons are slightly
-      more inset from the window edge.
-    * `customButtonsOnHover` _macOS_ - Only on macOS, results in a hidden
-      title bar and a full size content window, the traffic light buttons will
-      display when being hovered over in the top left of the window.
-      **Note:** This option is currently experimental.
-  * `trafficLightPosition` [Point](structures/point.md) (optional) _macOS_ -
-    Set a custom position for the traffic light buttons in frameless windows.
-  * `roundedCorners` boolean (optional) _macOS_ - Whether frameless window
-    should have rounded corners on macOS. Default is `true`. Setting this property
-    to `false` will prevent the window from being fullscreenable.
-  * `fullscreenWindowTitle` boolean (optional) _macOS_ _Deprecated_ - Shows
-    the title in the title bar in full screen mode on macOS for `hiddenInset`
-    titleBarStyle. Default is `false`.
-  * `thickFrame` boolean (optional) - Use `WS_THICKFRAME` style for frameless windows on
-    Windows, which adds standard window frame. Setting it to `false` will remove
-    window shadow and window animations. Default is `true`.
-  * `vibrancy` string (optional) _macOS_ - Add a type of vibrancy effect to
-    the window, only on macOS. Can be `appearance-based`, `light`, `dark`,
-    `titlebar`, `selection`, `menu`, `popover`, `sidebar`, `medium-light`,
-    `ultra-dark`, `header`, `sheet`, `window`, `hud`, `fullscreen-ui`,
-    `tooltip`, `content`, `under-window`, or `under-page`. Please note that
-    `appearance-based`, `light`, `dark`, `medium-light`, and `ultra-dark` are
-    deprecated and have been removed in macOS Catalina (10.15).
-  * `zoomToPageWidth` boolean (optional) _macOS_ - Controls the behavior on
-    macOS when option-clicking the green stoplight button on the toolbar or by
-    clicking the Window > Zoom menu item. If `true`, the window will grow to
-    the preferred width of the web page when zoomed, `false` will cause it to
-    zoom to the width of the screen. This will also affect the behavior when
-    calling `maximize()` directly. Default is `false`.
-  * `tabbingIdentifier` string (optional) _macOS_ - Tab group name, allows
-    opening the window as a native tab. Windows with the same
-    tabbing identifier will be grouped together. This also adds a native new
-    tab button to your window's tab bar and allows your `app` and window to
-    receive the `new-window-for-tab` event.
-  * `webPreferences` Object (optional) - Settings of web page's features.
-    * `devTools` boolean (optional) - Whether to enable DevTools. If it is set to `false`, can not use `BrowserWindow.webContents.openDevTools()` to open DevTools. Default is `true`.
-    * `nodeIntegration` boolean (optional) - Whether node integration is enabled.
-      Default is `false`.
-    * `nodeIntegrationInWorker` boolean (optional) - Whether node integration is
-      enabled in web workers. Default is `false`. More about this can be found
-      in [Multithreading](../tutorial/multithreading.md).
-    * `nodeIntegrationInSubFrames` boolean (optional) - Experimental option for
-      enabling Node.js support in sub-frames such as iframes and child windows. All your preloads will load for
-      every iframe, you can use `process.isMainFrame` to determine if you are
-      in the main frame or not.
-    * `preload` string (optional) - Specifies a script that will be loaded before other
-      scripts run in the page. This script will always have access to node APIs
-      no matter whether node integration is turned on or off. The value should
-      be the absolute file path to the script.
-      When node integration is turned off, the preload script can reintroduce
-      Node global symbols back to the global scope. See example
-      [here](context-bridge.md#exposing-node-global-symbols).
-    * `sandbox` boolean (optional) - If set, this will sandbox the renderer
-      associated with the window, making it compatible with the Chromium
-      OS-level sandbox and disabling the Node.js engine. This is not the same as
-      the `nodeIntegration` option and the APIs available to the preload script
-      are more limited. Read more about the option [here](../tutorial/sandbox.md).
-    * `session` [Session](session.md#class-session) (optional) - Sets the session used by the
-      page. Instead of passing the Session object directly, you can also choose to
-      use the `partition` option instead, which accepts a partition string. When
-      both `session` and `partition` are provided, `session` will be preferred.
-      Default is the default session.
-    * `partition` string (optional) - Sets the session used by the page according to the
-      session's partition string. If `partition` starts with `persist:`, the page
-      will use a persistent session available to all pages in the app with the
-      same `partition`. If there is no `persist:` prefix, the page will use an
-      in-memory session. By assigning the same `partition`, multiple pages can share
-      the same session. Default is the default session.
-    * `zoomFactor` number (optional) - The default zoom factor of the page, `3.0` represents
-      `300%`. Default is `1.0`.
-    * `javascript` boolean (optional) - Enables JavaScript support. Default is `true`.
-    * `webSecurity` boolean (optional) - When `false`, it will disable the
-      same-origin policy (usually using testing websites by people), and set
-      `allowRunningInsecureContent` to `true` if this options has not been set
-      by user. Default is `true`.
-    * `allowRunningInsecureContent` boolean (optional) - Allow an https page to run
-      JavaScript, CSS or plugins from http URLs. Default is `false`.
-    * `images` boolean (optional) - Enables image support. Default is `true`.
-    * `imageAnimationPolicy` string (optional) - Specifies how to run image animations (E.g. GIFs).  Can be `animate`, `animateOnce` or `noAnimation`.  Default is `animate`.
-    * `textAreasAreResizable` boolean (optional) - Make TextArea elements resizable. Default
-      is `true`.
-    * `webgl` boolean (optional) - Enables WebGL support. Default is `true`.
-    * `plugins` boolean (optional) - Whether plugins should be enabled. Default is `false`.
-    * `experimentalFeatures` boolean (optional) - Enables Chromium's experimental features.
-      Default is `false`.
-    * `scrollBounce` boolean (optional) _macOS_ - Enables scroll bounce
-      (rubber banding) effect on macOS. Default is `false`.
-    * `enableBlinkFeatures` string (optional) - A list of feature strings separated by `,`, like
-      `CSSVariables,KeyboardEventKey` to enable. The full list of supported feature
-      strings can be found in the [RuntimeEnabledFeatures.json5][runtime-enabled-features]
-      file.
-    * `disableBlinkFeatures` string (optional) - A list of feature strings separated by `,`,
-      like `CSSVariables,KeyboardEventKey` to disable. The full list of supported
-      feature strings can be found in the
-      [RuntimeEnabledFeatures.json5][runtime-enabled-features] file.
-    * `defaultFontFamily` Object (optional) - Sets the default font for the font-family.
-      * `standard` string (optional) - Defaults to `Times New Roman`.
-      * `serif` string (optional) - Defaults to `Times New Roman`.
-      * `sansSerif` string (optional) - Defaults to `Arial`.
-      * `monospace` string (optional) - Defaults to `Courier New`.
-      * `cursive` string (optional) - Defaults to `Script`.
-      * `fantasy` string (optional) - Defaults to `Impact`.
-    * `defaultFontSize` Integer (optional) - Defaults to `16`.
-    * `defaultMonospaceFontSize` Integer (optional) - Defaults to `13`.
-    * `minimumFontSize` Integer (optional) - Defaults to `0`.
-    * `defaultEncoding` string (optional) - Defaults to `ISO-8859-1`.
-    * `backgroundThrottling` boolean (optional) - Whether to throttle animations and timers
-      when the page becomes background. This also affects the
-      [Page Visibility API](#page-visibility). Defaults to `true`.
-    * `offscreen` boolean (optional) - Whether to enable offscreen rendering for the browser
-      window. Defaults to `false`. See the
-      [offscreen rendering tutorial](../tutorial/offscreen-rendering.md) for
-      more details.
-    * `contextIsolation` boolean (optional) - Whether to run Electron APIs and
-      the specified `preload` script in a separate JavaScript context. Defaults
-      to `true`. The context that the `preload` script runs in will only have
-      access to its own dedicated `document` and `window` globals, as well as
-      its own set of JavaScript builtins (`Array`, `Object`, `JSON`, etc.),
-      which are all invisible to the loaded content. The Electron API will only
-      be available in the `preload` script and not the loaded page. This option
-      should be used when loading potentially untrusted remote content to ensure
-      the loaded content cannot tamper with the `preload` script and any
-      Electron APIs being used.  This option uses the same technique used by
-      [Chrome Content Scripts][chrome-content-scripts].  You can access this
-      context in the dev tools by selecting the 'Electron Isolated Context'
-      entry in the combo box at the top of the Console tab.
-    * `webviewTag` boolean (optional) - Whether to enable the [`<webview>` tag](webview-tag.md).
-      Defaults to `false`. **Note:** The
-      `preload` script configured for the `<webview>` will have node integration
-      enabled when it is executed so you should ensure remote/untrusted content
-      is not able to create a `<webview>` tag with a possibly malicious `preload`
-      script. You can use the `will-attach-webview` event on [webContents](web-contents.md)
-      to strip away the `preload` script and to validate or alter the
-      `<webview>`'s initial settings.
-    * `additionalArguments` string[] (optional) - A list of strings that will be appended
-      to `process.argv` in the renderer process of this app.  Useful for passing small
-      bits of data down to renderer process preload scripts.
-    * `safeDialogs` boolean (optional) - Whether to enable browser style
-      consecutive dialog protection. Default is `false`.
-    * `safeDialogsMessage` string (optional) - The message to display when
-      consecutive dialog protection is triggered. If not defined the default
-      message would be used, note that currently the default message is in
-      English and not localized.
-    * `disableDialogs` boolean (optional) - Whether to disable dialogs
-      completely. Overrides `safeDialogs`. Default is `false`.
-    * `navigateOnDragDrop` boolean (optional) - Whether dragging and dropping a
-      file or link onto the page causes a navigation. Default is `false`.
-    * `autoplayPolicy` string (optional) - Autoplay policy to apply to
-      content in the window, can be `no-user-gesture-required`,
-      `user-gesture-required`, `document-user-activation-required`. Defaults to
-      `no-user-gesture-required`.
-    * `disableHtmlFullscreenWindowResize` boolean (optional) - Whether to
-      prevent the window from resizing when entering HTML Fullscreen. Default
-      is `false`.
-    * `accessibleTitle` string (optional) - An alternative title string provided only
-      to accessibility tools such as screen readers. This string is not directly
-      visible to users.
-    * `spellcheck` boolean (optional) - Whether to enable the builtin spellchecker.
-      Default is `true`.
-    * `enableWebSQL` boolean (optional) - Whether to enable the [WebSQL api](https://www.w3.org/TR/webdatabase/).
-      Default is `true`.
-    * `v8CacheOptions` string (optional) - Enforces the v8 code caching policy
-      used by blink. Accepted values are
-      * `none` - Disables code caching
-      * `code` - Heuristic based code caching
-      * `bypassHeatCheck` - Bypass code caching heuristics but with lazy compilation
-      * `bypassHeatCheckAndEagerCompile` - Same as above except compilation is eager.
-      Default policy is `code`.
-    * `enablePreferredSizeMode` boolean (optional) - Whether to enable
-      preferred size mode. The preferred size is the minimum size needed to
-      contain the layout of the document—without requiring scrolling. Enabling
-      this will cause the `preferred-size-changed` event to be emitted on the
-      `WebContents` when the preferred size changes. Default is `false`.
-  * `titleBarOverlay` Object | Boolean (optional) -  When using a frameless window in conjunction with `win.setWindowButtonVisibility(true)` on macOS or using a `titleBarStyle` so that the standard window controls ("traffic lights" on macOS) are visible, this property enables the Window Controls Overlay [JavaScript APIs][overlay-javascript-apis] and [CSS Environment Variables][overlay-css-env-vars]. Specifying `true` will result in an overlay with default system colors. Default is `false`.
-    * `color` String (optional) _Windows_ - The CSS color of the Window Controls Overlay when enabled. Default is the system color.
-    * `symbolColor` String (optional) _Windows_ - The CSS color of the symbols on the Window Controls Overlay when enabled. Default is the system color.
-    * `height` Integer (optional) _macOS_ _Windows_ - The height of the title bar and Window Controls Overlay in pixels. Default is system height.
-
-When setting minimum or maximum window size with `minWidth`/`maxWidth`/
-`minHeight`/`maxHeight`, it only constrains the users. It won't prevent you from
-passing a size that does not follow size constraints to `setBounds`/`setSize` or
-to the constructor of `BrowserWindow`.
-
-The possible values and behaviors of the `type` option are platform dependent.
-Possible values are:
-
-* On Linux, possible types are `desktop`, `dock`, `toolbar`, `splash`,
-  `notification`.
-* On macOS, possible types are `desktop`, `textured`, `panel`.
-  * The `textured` type adds metal gradient appearance
-    (`NSWindowStyleMaskTexturedBackground`).
-  * The `desktop` type places the window at the desktop background window level
-    (`kCGDesktopWindowLevel - 1`). Note that desktop window will not receive
-    focus, keyboard or mouse events, but you can use `globalShortcut` to receive
-    input sparingly.
-  * The `panel` type enables the window to float on top of full-screened apps
-    by adding the `NSWindowStyleMaskNonactivatingPanel` style mask,normally
-    reserved for NSPanel, at runtime. Also, the window will appear on all
-    spaces (desktops).
-* On Windows, possible type is `toolbar`.
+* `options` [BrowserWindowConstructorOptions](structures/browser-window-options.md?inline) (optional)
 
 ### Instance Events
 
@@ -888,7 +602,7 @@ On Linux the setter is a no-op, although the getter returns `true`.
 
 A `boolean` property that determines whether the window is excluded from the application’s Windows menu. `false` by default.
 
-```js
+```js @ts-expect-error=[11]
 const win = new BrowserWindow({ height: 600, width: 600 })
 
 const template = [
@@ -958,7 +672,7 @@ Hides the window.
 
 #### `win.isVisible()`
 
-Returns `boolean` - Whether the window is visible to the user.
+Returns `boolean` - Whether the window is visible to the user in the foreground of the app.
 
 #### `win.isModal()`
 
@@ -996,6 +710,8 @@ Returns `boolean` - Whether the window is minimized.
 
 Sets whether the window should be in fullscreen mode.
 
+**Note:** On macOS, fullscreen transitions take place asynchronously. If further actions depend on the fullscreen state, use the ['enter-full-screen'](browser-window.md#event-enter-full-screen) or ['leave-full-screen'](browser-window.md#event-leave-full-screen) events.
+
 #### `win.isFullScreen()`
 
 Returns `boolean` - Whether the window is in fullscreen mode.
@@ -1108,10 +824,14 @@ 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.
@@ -1489,6 +1209,9 @@ Node's [`url.format`](https://nodejs.org/api/url.html#url_url_format_urlobject)
 method:
 
 ```javascript
+const { BrowserWindow } = require('electron')
+const win = new BrowserWindow()
+
 const url = require('url').format({
   protocol: 'file',
   slashes: true,
@@ -1502,6 +1225,9 @@ You can load a URL using a `POST` request with URL-encoded data by doing
 the following:
 
 ```javascript
+const { BrowserWindow } = require('electron')
+const win = new BrowserWindow()
+
 win.loadURL('http://localhost:8000/post', {
   postData: [{
     type: 'rawData',
@@ -1813,6 +1539,10 @@ tabs in the window.
 Selects the next tab when native tabs are enabled and there are other
 tabs in the window.
 
+#### `win.showAllTabs()` _macOS_
+
+Shows or hides the tab overview when native tabs are enabled.
+
 #### `win.mergeAllWindows()` _macOS_
 
 Merges all windows into one window with multiple tabs when native tabs
@@ -1836,15 +1566,26 @@ Adds a window as a tab on this window, after the tab for the window instance.
 
 #### `win.setVibrancy(type)` _macOS_
 
-* `type` string | null - Can be `appearance-based`, `light`, `dark`, `titlebar`,
-  `selection`, `menu`, `popover`, `sidebar`, `medium-light`, `ultra-dark`, `header`, `sheet`, `window`, `hud`, `fullscreen-ui`, `tooltip`, `content`, `under-window`, or `under-page`. See
+* `type` string | null - Can be `titlebar`, `selection`, `menu`, `popover`, `sidebar`, `header`, `sheet`, `window`, `hud`, `fullscreen-ui`, `tooltip`, `content`, `under-window`, or `under-page`. See
   the [macOS documentation][vibrancy-docs] for more details.
 
 Adds a vibrancy effect to the browser window. Passing `null` or an empty string
 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.setBackgroundMaterial(material)` _Windows_
+
+* `material` string
+  * `auto` - Let the Desktop Window Manager (DWM) automatically decide the system-drawn backdrop material for this window. This is the default.
+  * `none` - Don't draw any system backdrop.
+  * `mica` - Draw the backdrop material effect corresponding to a long-lived window.
+  * `acrylic` - Draw the backdrop material effect corresponding to a transient window.
+  * `tabbed` - Draw the backdrop material effect corresponding to a window with a tabbed title bar.
+
+This method sets the browser window's system-drawn background material, including behind the non-client area.
+
+See the [Windows documentation](https://learn.microsoft.com/en-us/windows/win32/api/dwmapi/ne-dwmapi-dwm_systembackdrop_type) for more details.
+
+**Note:** This method is only supported on Windows 11 22H2 and up.
 
 #### `win.setWindowButtonPosition(position)` _macOS_
 
@@ -1858,25 +1599,6 @@ Passing `null` will reset the position to default.
 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
@@ -1938,8 +1660,8 @@ Throws an error if `browserView` is not attached to `win`.
 
 #### `win.getBrowserViews()` _Experimental_ _Deprecated_
 
-Returns `BrowserView[]` - an array of all BrowserViews that have been attached
-with `addBrowserView` or `setBrowserView`.
+Returns `BrowserView[]` - a sorted by z-index array of all BrowserViews that have been attached
+with `addBrowserView` or `setBrowserView`. The top-most BrowserView is the last element of the array.
 
 > **Note**
 > The `BrowserView` class is deprecated, and replaced by the new
@@ -1955,12 +1677,8 @@ with `addBrowserView` or `setBrowserView`.
 On a Window with Window Controls Overlay already enabled, this method updates
 the style of the title bar overlay.
 
-[runtime-enabled-features]: https://source.chromium.org/chromium/chromium/src/+/main:third_party/blink/renderer/platform/runtime_enabled_features.json5
 [page-visibility-api]: https://developer.mozilla.org/en-US/docs/Web/API/Page_Visibility_API
 [quick-look]: https://en.wikipedia.org/wiki/Quick_Look
 [vibrancy-docs]: https://developer.apple.com/documentation/appkit/nsvisualeffectview?preferredLanguage=objc
 [window-levels]: https://developer.apple.com/documentation/appkit/nswindow/level
-[chrome-content-scripts]: https://developer.chrome.com/extensions/content_scripts#execution-environment
 [event-emitter]: https://nodejs.org/api/events.html#events_class_eventemitter
-[overlay-javascript-apis]: https://github.com/WICG/window-controls-overlay/blob/main/explainer.md#javascript-apis
-[overlay-css-env-vars]: https://github.com/WICG/window-controls-overlay/blob/main/explainer.md#css-environment-variables

+ 4 - 4
docs/api/client-request.md

@@ -65,7 +65,7 @@ strictly follow the Node.js model as described in the
 
 For instance, we could have created the same request to 'github.com' as follows:
 
-```JavaScript
+```javascript
 const request = net.request({
   method: 'GET',
   protocol: 'https:',
@@ -104,7 +104,7 @@ The `callback` function is expected to be called back with user credentials:
 * `username` string
 * `password` string
 
-```JavaScript
+```javascript @ts-type={request:Electron.ClientRequest}
 request.on('login', (authInfo, callback) => {
   callback('username', 'password')
 })
@@ -113,9 +113,9 @@ request.on('login', (authInfo, callback) => {
 Providing empty credentials will cancel the request and report an authentication
 error on the response object:
 
-```JavaScript
+```javascript @ts-type={request:Electron.ClientRequest}
 request.on('response', (response) => {
-  console.log(`STATUS: ${response.statusCode}`);
+  console.log(`STATUS: ${response.statusCode}`)
   response.on('error', (error) => {
     console.log(`ERROR: ${JSON.stringify(error)}`)
   })

+ 1 - 4
docs/api/clipboard.md

@@ -148,10 +148,7 @@ clipboard.
 ```js
 const { clipboard } = require('electron')
 
-clipboard.writeBookmark({
-  text: 'https://electronjs.org',
-  bookmark: 'Electron Homepage'
-})
+clipboard.writeBookmark('Electron Homepage', 'https://electronjs.org')
 ```
 
 ### `clipboard.readFindText()` _macOS_

+ 44 - 7
docs/api/command-line-switches.md

@@ -116,14 +116,20 @@ Ignore the connections limit for `domains` list separated by `,`.
 
 ### --js-flags=`flags`
 
-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.
+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.
 
 ```sh
 $ electron --js-flags="--harmony_proxies --harmony_collections" 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.
+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
+```
 
 ### --lang
 
@@ -241,19 +247,25 @@ 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-port=\[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`
 
 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`.
 
@@ -263,12 +275,37 @@ 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

+ 2 - 2
docs/api/context-bridge.md

@@ -18,7 +18,7 @@ contextBridge.exposeInMainWorld(
 )
 ```
 
-```javascript
+```javascript @ts-nocheck
 // Renderer (Main World)
 
 window.electron.doThing()
@@ -104,7 +104,7 @@ contextBridge.exposeInIsolatedWorld(
 )
 ```
 
-```javascript
+```javascript @ts-nocheck
 // Renderer (In isolated world id1004)
 
 window.electron.doThing()

+ 2 - 2
docs/api/cookies.md

@@ -22,7 +22,7 @@ session.defaultSession.cookies.get({})
   })
 
 // Query all cookies associated with a specific url.
-session.defaultSession.cookies.get({ url: 'http://www.github.com' })
+session.defaultSession.cookies.get({ url: 'https://www.github.com' })
   .then((cookies) => {
     console.log(cookies)
   }).catch((error) => {
@@ -31,7 +31,7 @@ session.defaultSession.cookies.get({ url: 'http://www.github.com' })
 
 // Set a cookie with the given cookie data;
 // may overwrite equivalent cookies if they exist.
-const cookie = { url: 'http://www.github.com', name: 'dummy_name', value: 'dummy' }
+const cookie = { url: 'https://www.github.com', name: 'dummy_name', value: 'dummy' }
 session.defaultSession.cookies.set(cookie)
   .then(() => {
     // success

+ 1 - 1
docs/api/crash-reporter.md

@@ -16,7 +16,7 @@ crashReporter.start({ submitURL: 'https://your-domain.com/url-to-submit' })
 For setting up a server to accept and process crash reports, you can use
 following projects:
 
-* [socorro](https://github.com/mozilla/socorro)
+* [socorro](https://github.com/mozilla-services/socorro)
 * [mini-breakpad-server](https://github.com/electron/mini-breakpad-server)
 
 > **Note:** Electron uses Crashpad, not Breakpad, to collect and upload

+ 5 - 3
docs/api/desktop-capturer.md

@@ -10,7 +10,9 @@ title is `Electron`:
 
 ```javascript
 // In the main process.
-const { desktopCapturer } = require('electron')
+const { BrowserWindow, desktopCapturer } = require('electron')
+
+const mainWindow = new BrowserWindow()
 
 desktopCapturer.getSources({ types: ['window', 'screen'] }).then(async sources => {
   for (const source of sources) {
@@ -22,7 +24,7 @@ desktopCapturer.getSources({ types: ['window', 'screen'] }).then(async sources =
 })
 ```
 
-```javascript
+```javascript @ts-nocheck
 // In the preload script.
 const { ipcRenderer } = require('electron')
 
@@ -89,7 +91,7 @@ The `desktopCapturer` module has the following methods:
 
 * `options` Object
   * `types` string[] - An array of strings that lists the types of desktop sources
-    to be captured, available types are `screen` and `window`.
+    to be captured, available types can be `screen` and `window`.
   * `thumbnailSize` [Size](structures/size.md) (optional) - The size that the media source thumbnail
     should be scaled to. Default is `150` x `150`. Set width or height to 0 when you do not need
     the thumbnails. This will save the processing time required for capturing the content of each

+ 10 - 10
docs/api/dialog.md

@@ -72,7 +72,7 @@ and a directory selector, so if you set `properties` to
 `['openFile', 'openDirectory']` on these platforms, a directory selector will be
 shown.
 
-```js
+```js @ts-type={mainWindow:Electron.BrowserWindow}
 dialog.showOpenDialogSync(mainWindow, {
   properties: ['openFile', 'openDirectory']
 })
@@ -139,7 +139,7 @@ and a directory selector, so if you set `properties` to
 `['openFile', 'openDirectory']` on these platforms, a directory selector will be
 shown.
 
-```js
+```js @ts-type={mainWindow:Electron.BrowserWindow}
 dialog.showOpenDialog(mainWindow, {
   properties: ['openFile', 'openDirectory']
 }).then(result => {
@@ -223,10 +223,10 @@ expanding and collapsing the dialog.
 * `browserWindow` [BrowserWindow](browser-window.md) (optional)
 * `options` Object
   * `message` string - Content of the message box.
-  * `type` string (optional) - Can be `"none"`, `"info"`, `"error"`, `"question"` or
-  `"warning"`. On Windows, `"question"` displays the same icon as `"info"`, unless
-  you set an icon using the `"icon"` option. On macOS, both `"warning"` and
-  `"error"` display the same warning icon.
+  * `type` string (optional) - Can be `none`, `info`, `error`, `question` or
+  `warning`. On Windows, `question` displays the same icon as `info`, unless
+  you set an icon using the `icon` option. On macOS, both `warning` and
+  `error` display the same warning icon.
   * `buttons` string[]&#32;(optional) - Array of texts for buttons. On Windows, an empty array
     will result in one button labeled "OK".
   * `defaultId` Integer (optional) - Index of the button in the buttons array which will
@@ -266,10 +266,10 @@ If `browserWindow` is not shown dialog will not be attached to it. In such case
 * `browserWindow` [BrowserWindow](browser-window.md) (optional)
 * `options` Object
   * `message` string - Content of the message box.
-  * `type` string (optional) - Can be `"none"`, `"info"`, `"error"`, `"question"` or
-  `"warning"`. On Windows, `"question"` displays the same icon as `"info"`, unless
-  you set an icon using the `"icon"` option. On macOS, both `"warning"` and
-  `"error"` display the same warning icon.
+  * `type` string (optional) - Can be `none`, `info`, `error`, `question` or
+  `warning`. On Windows, `question` displays the same icon as `info`, unless
+  you set an icon using the `icon` option. On macOS, both `warning` and
+  `error` display the same warning icon.
   * `buttons` string[]&#32;(optional) - Array of texts for buttons. On Windows, an empty array
     will result in one button labeled "OK".
   * `defaultId` Integer (optional) - Index of the button in the buttons array which will

+ 62 - 13
docs/api/extensions.md

@@ -40,18 +40,41 @@ We support the following extensions APIs, with some caveats. Other APIs may
 additionally be supported, but support for any APIs not listed here is
 provisional and may be removed.
 
+### Supported Manifest Keys
+
+- `name`
+- `version`
+- `author`
+- `permissions`
+- `content_scripts`
+- `default_locale`
+- `devtools_page`
+- `short_name`
+- `host_permissions` (Manifest V3)
+- `manifest_version`
+- `background` (Manifest V2)
+- `minimum_chrome_version`
+
+See [Manifest file format](https://developer.chrome.com/docs/extensions/mv3/manifest/) for more information about the purpose of each possible key.
+
 ### `chrome.devtools.inspectedWindow`
 
 All features of this API are supported.
 
+See [official documentation](https://developer.chrome.com/docs/extensions/reference/devtools_inspectedWindow) for more information.
+
 ### `chrome.devtools.network`
 
 All features of this API are supported.
 
+See [official documentation](https://developer.chrome.com/docs/extensions/reference/devtools_network) for more information.
+
 ### `chrome.devtools.panels`
 
 All features of this API are supported.
 
+See [official documentation](https://developer.chrome.com/docs/extensions/reference/devtools_panels) for more information.
+
 ### `chrome.extension`
 
 The following properties of `chrome.extension` are supported:
@@ -63,6 +86,25 @@ The following methods of `chrome.extension` are supported:
 - `chrome.extension.getURL`
 - `chrome.extension.getBackgroundPage`
 
+See [official documentation](https://developer.chrome.com/docs/extensions/reference/extension) for more information.
+
+### `chrome.management`
+
+The following methods of `chrome.management` are supported:
+
+- `chrome.management.getAll`
+- `chrome.management.get`
+- `chrome.management.getSelf`
+- `chrome.management.getPermissionWarningsById`
+- `chrome.management.getPermissionWarningsByManifest`
+
+The following events of `chrome.management` are supported:
+
+- `chrome.management.onEnabled`
+- `chrome.management.onDisabled`
+
+See [official documentation](https://developer.chrome.com/docs/extensions/reference/management) for more information.
+
 ### `chrome.runtime`
 
 The following properties of `chrome.runtime` are supported:
@@ -89,10 +131,23 @@ The following events of `chrome.runtime` are supported:
 - `chrome.runtime.onConnect`
 - `chrome.runtime.onMessage`
 
+See [official documentation](https://developer.chrome.com/docs/extensions/reference/runtime) for more information.
+
+### `chrome.scripting`
+
+All features of this API are supported.
+
+See [official documentation](https://developer.chrome.com/docs/extensions/reference/scripting) for more information.
+
 ### `chrome.storage`
 
-Only `chrome.storage.local` is supported; `chrome.storage.sync` and
-`chrome.storage.managed` are not.
+The following methods of `chrome.storage` are supported:
+
+- `chrome.storage.local`
+
+`chrome.storage.sync` and `chrome.storage.managed` are **not** supported.
+
+See [official documentation](https://developer.chrome.com/docs/extensions/reference/storage) for more information.
 
 ### `chrome.tabs`
 
@@ -101,6 +156,8 @@ 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`.
 
@@ -108,20 +165,12 @@ The following methods of `chrome.tabs` are supported:
 > tab". Since Electron has no such concept, passing `-1` as a tab ID is not
 > supported and will raise an error.
 
-### `chrome.management`
-
-The following methods of `chrome.management` are supported:
-
-- `chrome.management.getAll`
-- `chrome.management.get`
-- `chrome.management.getSelf`
-- `chrome.management.getPermissionWarningsById`
-- `chrome.management.getPermissionWarningsByManifest`
-- `chrome.management.onEnabled`
-- `chrome.management.onDisabled`
+See [official documentation](https://developer.chrome.com/docs/extensions/reference/tabs) for more information.
 
 ### `chrome.webRequest`
 
 All features of this API are supported.
 
 > **NOTE:** Electron's [`webRequest`](web-request.md) module takes precedence over `chrome.webRequest` if there are conflicting handlers.
+
+See [official documentation](https://developer.chrome.com/docs/extensions/reference/webRequest) for more information.

+ 2 - 2
docs/api/incoming-message.md

@@ -89,7 +89,7 @@ tuples. So, the even-numbered offsets are key values, and the odd-numbered
 offsets are the associated values. Header names are not lowercased, and
 duplicates are not merged.
 
-```javascript
+```javascript @ts-type={response:Electron.IncomingMessage}
 // Prints something like:
 //
 // [ 'user-agent',
@@ -100,5 +100,5 @@ duplicates are not merged.
 //   '127.0.0.1:8000',
 //   'ACCEPT',
 //   '*/*' ]
-console.log(request.rawHeaders)
+console.log(response.rawHeaders)
 ```

+ 5 - 16
docs/api/ipc-main.md

@@ -72,7 +72,7 @@ Removes listeners of the specified `channel`.
 ### `ipcMain.handle(channel, listener)`
 
 * `channel` string
-* `listener` Function<Promise\<void&#62; | any&#62;
+* `listener` Function<Promise\<any&#62; | any&#62;
   * `event` [IpcMainInvokeEvent][ipc-main-invoke-event]
   * `...args` any[]
 
@@ -83,14 +83,14 @@ If `listener` returns a Promise, the eventual result of the promise will be
 returned as a reply to the remote caller. Otherwise, the return value of the
 listener will be used as the value of the reply.
 
-```js title='Main Process'
+```js title='Main Process' @ts-type={somePromise:(...args:unknown[])=>Promise<unknown>}
 ipcMain.handle('my-invokable-ipc', async (event, ...args) => {
   const result = await somePromise(...args)
   return result
 })
 ```
 
-```js title='Renderer Process'
+```js title='Renderer Process' @ts-type={arg1:unknown} @ts-type={arg2:unknown}
 async () => {
   const result = await ipcRenderer.invoke('my-invokable-ipc', arg1, arg2)
   // ...
@@ -109,8 +109,8 @@ provided to the renderer process. Please refer to
 ### `ipcMain.handleOnce(channel, listener)`
 
 * `channel` string
-* `listener` Function<Promise\<void&#62; | any&#62;
-  * `event` IpcMainInvokeEvent
+* `listener` Function<Promise\<any&#62; | any&#62;
+  * `event` [IpcMainInvokeEvent][ipc-main-invoke-event]
   * `...args` any[]
 
 Handles a single `invoke`able IPC message, then removes the listener. See
@@ -122,17 +122,6 @@ 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

+ 4 - 16
docs/api/ipc-renderer.md

@@ -26,7 +26,7 @@ The `ipcRenderer` module has the following method to listen for events and send
 
 * `channel` string
 * `listener` Function
-  * `event` IpcRendererEvent
+  * `event` [IpcRendererEvent][ipc-renderer-event]
   * `...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
+  * `event` [IpcRendererEvent][ipc-renderer-event]
   * `...args` any[]
 
 Adds a one time `listener` function for the event. This `listener` is invoked
@@ -101,7 +101,7 @@ The main process should listen for `channel` with
 
 For example:
 
-```javascript
+```javascript @ts-type={someArgument:unknown} @ts-type={doSomeWork:(arg:unknown)=>Promise<unknown>}
 // Renderer process
 ipcRenderer.invoke('some-name', someArgument).then((result) => {
   // ...
@@ -192,14 +192,6 @@ ipcMain.on('port', (e, msg) => {
 For more information on using `MessagePort` and `MessageChannel`, see the [MDN
 documentation](https://developer.mozilla.org/en-US/docs/Web/API/MessageChannel).
 
-### `ipcRenderer.sendTo(webContentsId, channel, ...args)`
-
-* `webContentsId` number
-* `channel` string
-* `...args` any[]
-
-Sends a message to a window with `webContentsId` via `channel`.
-
 ### `ipcRenderer.sendToHost(channel, ...args)`
 
 * `channel` string
@@ -208,12 +200,8 @@ 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

+ 3 - 2
docs/api/menu-item.md

@@ -14,7 +14,7 @@ See [`Menu`](menu.md) for examples.
     * `menuItem` MenuItem
     * `browserWindow` [BrowserWindow](browser-window.md) | undefined - This will not be defined if no window is open.
     * `event` [KeyboardEvent](structures/keyboard-event.md)
-  * `role` string (optional) - Can be `undo`, `redo`, `cut`, `copy`, `paste`, `pasteAndMatchStyle`, `delete`, `selectAll`, `reload`, `forceReload`, `toggleDevTools`, `resetZoom`, `zoomIn`, `zoomOut`, `toggleSpellChecker`, `togglefullscreen`, `window`, `minimize`, `close`, `help`, `about`, `services`, `hide`, `hideOthers`, `unhide`, `quit`, `showSubstitutions`, `toggleSmartQuotes`, `toggleSmartDashes`, `toggleTextReplacement`, `startSpeaking`, `stopSpeaking`, `zoom`, `front`, `appMenu`, `fileMenu`, `editMenu`, `viewMenu`, `shareMenu`, `recentDocuments`, `toggleTabBar`, `selectNextTab`, `selectPreviousTab`, `mergeAllWindows`, `clearRecentDocuments`, `moveTabToNewWindow` or `windowMenu` - Define the action of the menu item, when specified the
+  * `role` string (optional) - Can be `undo`, `redo`, `cut`, `copy`, `paste`, `pasteAndMatchStyle`, `delete`, `selectAll`, `reload`, `forceReload`, `toggleDevTools`, `resetZoom`, `zoomIn`, `zoomOut`, `toggleSpellChecker`, `togglefullscreen`, `window`, `minimize`, `close`, `help`, `about`, `services`, `hide`, `hideOthers`, `unhide`, `quit`, `showSubstitutions`, `toggleSmartQuotes`, `toggleSmartDashes`, `toggleTextReplacement`, `startSpeaking`, `stopSpeaking`, `zoom`, `front`, `appMenu`, `fileMenu`, `editMenu`, `viewMenu`, `shareMenu`, `recentDocuments`, `toggleTabBar`, `selectNextTab`, `selectPreviousTab`, `showAllTabs`, `mergeAllWindows`, `clearRecentDocuments`, `moveTabToNewWindow` or `windowMenu` - Define the action of the menu item, when specified the
     `click` property will be ignored. See [roles](#roles).
   * `type` string (optional) - Can be `normal`, `separator`, `submenu`, `checkbox` or
     `radio`.
@@ -111,6 +111,7 @@ The following additional roles are available on _macOS_:
 * `toggleTabBar` - Map to the `toggleTabBar` action.
 * `selectNextTab` - Map to the `selectNextTab` action.
 * `selectPreviousTab` - Map to the `selectPreviousTab` action.
+* `showAllTabs` - Map to the `showAllTabs` action.
 * `mergeAllWindows` - Map to the `mergeAllWindows` action.
 * `moveTabToNewWindow` - Map to the `moveTabToNewWindow` action.
 * `window` - The submenu is a "Window" menu.
@@ -159,7 +160,7 @@ A `string` indicating the type of the item. Can be `normal`, `separator`, `subme
 
 #### `menuItem.role`
 
-A `string` (optional) indicating the item's role, if set. Can be `undo`, `redo`, `cut`, `copy`, `paste`, `pasteAndMatchStyle`, `delete`, `selectAll`, `reload`, `forceReload`, `toggleDevTools`, `resetZoom`, `zoomIn`, `zoomOut`, `toggleSpellChecker`, `togglefullscreen`, `window`, `minimize`, `close`, `help`, `about`, `services`, `hide`, `hideOthers`, `unhide`, `quit`, `startSpeaking`, `stopSpeaking`, `zoom`, `front`, `appMenu`, `fileMenu`, `editMenu`, `viewMenu`, `shareMenu`, `recentDocuments`, `toggleTabBar`, `selectNextTab`, `selectPreviousTab`, `mergeAllWindows`, `clearRecentDocuments`, `moveTabToNewWindow` or `windowMenu`
+A `string` (optional) indicating the item's role, if set. Can be `undo`, `redo`, `cut`, `copy`, `paste`, `pasteAndMatchStyle`, `delete`, `selectAll`, `reload`, `forceReload`, `toggleDevTools`, `resetZoom`, `zoomIn`, `zoomOut`, `toggleSpellChecker`, `togglefullscreen`, `window`, `minimize`, `close`, `help`, `about`, `services`, `hide`, `hideOthers`, `unhide`, `quit`, `startSpeaking`, `stopSpeaking`, `zoom`, `front`, `appMenu`, `fileMenu`, `editMenu`, `viewMenu`, `shareMenu`, `recentDocuments`, `toggleTabBar`, `selectNextTab`, `selectPreviousTab`, `showAllTabs`, `mergeAllWindows`, `clearRecentDocuments`, `moveTabToNewWindow` or `windowMenu`
 
 #### `menuItem.accelerator`
 

+ 51 - 41
docs/api/menu.md

@@ -80,6 +80,10 @@ The `menu` object has the following instance methods:
   * `positioningItem` number (optional) _macOS_ - The index of the menu item to
     be positioned under the mouse cursor at the specified coordinates. Default
     is -1.
+  * `sourceType` string (optional) _Windows_ _Linux_ - This should map to the `menuSourceType`
+    provided by the `context-menu` event. It is not recommended to set this value manually,
+    only provide values you receive from other APIs or leave it `undefined`.
+    Can be `none`, `mouse`, `keyboard`, `touch`, `touchMenu`, `longPress`, `longTap`, `touchHandle`, `stylus`, `adjustSelection`, or `adjustSelectionReset`.
   * `callback` Function (optional) - Called when menu is closed.
 
 Pops up this menu as a context menu in the [`BrowserWindow`](browser-window.md).
@@ -147,27 +151,29 @@ can have a submenu.
 
 An example of creating the application menu with the simple template API:
 
-```javascript
+```javascript @ts-expect-error=[107]
 const { app, Menu } = require('electron')
 
 const isMac = process.platform === 'darwin'
 
 const template = [
   // { role: 'appMenu' }
-  ...(isMac ? [{
-    label: app.name,
-    submenu: [
-      { role: 'about' },
-      { type: 'separator' },
-      { role: 'services' },
-      { type: 'separator' },
-      { role: 'hide' },
-      { role: 'hideOthers' },
-      { role: 'unhide' },
-      { type: 'separator' },
-      { role: 'quit' }
-    ]
-  }] : []),
+  ...(isMac
+    ? [{
+        label: app.name,
+        submenu: [
+          { role: 'about' },
+          { type: 'separator' },
+          { role: 'services' },
+          { type: 'separator' },
+          { role: 'hide' },
+          { role: 'hideOthers' },
+          { role: 'unhide' },
+          { type: 'separator' },
+          { role: 'quit' }
+        ]
+      }]
+    : []),
   // { role: 'fileMenu' }
   {
     label: 'File',
@@ -185,23 +191,25 @@ const template = [
       { role: 'cut' },
       { role: 'copy' },
       { role: 'paste' },
-      ...(isMac ? [
-        { role: 'pasteAndMatchStyle' },
-        { role: 'delete' },
-        { role: 'selectAll' },
-        { type: 'separator' },
-        {
-          label: 'Speech',
-          submenu: [
-            { role: 'startSpeaking' },
-            { role: 'stopSpeaking' }
+      ...(isMac
+        ? [
+            { role: 'pasteAndMatchStyle' },
+            { role: 'delete' },
+            { role: 'selectAll' },
+            { type: 'separator' },
+            {
+              label: 'Speech',
+              submenu: [
+                { role: 'startSpeaking' },
+                { role: 'stopSpeaking' }
+              ]
+            }
           ]
-        }
-      ] : [
-        { role: 'delete' },
-        { type: 'separator' },
-        { role: 'selectAll' }
-      ])
+        : [
+            { role: 'delete' },
+            { type: 'separator' },
+            { role: 'selectAll' }
+          ])
     ]
   },
   // { role: 'viewMenu' }
@@ -225,14 +233,16 @@ const template = [
     submenu: [
       { role: 'minimize' },
       { role: 'zoom' },
-      ...(isMac ? [
-        { type: 'separator' },
-        { role: 'front' },
-        { type: 'separator' },
-        { role: 'window' }
-      ] : [
-        { role: 'close' }
-      ])
+      ...(isMac
+        ? [
+            { type: 'separator' },
+            { role: 'front' },
+            { type: 'separator' },
+            { role: 'window' }
+          ]
+        : [
+            { role: 'close' }
+          ])
     ]
   },
   {
@@ -261,7 +271,7 @@ menu on behalf of the renderer.
 
 Below is an example of showing a menu when the user right clicks the page:
 
-```js
+```js @ts-expect-error=[21]
 // renderer
 window.addEventListener('contextmenu', (e) => {
   e.preventDefault()
@@ -283,7 +293,7 @@ ipcMain.on('show-context-menu', (event) => {
     { label: 'Menu Item 2', type: 'checkbox', checked: true }
   ]
   const menu = Menu.buildFromTemplate(template)
-  menu.popup(BrowserWindow.fromWebContents(event.sender))
+  menu.popup({ window: BrowserWindow.fromWebContents(event.sender) })
 })
 ```
 

+ 4 - 3
docs/api/message-channel-main.md

@@ -17,7 +17,8 @@ Example:
 
 ```js
 // Main process
-const { MessageChannelMain } = require('electron')
+const { BrowserWindow, MessageChannelMain } = require('electron')
+const w = new BrowserWindow()
 const { port1, port2 } = new MessageChannelMain()
 w.webContents.postMessage('port', null, [port2])
 port1.postMessage({ some: 'message' })
@@ -26,9 +27,9 @@ port1.postMessage({ some: 'message' })
 const { ipcRenderer } = require('electron')
 ipcRenderer.on('port', (e) => {
   // e.ports is a list of ports sent along with this message
-  e.ports[0].on('message', (messageEvent) => {
+  e.ports[0].onmessage = (messageEvent) => {
     console.log(messageEvent.data)
-  })
+  }
 })
 ```
 

+ 1 - 1
docs/api/native-image.md

@@ -306,7 +306,7 @@ Returns `NativeImage` - The cropped image.
   * `width` Integer (optional) - Defaults to the image's width.
   * `height` Integer (optional) - Defaults to the image's height.
   * `quality` string (optional) - The desired quality of the resize image.
-    Possible values are `good`, `better`, or `best`. The default is `best`.
+    Possible values include `good`, `better`, or `best`. The default is `best`.
     These values express a desired quality/speed tradeoff. They are translated
     into an algorithm-specific method that depends on the capabilities
     (CPU, GPU) of the underlying platform. It is possible for all three methods

+ 1 - 1
docs/api/net-log.md

@@ -5,7 +5,7 @@
 Process: [Main](../glossary.md#main-process)
 
 ```javascript
-const { netLog } = require('electron')
+const { app, netLog } = require('electron')
 
 app.whenReady().then(async () => {
   await netLog.startLogging('/path/to/net-log')

+ 39 - 0
docs/api/net.md

@@ -129,6 +129,45 @@ won't be able to connect to remote sites. However, a return value of
 whether a particular connection attempt to a particular remote site
 will be successful.
 
+#### `net.resolveHost(host, [options])`
+
+* `host` string - Hostname to resolve.
+* `options` Object (optional)
+  * `queryType` string (optional) - Requested DNS query type. If unspecified,
+    resolver will pick A or AAAA (or both) based on IPv4/IPv6 settings:
+    * `A` - Fetch only A records
+    * `AAAA` - Fetch only AAAA records.
+  * `source` string (optional) - The source to use for resolved addresses.
+    Default allows the resolver to pick an appropriate source. Only affects use
+    of big external sources (e.g. calling the system for resolution or using
+    DNS). Even if a source is specified, results can still come from cache,
+    resolving "localhost" or IP literals, etc. One of the following values:
+    * `any` (default) - Resolver will pick an appropriate source. Results could
+      come from DNS, MulticastDNS, HOSTS file, etc
+    * `system` - Results will only be retrieved from the system or OS, e.g. via
+      the `getaddrinfo()` system call
+    * `dns` - Results will only come from DNS queries
+    * `mdns` - Results will only come from Multicast DNS queries
+    * `localOnly` - No external sources will be used. Results will only come
+      from fast local sources that are available no matter the source setting,
+      e.g. cache, hosts file, IP literal resolution, etc.
+  * `cacheUsage` string (optional) - Indicates what DNS cache entries, if any,
+    can be used to provide a response. One of the following values:
+    * `allowed` (default) - Results may come from the host cache if non-stale
+    * `staleAllowed` - Results may come from the host cache even if stale (by
+      expiration or network changes)
+    * `disallowed` - Results will not come from the host cache.
+  * `secureDnsPolicy` string (optional) - Controls the resolver's Secure DNS
+    behavior for this request. One of the following values:
+    * `allow` (default)
+    * `disable`
+
+Returns [`Promise<ResolvedHost>`](structures/resolved-host.md) - Resolves with the resolved IP addresses for the `host`.
+
+This method will resolve hosts from the [default
+session](session.md#sessiondefaultsession). To resolve a host from
+another session, use [ses.resolveHost()](session.md#sesresolvehosthost-options).
+
 ## Properties
 
 ### `net.online` _Readonly_

+ 29 - 1
docs/api/power-monitor.md

@@ -24,6 +24,30 @@ Emitted when the system changes to AC power.
 
 Emitted when system changes to battery power.
 
+### Event: 'thermal-state-change' _macOS_
+
+* `state` string - The system's new thermal state. Can be `unknown`, `nominal`, `fair`, `serious`, `critical`.
+
+Emitted when the thermal state of the system changes. Notification of a change
+in the thermal status of the system, such as entering a critical temperature
+range. Depending on the severity, the system might take steps to reduce said
+temperature, for example, throttling the CPU or switching on the fans if
+available.
+
+Apps may react to the new state by reducing expensive computing tasks (e.g.
+video encoding), or notifying the user. The same state might be received
+repeatedly.
+
+See https://developer.apple.com/library/archive/documentation/Performance/Conceptual/power_efficiency_guidelines_osx/RespondToThermalStateChanges.html
+
+### Event: 'speed-limit-change' _macOS_ _Windows_
+
+* `limit` number - The operating system's advertised speed limit for CPUs, in percent.
+
+Notification of a change in the operating system's advertised speed limit for
+CPUs, in percent. Values below 100 indicate that the system is impairing
+processing power due to thermal management.
+
 ### Event: 'shutdown' _Linux_ _macOS_
 
 Emitted when the system is about to reboot or shut down. If the event handler
@@ -55,7 +79,7 @@ The `powerMonitor` module has the following methods:
 
 * `idleThreshold` Integer
 
-Returns `string` - The system's current state. Can be `active`, `idle`, `locked` or `unknown`.
+Returns `string` - The system's current idle state. Can be `active`, `idle`, `locked` or `unknown`.
 
 Calculate the system idle state. `idleThreshold` is the amount of time (in seconds)
 before considered idle.  `locked` is available on supported systems only.
@@ -66,6 +90,10 @@ Returns `Integer` - Idle time in seconds
 
 Calculate system idle time in seconds.
 
+### `powerMonitor.getCurrentThermalState()` _macOS_
+
+Returns `string` - The system's current thermal state. Can be `unknown`, `nominal`, `fair`, `serious`, or `critical`.
+
 ### `powerMonitor.isOnBatteryPower()`
 
 Returns `boolean` - Whether the system is on battery power.

+ 2 - 0
docs/api/power-save-blocker.md

@@ -49,6 +49,8 @@ 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`.

+ 9 - 9
docs/api/protocol.md

@@ -32,7 +32,7 @@ To have your custom protocol work in combination with a custom session, you need
 to register it to that session explicitly.
 
 ```javascript
-const { session, app, protocol } = require('electron')
+const { app, BrowserWindow, net, protocol, session } = require('electron')
 const path = require('path')
 const url = require('url')
 
@@ -41,11 +41,11 @@ app.whenReady().then(() => {
   const ses = session.fromPartition(partition)
 
   ses.protocol.handle('atom', (request) => {
-    const path = request.url.slice('atom://'.length)
-    return net.fetch(url.pathToFileURL(path.join(__dirname, path)))
+    const filePath = request.url.slice('atom://'.length)
+    return net.fetch(url.pathToFileURL(path.join(__dirname, filePath)).toString())
   })
 
-  mainWindow = new BrowserWindow({ webPreferences: { partition } })
+  const mainWindow = new BrowserWindow({ webPreferences: { partition } })
 })
 ```
 
@@ -121,9 +121,9 @@ Either a `Response` or a `Promise<Response>` can be returned.
 Example:
 
 ```js
-import { app, protocol } from 'electron'
-import { join } from 'path'
-import { pathToFileURL } from 'url'
+const { app, net, protocol } = require('electron')
+const { join } = require('path')
+const { pathToFileURL } = require('url')
 
 protocol.registerSchemesAsPrivileged([
   {
@@ -131,7 +131,7 @@ protocol.registerSchemesAsPrivileged([
     privileges: {
       standard: true,
       secure: true,
-      supportsFetchAPI: true
+      supportFetchAPI: true
     }
   }
 ])
@@ -147,7 +147,7 @@ app.whenReady().then(() => {
       }
       // 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)))
+      return net.fetch(pathToFileURL(join(__dirname, pathname)).toString())
     } else if (host === 'api') {
       return net.fetch('https://api.my-server.com/' + pathname, {
         method: req.method,

+ 25 - 0
docs/api/safe-storage.md

@@ -38,3 +38,28 @@ 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_libsecret` - 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-libsecret"`.
+* `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.

+ 118 - 51
docs/api/session.md

@@ -13,7 +13,7 @@ property of [`WebContents`](web-contents.md), or from the `session` module.
 const { BrowserWindow } = require('electron')
 
 const win = new BrowserWindow({ width: 800, height: 600 })
-win.loadURL('http://github.com')
+win.loadURL('https://github.com')
 
 const ses = win.webContents.session
 console.log(ses.getUserAgent())
@@ -98,7 +98,7 @@ Emitted when Electron is about to download `item` in `webContents`.
 Calling `event.preventDefault()` will cancel the download and `item` will not be
 available from next tick of the process.
 
-```javascript
+```javascript @ts-expect-error=[4]
 const { session } = require('electron')
 session.defaultSession.on('will-download', (event, item, webContents) => {
   event.preventDefault()
@@ -214,7 +214,7 @@ cancel the request.  Additionally, permissioning on `navigator.hid` can
 be further managed by using [`ses.setPermissionCheckHandler(handler)`](#sessetpermissioncheckhandlerhandler)
 and [`ses.setDevicePermissionHandler(handler)`](#sessetdevicepermissionhandlerhandler).
 
-```javascript
+```javascript @ts-type={fetchGrantedDevices:()=>(Array<Electron.DevicePermissionHandlerHandlerDetails['device']>)}
 const { app, BrowserWindow } = require('electron')
 
 let win = null
@@ -253,7 +253,7 @@ app.whenReady().then(() => {
   win.webContents.session.on('select-hid-device', (event, details, callback) => {
     event.preventDefault()
     const selectedDevice = details.deviceList.find((device) => {
-      return device.vendorId === '9025' && device.productId === '67'
+      return device.vendorId === 9025 && device.productId === 67
     })
     callback(selectedDevice?.deviceId)
   })
@@ -320,7 +320,7 @@ cancel the request.  Additionally, permissioning on `navigator.serial` can
 be managed by using [ses.setPermissionCheckHandler(handler)](#sessetpermissioncheckhandlerhandler)
 with the `serial` permission.
 
-```javascript
+```javascript @ts-type={fetchGrantedDevices:()=>(Array<Electron.DevicePermissionHandlerHandlerDetails['device']>)}
 const { app, BrowserWindow } = require('electron')
 
 let win = null
@@ -463,7 +463,7 @@ cancel the request.  Additionally, permissioning on `navigator.usb` can
 be further managed by using [`ses.setPermissionCheckHandler(handler)`](#sessetpermissioncheckhandlerhandler)
 and [`ses.setDevicePermissionHandler(handler)`](#sessetdevicepermissionhandlerhandler).
 
-```javascript
+```javascript @ts-type={fetchGrantedDevices:()=>(Array<Electron.DevicePermissionHandlerHandlerDetails['device']>)} @ts-type={updateGrantedDevices:(devices:Array<Electron.DevicePermissionHandlerHandlerDetails['device']>)=>void}
 const { app, BrowserWindow } = require('electron')
 
 let win = null
@@ -502,7 +502,7 @@ app.whenReady().then(() => {
   win.webContents.session.on('select-usb-device', (event, details, callback) => {
     event.preventDefault()
     const selectedDevice = details.deviceList.find((device) => {
-      return device.vendorId === '9025' && device.productId === '67'
+      return device.vendorId === 9025 && device.productId === 67
     })
     if (selectedDevice) {
       // Optionally, add this to the persisted devices (updateGrantedDevices needs to be implemented by developer to persist permissions)
@@ -519,9 +519,8 @@ app.whenReady().then(() => {
 Returns:
 
 * `event` Event
-* `details` Object
-  * `device` [USBDevice](structures/usb-device.md)
-  * `frame` [WebFrameMain](web-frame-main.md)
+* `device` [USBDevice](structures/usb-device.md)
+* `webContents` [WebContents](web-contents.md)
 
 Emitted after `navigator.usb.requestDevice` has been called and
 `select-usb-device` has fired if a new device becomes available before
@@ -534,9 +533,8 @@ with the newly added device.
 Returns:
 
 * `event` Event
-* `details` Object
-  * `device` [USBDevice](structures/usb-device.md)
-  * `frame` [WebFrameMain](web-frame-main.md)
+* `device` [USBDevice](structures/usb-device.md)
+* `webContents` [WebContents](web-contents.md)
 
 Emitted after `navigator.usb.requestDevice` has been called and
 `select-usb-device` has fired if a device has been removed before the callback
@@ -550,7 +548,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
@@ -576,11 +574,11 @@ Clears the session’s HTTP cache.
 * `options` Object (optional)
   * `origin` string (optional) - Should follow `window.location.origin`’s representation
     `scheme://host:port`.
-  * `storages` string[] (optional) - The types of storages to clear, can contain:
+  * `storages` string[] (optional) - The types of storages to clear, can be
     `cookies`, `filesystem`, `indexdb`, `localstorage`,
     `shadercache`, `websql`, `serviceworkers`, `cachestorage`. If not
     specified, clear all storage types.
-  * `quotas` string[] (optional) - The types of quotas to clear, can contain:
+  * `quotas` string[] (optional) - The types of quotas to clear, can be
     `temporary`, `syncable`. If not specified, clear all quotas.
 
 Returns `Promise<void>` - resolves when the storage data has been cleared.
@@ -757,15 +755,17 @@ Sets download saving directory. By default, the download directory will be the
 Emulates network with the given configuration for the `session`.
 
 ```javascript
+const win = new BrowserWindow()
+
 // To emulate a GPRS connection with 50kbps throughput and 500 ms latency.
-window.webContents.session.enableNetworkEmulation({
+win.webContents.session.enableNetworkEmulation({
   latency: 500,
   downloadThroughput: 6400,
   uploadThroughput: 6400
 })
 
 // To emulate a network outage.
-window.webContents.session.enableNetworkEmulation({ offline: true })
+win.webContents.session.enableNetworkEmulation({ offline: true })
 ```
 
 #### `ses.preconnect(options)`
@@ -891,18 +891,19 @@ 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.
-    * `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.
+    * `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.
     * `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.
@@ -934,7 +935,22 @@ 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.  Valid values are `midiSysex`, `notifications`, `geolocation`, `media`,`mediaKeySystem`,`midi`, `pointerLock`, `fullscreen`, `openExternal`, `hid`, `serial`, or `usb`.
+  * `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).
   * `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.
@@ -1026,7 +1042,7 @@ Passing `null` instead of a function resets the handler to its default state.
   * `details` Object
     * `deviceType` string - The type of device that permission is being requested on, can be `hid`, `serial`, or `usb`.
     * `origin` string - The origin URL of the device permission check.
-    * `device` [HIDDevice](structures/hid-device.md) | [SerialPort](structures/serial-port.md)- the device that permission is being requested for.
+    * `device` [HIDDevice](structures/hid-device.md) | [SerialPort](structures/serial-port.md) | [USBDevice](structures/usb-device.md) - the device that permission is being requested for.
 
 Sets the handler which can be used to respond to device permission checks for the `session`.
 Returning `true` will allow the device to be permitted and `false` will reject it.
@@ -1038,7 +1054,7 @@ Additionally, the default behavior of Electron is to store granted device permis
 If longer term storage is needed, a developer can store granted device
 permissions (eg when handling the `select-hid-device` event) and then read from that storage with `setDevicePermissionHandler`.
 
-```javascript
+```javascript @ts-type={fetchGrantedDevices:()=>(Array<Electron.DevicePermissionHandlerHandlerDetails['device']>)}
 const { app, BrowserWindow } = require('electron')
 
 let win = null
@@ -1086,9 +1102,58 @@ app.whenReady().then(() => {
   win.webContents.session.on('select-hid-device', (event, details, callback) => {
     event.preventDefault()
     const selectedDevice = details.deviceList.find((device) => {
-      return device.vendorId === '9025' && device.productId === '67'
+      return device.vendorId === 9025 && device.productId === 67
+    })
+    callback(selectedDevice?.deviceId)
+  })
+})
+```
+
+#### `ses.setUSBProtectedClassesHandler(handler)`
+
+* `handler` Function\<string[]> | null
+  * `details` Object
+    * `protectedClasses` string[] - The current list of protected USB classes. Possible class values include:
+      * `audio`
+      * `audio-video`
+      * `hid`
+      * `mass-storage`
+      * `smart-card`
+      * `video`
+      * `wireless`
+
+Sets the handler which can be used to override which [USB classes are protected](https://wicg.github.io/webusb/#usbinterface-interface).
+The return value for the handler is a string array of USB classes which should be considered protected (eg not available in the renderer).  Valid values for the array are:
+
+* `audio`
+* `audio-video`
+* `hid`
+* `mass-storage`
+* `smart-card`
+* `video`
+* `wireless`
+
+Returning an empty string array from the handler will allow all USB classes; returning the passed in array will maintain the default list of protected USB classes (this is also the default behavior if a handler is not defined).
+To clear the handler, call `setUSBProtectedClassesHandler(null)`.
+
+```javascript
+const { app, BrowserWindow } = require('electron')
+
+let win = null
+
+app.whenReady().then(() => {
+  win = new BrowserWindow()
+
+  win.webContents.session.setUSBProtectedClassesHandler((details) => {
+    // Allow all classes:
+    // return []
+    // Keep the current set of protected classes:
+    // return details.protectedClasses
+    // Selectively remove classes:
+    return details.protectedClasses.filter((usbClass) => {
+      // Exclude classes except for audio classes
+      return usbClass.indexOf('audio') === -1
     })
-    callback(selectedPort?.deviceId)
   })
 })
 ```
@@ -1127,31 +1192,31 @@ macOS does not require a handler because macOS handles the pairing
 automatically.  To clear the handler, call `setBluetoothPairingHandler(null)`.
 
 ```javascript
-
-const { app, BrowserWindow, ipcMain, session } = require('electron')
-
-let bluetoothPinCallback = null
+const { app, BrowserWindow, session } = require('electron')
+const path = require('path')
 
 function createWindow () {
+  let bluetoothPinCallback = null
+
   const mainWindow = new BrowserWindow({
     webPreferences: {
       preload: path.join(__dirname, 'preload.js')
     }
   })
-}
 
-// Listen for an IPC message from the renderer to get the response for the Bluetooth pairing.
-ipcMain.on('bluetooth-pairing-response', (event, response) => {
-  bluetoothPinCallback(response)
-})
+  mainWindow.webContents.session.setBluetoothPairingHandler((details, callback) => {
+    bluetoothPinCallback = callback
+    // Send a IPC message to the renderer to prompt the user to confirm the pairing.
+    // Note that this will require logic in the renderer to handle this message and
+    // display a prompt to the user.
+    mainWindow.webContents.send('bluetooth-pairing-request', details)
+  })
 
-mainWindow.webContents.session.setBluetoothPairingHandler((details, callback) => {
-  bluetoothPinCallback = callback
-  // Send a IPC message to the renderer to prompt the user to confirm the pairing.
-  // Note that this will require logic in the renderer to handle this message and
-  // display a prompt to the user.
-  mainWindow.webContents.send('bluetooth-pairing-request', details)
-})
+  // Listen for an IPC message from the renderer to get the response for the Bluetooth pairing.
+  mainWindow.webContents.ipc.on('bluetooth-pairing-response', (event, response) => {
+    bluetoothPinCallback(response)
+  })
+}
 
 app.whenReady().then(() => {
   createWindow()
@@ -1235,16 +1300,18 @@ reused for new connections.
 
 Returns `Promise<Buffer>` - resolves with blob data.
 
-#### `ses.downloadURL(url)`
+#### `ses.downloadURL(url[, options])`
 
 * `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).
+unlike [`webContents.downloadURL`](web-contents.md#contentsdownloadurlurl-options).
 
 #### `ses.createInterruptedDownload(options)`
 
@@ -1392,7 +1459,7 @@ extension to be loaded.
 const { app, session } = require('electron')
 const path = require('path')
 
-app.on('ready', async () => {
+app.whenReady().then(async () => {
   await session.defaultSession.loadExtension(
     path.join(__dirname, 'react-devtools'),
     // allowFileAccess is required to load the devtools extension on file:// URLs.
@@ -1483,7 +1550,7 @@ app.whenReady().then(() => {
   const protocol = session.fromPartition('some-partition').protocol
   if (!protocol.registerFileProtocol('atom', (request, callback) => {
     const url = request.url.substr(7)
-    callback({ path: path.normalize(`${__dirname}/${url}`) })
+    callback({ path: path.normalize(path.join(__dirname, url)) })
   })) {
     console.error('Failed to register protocol')
   }

+ 164 - 0
docs/api/structures/browser-window-options.md

@@ -0,0 +1,164 @@
+# BrowserWindowConstructorOptions Object
+
+* `width` Integer (optional) - Window's width in pixels. Default is `800`.
+* `height` Integer (optional) - Window's height in pixels. Default is `600`.
+* `x` Integer (optional) - (**required** if y is used) Window's left offset from screen.
+  Default is to center the window.
+* `y` Integer (optional) - (**required** if x is used) Window's top offset from screen.
+  Default is to center the window.
+* `useContentSize` boolean (optional) - The `width` and `height` would be used as web
+  page's size, which means the actual window's size will include window
+  frame's size and be slightly larger. Default is `false`.
+* `center` boolean (optional) - Show window in the center of the screen. Default is `false`.
+* `minWidth` Integer (optional) - Window's minimum width. Default is `0`.
+* `minHeight` Integer (optional) - Window's minimum height. Default is `0`.
+* `maxWidth` Integer (optional) - Window's maximum width. Default is no limit.
+* `maxHeight` Integer (optional) - Window's maximum height. Default is no limit.
+* `resizable` boolean (optional) - Whether window is resizable. Default is `true`.
+* `movable` boolean (optional) _macOS_ _Windows_ - Whether window is
+  movable. This is not implemented on Linux. Default is `true`.
+* `minimizable` boolean (optional) _macOS_ _Windows_ - Whether window is
+  minimizable. This is not implemented on Linux. Default is `true`.
+* `maximizable` boolean (optional) _macOS_ _Windows_ - Whether window is
+  maximizable. This is not implemented on Linux. Default is `true`.
+* `closable` boolean (optional) _macOS_ _Windows_ - Whether window is
+  closable. This is not implemented on Linux. Default is `true`.
+* `focusable` boolean (optional) - Whether the window can be focused. Default is
+  `true`. On Windows setting `focusable: false` also implies setting
+  `skipTaskbar: true`. On Linux setting `focusable: false` makes the window
+  stop interacting with wm, so the window will always stay on top in all
+  workspaces.
+* `alwaysOnTop` boolean (optional) - Whether the window should always stay on top of
+  other windows. Default is `false`.
+* `fullscreen` boolean (optional) - Whether the window should show in fullscreen. When
+  explicitly set to `false` the fullscreen button will be hidden or disabled
+  on macOS. Default is `false`.
+* `fullscreenable` boolean (optional) - Whether the window can be put into fullscreen
+  mode. On macOS, also whether the maximize/zoom button should toggle full
+  screen mode or maximize window. Default is `true`.
+* `simpleFullscreen` boolean (optional) _macOS_ - Use pre-Lion fullscreen on
+  macOS. Default is `false`.
+* `skipTaskbar` boolean (optional) _macOS_ _Windows_ - Whether to show the window in taskbar.
+  Default is `false`.
+* `hiddenInMissionControl` boolean (optional) _macOS_ - Whether window should be hidden when the user toggles into mission control.
+* `kiosk` boolean (optional) - Whether the window is in kiosk mode. Default is `false`.
+* `title` string (optional) - Default window title. Default is `"Electron"`. If the HTML tag `<title>` is defined in the HTML file loaded by `loadURL()`, this property will be ignored.
+* `icon` ([NativeImage](../native-image.md) | string) (optional) - The window icon. On Windows it is
+  recommended to use `ICO` icons to get best visual effects, you can also
+  leave it undefined so the executable's icon will be used.
+* `show` boolean (optional) - Whether window should be shown when created. Default is
+  `true`.
+* `paintWhenInitiallyHidden` boolean (optional) - Whether the renderer should be active when `show` is `false` and it has just been created.  In order for `document.visibilityState` to work correctly on first load with `show: false` you should set this to `false`.  Setting this to `false` will cause the `ready-to-show` event to not fire.  Default is `true`.
+* `frame` boolean (optional) - Specify `false` to create a
+  [frameless window](../../tutorial/window-customization.md#create-frameless-windows). Default is `true`.
+* `parent` BrowserWindow (optional) - Specify parent window. Default is `null`.
+* `modal` boolean (optional) - Whether this is a modal window. This only works when the
+  window is a child window. Default is `false`.
+* `acceptFirstMouse` boolean (optional) _macOS_ - Whether clicking an
+  inactive window will also click through to the web contents. Default is
+  `false` on macOS. This option is not configurable on other platforms.
+* `disableAutoHideCursor` boolean (optional) - Whether to hide cursor when typing.
+  Default is `false`.
+* `autoHideMenuBar` boolean (optional) - Auto hide the menu bar unless the `Alt`
+  key is pressed. Default is `false`.
+* `enableLargerThanScreen` boolean (optional) _macOS_ - Enable the window to
+  be resized larger than screen. Only relevant for macOS, as other OSes
+  allow larger-than-screen windows by default. Default is `false`.
+* `backgroundColor` string (optional) - The window's background color in Hex, RGB, RGBA, HSL, HSLA or named CSS color format. Alpha in #AARRGGBB format is supported if `transparent` is set to `true`. Default is `#FFF` (white). See [win.setBackgroundColor](../browser-window.md#winsetbackgroundcolorbackgroundcolor) for more information.
+* `hasShadow` boolean (optional) - Whether window should have a shadow. Default is `true`.
+* `opacity` number (optional) _macOS_ _Windows_ - Set the initial opacity of
+  the window, between 0.0 (fully transparent) and 1.0 (fully opaque). This
+  is only implemented on Windows and macOS.
+* `darkTheme` boolean (optional) - Forces using dark theme for the window, only works on
+  some GTK+3 desktop environments. Default is `false`.
+* `transparent` boolean (optional) - Makes the window [transparent](../../tutorial/window-customization.md#create-transparent-windows).
+  Default is `false`. On Windows, does not work unless the window is frameless.
+* `type` string (optional) - The type of window, default is normal window. See more about
+  this below.
+* `visualEffectState` string (optional) _macOS_ - Specify how the material
+  appearance should reflect window activity state on macOS. Must be used
+  with the `vibrancy` property. Possible values are:
+  * `followWindow` - The backdrop should automatically appear active when the window is active, and inactive when it is not. This is the default.
+  * `active` - The backdrop should always appear active.
+  * `inactive` - The backdrop should always appear inactive.
+* `titleBarStyle` string (optional) _macOS_ _Windows_ - The style of window title bar.
+  Default is `default`. Possible values are:
+  * `default` - Results in the standard title bar for macOS or Windows respectively.
+  * `hidden` - Results in a hidden title bar and a full size content window. On macOS, the window still has the standard window controls (“traffic lights”) in the top left. On Windows, when combined with `titleBarOverlay: true` it will activate the Window Controls Overlay (see `titleBarOverlay` for more information), otherwise no window controls will be shown.
+  * `hiddenInset` _macOS_ - Only on macOS, results in a hidden title bar
+    with an alternative look where the traffic light buttons are slightly
+    more inset from the window edge.
+  * `customButtonsOnHover` _macOS_ - Only on macOS, results in a hidden
+    title bar and a full size content window, the traffic light buttons will
+    display when being hovered over in the top left of the window.
+    **Note:** This option is currently experimental.
+* `trafficLightPosition` [Point](point.md) (optional) _macOS_ -
+  Set a custom position for the traffic light buttons in frameless windows.
+* `roundedCorners` boolean (optional) _macOS_ - Whether frameless window
+  should have rounded corners on macOS. Default is `true`. Setting this property
+  to `false` will prevent the window from being fullscreenable.
+* `fullscreenWindowTitle` boolean (optional) _macOS_ _Deprecated_ - Shows
+  the title in the title bar in full screen mode on macOS for `hiddenInset`
+  titleBarStyle. Default is `false`.
+* `thickFrame` boolean (optional) - Use `WS_THICKFRAME` style for frameless windows on
+  Windows, which adds standard window frame. Setting it to `false` will remove
+  window shadow and window animations. Default is `true`.
+* `vibrancy` string (optional) _macOS_ - Add a type of vibrancy effect to
+  the window, only on macOS. Can be `appearance-based`, `titlebar`, `selection`,
+  `menu`, `popover`, `sidebar`, `header`, `sheet`, `window`, `hud`, `fullscreen-ui`,
+  `tooltip`, `content`, `under-window`, or `under-page`.
+* `backgroundMaterial` string (optional) _Windows_ - Set the window's
+  system-drawn background material, including behind the non-client area.
+  Can be `auto`, `none`, `mica`, `acrylic` or `tabbed`. See [win.setBackgroundMaterial](../browser-window.md#winsetbackgroundmaterialmaterial-windows) for more information.
+* `zoomToPageWidth` boolean (optional) _macOS_ - Controls the behavior on
+  macOS when option-clicking the green stoplight button on the toolbar or by
+  clicking the Window > Zoom menu item. If `true`, the window will grow to
+  the preferred width of the web page when zoomed, `false` will cause it to
+  zoom to the width of the screen. This will also affect the behavior when
+  calling `maximize()` directly. Default is `false`.
+* `tabbingIdentifier` string (optional) _macOS_ - Tab group name, allows
+  opening the window as a native tab. Windows with the same
+  tabbing identifier will be grouped together. This also adds a native new
+  tab button to your window's tab bar and allows your `app` and window to
+  receive the `new-window-for-tab` event.
+* `webPreferences` [WebPreferences](web-preferences.md?inline) (optional) - Settings of web page's features.
+* `titleBarOverlay` Object | Boolean (optional) -  When using a frameless window in conjunction with `win.setWindowButtonVisibility(true)` on macOS or using a `titleBarStyle` so that the standard window controls ("traffic lights" on macOS) are visible, this property enables the Window Controls Overlay [JavaScript APIs][overlay-javascript-apis] and [CSS Environment Variables][overlay-css-env-vars]. Specifying `true` will result in an overlay with default system colors. Default is `false`.
+  * `color` String (optional) _Windows_ - The CSS color of the Window Controls Overlay when enabled. Default is the system color.
+  * `symbolColor` String (optional) _Windows_ - The CSS color of the symbols on the Window Controls Overlay when enabled. Default is the system color.
+  * `height` Integer (optional) _macOS_ _Windows_ - The height of the title bar and Window Controls Overlay in pixels. Default is system height.
+
+When setting minimum or maximum window size with `minWidth`/`maxWidth`/
+`minHeight`/`maxHeight`, it only constrains the users. It won't prevent you from
+passing a size that does not follow size constraints to `setBounds`/`setSize` or
+to the constructor of `BrowserWindow`.
+
+The possible values and behaviors of the `type` option are platform dependent.
+Possible values are:
+
+* On Linux, possible types are `desktop`, `dock`, `toolbar`, `splash`,
+  `notification`.
+  * The `desktop` type places the window at the desktop background window level
+    (kCGDesktopWindowLevel - 1). However, note that a desktop window will not
+    receive focus, keyboard, or mouse events. You can still use globalShortcut to
+    receive input sparingly.
+  * The `dock` type creates a dock-like window behavior.
+  * The `toolbar` type creates a window with a toolbar appearance.
+  * The `splash` type behaves in a specific way. It is not
+    draggable, even if the CSS styling of the window's body contains
+    -webkit-app-region: drag. This type is commonly used for splash screens.
+  * The `notification` type creates a window that behaves like a system notification.
+* On macOS, possible types are `desktop`, `textured`, `panel`.
+  * The `textured` type adds metal gradient appearance
+    (`NSWindowStyleMaskTexturedBackground`).
+  * The `desktop` type places the window at the desktop background window level
+    (`kCGDesktopWindowLevel - 1`). Note that desktop window will not receive
+    focus, keyboard or mouse events, but you can use `globalShortcut` to receive
+    input sparingly.
+  * The `panel` type enables the window to float on top of full-screened apps
+    by adding the `NSWindowStyleMaskNonactivatingPanel` style mask,normally
+    reserved for NSPanel, at runtime. Also, the window will appear on all
+    spaces (desktops).
+* On Windows, possible type is `toolbar`.
+
+[overlay-css-env-vars]: https://github.com/WICG/window-controls-overlay/blob/main/explainer.md#css-environment-variables
+[overlay-javascript-apis]: https://github.com/WICG/window-controls-overlay/blob/main/explainer.md#javascript-apis

+ 0 - 2
docs/api/structures/ipc-renderer-event.md

@@ -1,8 +1,6 @@
 # IpcRendererEvent Object extends `Event`
 
 * `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`.
 * `ports` [MessagePort][][] - A list of MessagePorts that were transferred with this message
 
-[ipc-renderer-sendto]: ../ipc-renderer.md#ipcrenderersendtowebcontentsid-channel-args
 [MessagePort]: https://developer.mozilla.org/en-US/docs/Web/API/MessagePort

+ 0 - 2
docs/api/structures/product.md

@@ -3,8 +3,6 @@
 * `productIdentifier` string - The string that identifies the product to the Apple App Store.
 * `localizedDescription` string - A description of the product.
 * `localizedTitle` string - The name of the product.
-* `contentVersion` string - A string that identifies the version of the content.
-* `contentLengths` number[] - The total size of the content, in bytes.
 * `price` number - The cost of the product in the local currency.
 * `formattedPrice` string - The locale formatted price of the product.
 * `currencyCode` string - 3 character code presenting a product's currency based on the ISO 4217 standard.

+ 13 - 0
docs/api/structures/render-process-gone-details.md

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

+ 6 - 6
docs/api/structures/serial-port.md

@@ -2,9 +2,9 @@
 
 * `portId` string - Unique identifier for the port.
 * `portName` string - Name of the port.
-* `displayName` string - A string suitable for display to the user for describing this device.
-* `vendorId` string - Optional USB vendor ID.
-* `productId` string - Optional USB product ID.
-* `serialNumber` string - The USB device serial number.
-* `usbDriverName` string (optional) - Represents a single serial port on macOS can be enumerated by multiple drivers.
-* `deviceInstanceId` string (optional) - A stable identifier on Windows that can be used for device permissions.
+* `displayName` string (optional) - A string suitable for display to the user for describing this device.
+* `vendorId` string (optional) - The USB vendor ID.
+* `productId` string (optional) - The USB product ID.
+* `serialNumber` string (optional) - The USB device serial number.
+* `usbDriverName` string (optional) _macOS_ - Represents a single serial port on macOS can be enumerated by multiple drivers.
+* `deviceInstanceId` string (optional) _Windows_ - A stable identifier on Windows that can be used for device permissions.

+ 144 - 0
docs/api/structures/web-preferences.md

@@ -0,0 +1,144 @@
+# WebPreferences Object
+
+* `devTools` boolean (optional) - Whether to enable DevTools. If it is set to `false`, can not use `BrowserWindow.webContents.openDevTools()` to open DevTools. Default is `true`.
+* `nodeIntegration` boolean (optional) - Whether node integration is enabled.
+  Default is `false`.
+* `nodeIntegrationInWorker` boolean (optional) - Whether node integration is
+  enabled in web workers. Default is `false`. More about this can be found
+  in [Multithreading](../../tutorial/multithreading.md).
+* `nodeIntegrationInSubFrames` boolean (optional) - Experimental option for
+  enabling Node.js support in sub-frames such as iframes and child windows. All your preloads will load for
+  every iframe, you can use `process.isMainFrame` to determine if you are
+  in the main frame or not.
+* `preload` string (optional) - Specifies a script that will be loaded before other
+  scripts run in the page. This script will always have access to node APIs
+  no matter whether node integration is turned on or off. The value should
+  be the absolute file path to the script.
+  When node integration is turned off, the preload script can reintroduce
+  Node global symbols back to the global scope. See example
+  [here](../context-bridge.md#exposing-node-global-symbols).
+* `sandbox` boolean (optional) - If set, this will sandbox the renderer
+  associated with the window, making it compatible with the Chromium
+  OS-level sandbox and disabling the Node.js engine. This is not the same as
+  the `nodeIntegration` option and the APIs available to the preload script
+  are more limited. Read more about the option [here](../../tutorial/sandbox.md).
+* `session` [Session](../session.md#class-session) (optional) - Sets the session used by the
+  page. Instead of passing the Session object directly, you can also choose to
+  use the `partition` option instead, which accepts a partition string. When
+  both `session` and `partition` are provided, `session` will be preferred.
+  Default is the default session.
+* `partition` string (optional) - Sets the session used by the page according to the
+  session's partition string. If `partition` starts with `persist:`, the page
+  will use a persistent session available to all pages in the app with the
+  same `partition`. If there is no `persist:` prefix, the page will use an
+  in-memory session. By assigning the same `partition`, multiple pages can share
+  the same session. Default is the default session.
+* `zoomFactor` number (optional) - The default zoom factor of the page, `3.0` represents
+  `300%`. Default is `1.0`.
+* `javascript` boolean (optional) - Enables JavaScript support. Default is `true`.
+* `webSecurity` boolean (optional) - When `false`, it will disable the
+  same-origin policy (usually using testing websites by people), and set
+  `allowRunningInsecureContent` to `true` if this options has not been set
+  by user. Default is `true`.
+* `allowRunningInsecureContent` boolean (optional) - Allow an https page to run
+  JavaScript, CSS or plugins from http URLs. Default is `false`.
+* `images` boolean (optional) - Enables image support. Default is `true`.
+* `imageAnimationPolicy` string (optional) - Specifies how to run image animations (E.g. GIFs).  Can be `animate`, `animateOnce` or `noAnimation`.  Default is `animate`.
+* `textAreasAreResizable` boolean (optional) - Make TextArea elements resizable. Default
+  is `true`.
+* `webgl` boolean (optional) - Enables WebGL support. Default is `true`.
+* `plugins` boolean (optional) - Whether plugins should be enabled. Default is `false`.
+* `experimentalFeatures` boolean (optional) - Enables Chromium's experimental features.
+  Default is `false`.
+* `scrollBounce` boolean (optional) _macOS_ - Enables scroll bounce
+  (rubber banding) effect on macOS. Default is `false`.
+* `enableBlinkFeatures` string (optional) - A list of feature strings separated by `,`, like
+  `CSSVariables,KeyboardEventKey` to enable. The full list of supported feature
+  strings can be found in the [RuntimeEnabledFeatures.json5][runtime-enabled-features]
+  file.
+* `disableBlinkFeatures` string (optional) - A list of feature strings separated by `,`,
+  like `CSSVariables,KeyboardEventKey` to disable. The full list of supported
+  feature strings can be found in the
+  [RuntimeEnabledFeatures.json5][runtime-enabled-features] file.
+* `defaultFontFamily` Object (optional) - Sets the default font for the font-family.
+  * `standard` string (optional) - Defaults to `Times New Roman`.
+  * `serif` string (optional) - Defaults to `Times New Roman`.
+  * `sansSerif` string (optional) - Defaults to `Arial`.
+  * `monospace` string (optional) - Defaults to `Courier New`.
+  * `cursive` string (optional) - Defaults to `Script`.
+  * `fantasy` string (optional) - Defaults to `Impact`.
+  * `math` string (optional) - Defaults to `Latin Modern Math`.
+* `defaultFontSize` Integer (optional) - Defaults to `16`.
+* `defaultMonospaceFontSize` Integer (optional) - Defaults to `13`.
+* `minimumFontSize` Integer (optional) - Defaults to `0`.
+* `defaultEncoding` string (optional) - Defaults to `ISO-8859-1`.
+* `backgroundThrottling` boolean (optional) - Whether to throttle animations and timers
+  when the page becomes background. This also affects the
+  [Page Visibility API](../browser-window.md#page-visibility). Defaults to `true`.
+* `offscreen` boolean (optional) - Whether to enable offscreen rendering for the browser
+  window. Defaults to `false`. See the
+  [offscreen rendering tutorial](../../tutorial/offscreen-rendering.md) for
+  more details.
+* `contextIsolation` boolean (optional) - Whether to run Electron APIs and
+  the specified `preload` script in a separate JavaScript context. Defaults
+  to `true`. The context that the `preload` script runs in will only have
+  access to its own dedicated `document` and `window` globals, as well as
+  its own set of JavaScript builtins (`Array`, `Object`, `JSON`, etc.),
+  which are all invisible to the loaded content. The Electron API will only
+  be available in the `preload` script and not the loaded page. This option
+  should be used when loading potentially untrusted remote content to ensure
+  the loaded content cannot tamper with the `preload` script and any
+  Electron APIs being used.  This option uses the same technique used by
+  [Chrome Content Scripts][chrome-content-scripts].  You can access this
+  context in the dev tools by selecting the 'Electron Isolated Context'
+  entry in the combo box at the top of the Console tab.
+* `webviewTag` boolean (optional) - Whether to enable the [`<webview>` tag](../webview-tag.md).
+  Defaults to `false`. **Note:** The
+  `preload` script configured for the `<webview>` will have node integration
+  enabled when it is executed so you should ensure remote/untrusted content
+  is not able to create a `<webview>` tag with a possibly malicious `preload`
+  script. You can use the `will-attach-webview` event on [webContents](../web-contents.md)
+  to strip away the `preload` script and to validate or alter the
+  `<webview>`'s initial settings.
+* `additionalArguments` string[] (optional) - A list of strings that will be appended
+  to `process.argv` in the renderer process of this app.  Useful for passing small
+  bits of data down to renderer process preload scripts.
+* `safeDialogs` boolean (optional) - Whether to enable browser style
+  consecutive dialog protection. Default is `false`.
+* `safeDialogsMessage` string (optional) - The message to display when
+  consecutive dialog protection is triggered. If not defined the default
+  message would be used, note that currently the default message is in
+  English and not localized.
+* `disableDialogs` boolean (optional) - Whether to disable dialogs
+  completely. Overrides `safeDialogs`. Default is `false`.
+* `navigateOnDragDrop` boolean (optional) - Whether dragging and dropping a
+  file or link onto the page causes a navigation. Default is `false`.
+* `autoplayPolicy` string (optional) - Autoplay policy to apply to
+  content in the window, can be `no-user-gesture-required`,
+  `user-gesture-required`, `document-user-activation-required`. Defaults to
+  `no-user-gesture-required`.
+* `disableHtmlFullscreenWindowResize` boolean (optional) - Whether to
+  prevent the window from resizing when entering HTML Fullscreen. Default
+  is `false`.
+* `accessibleTitle` string (optional) - An alternative title string provided only
+  to accessibility tools such as screen readers. This string is not directly
+  visible to users.
+* `spellcheck` boolean (optional) - Whether to enable the builtin spellchecker.
+  Default is `true`.
+* `enableWebSQL` boolean (optional) - Whether to enable the [WebSQL api](https://www.w3.org/TR/webdatabase/).
+  Default is `true`.
+* `v8CacheOptions` string (optional) - Enforces the v8 code caching policy
+  used by blink. Accepted values are
+  * `none` - Disables code caching
+  * `code` - Heuristic based code caching
+  * `bypassHeatCheck` - Bypass code caching heuristics but with lazy compilation
+  * `bypassHeatCheckAndEagerCompile` - Same as above except compilation is eager.
+  Default policy is `code`.
+* `enablePreferredSizeMode` boolean (optional) - Whether to enable
+  preferred size mode. The preferred size is the minimum size needed to
+  contain the layout of the document—without requiring scrolling. Enabling
+  this will cause the `preferred-size-changed` event to be emitted on the
+  `WebContents` when the preferred size changes. Default is `false`.
+
+[chrome-content-scripts]: https://developer.chrome.com/extensions/content_scripts#execution-environment
+[runtime-enabled-features]: https://source.chromium.org/chromium/chromium/src/+/main:third_party/blink/renderer/platform/runtime_enabled_features.json5

+ 5 - 41
docs/api/system-preferences.md

@@ -6,7 +6,7 @@ Process: [Main](../glossary.md#main-process)
 
 ```javascript
 const { systemPreferences } = require('electron')
-console.log(systemPreferences.isDarkMode())
+console.log(systemPreferences.isAeroGlassEnabled())
 ```
 
 ## Events
@@ -27,32 +27,8 @@ Returns:
 
 * `event` Event
 
-### Event: 'inverted-color-scheme-changed' _Windows_ _Deprecated_
-
-Returns:
-
-* `event` Event
-* `invertedColorScheme` boolean - `true` if an inverted color scheme (a high contrast color scheme with light text and dark backgrounds) is being used, `false` otherwise.
-
-**Deprecated:** Should use the new [`updated`](native-theme.md#event-updated) event on the `nativeTheme` module.
-
-### Event: 'high-contrast-color-scheme-changed' _Windows_ _Deprecated_
-
-Returns:
-
-* `event` Event
-* `highContrastColorScheme` boolean - `true` if a high contrast theme is being used, `false` otherwise.
-
-**Deprecated:** Should use the new [`updated`](native-theme.md#event-updated) event on the `nativeTheme` module.
-
 ## 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.
@@ -228,10 +204,10 @@ const win = new BrowserWindow(browserOptions)
 
 // Navigate.
 if (browserOptions.transparent) {
-  win.loadURL(`file://${__dirname}/index.html`)
+  win.loadFile('index.html')
 } else {
   // No transparency, so we load a fallback that uses basic styles.
-  win.loadURL(`file://${__dirname}/fallback.html`)
+  win.loadFile('fallback.html')
 }
 ```
 
@@ -297,7 +273,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 isn’t disabled.
@@ -356,18 +332,6 @@ 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`.
@@ -453,7 +417,7 @@ Returns an object with system animation settings.
 
 ## Properties
 
-### `systemPreferences.appLevelAppearance` _macOS_
+### `systemPreferences.appLevelAppearance` _macOS_ _Deprecated_
 
 A `string` property that can be `dark`, `light` or `unknown`. It determines the macOS appearance setting for
 your application. This maps to values in: [NSApplication.appearance](https://developer.apple.com/documentation/appkit/nsapplication/2967170-appearance?language=objc). Setting this will override the

+ 4 - 4
docs/api/touch-bar.md

@@ -87,12 +87,12 @@ const { TouchBarLabel, TouchBarButton, TouchBarSpacer } = TouchBar
 let spinning = false
 
 // Reel labels
-const reel1 = new TouchBarLabel()
-const reel2 = new TouchBarLabel()
-const reel3 = new TouchBarLabel()
+const reel1 = new TouchBarLabel({ label: '' })
+const reel2 = new TouchBarLabel({ label: '' })
+const reel3 = new TouchBarLabel({ label: '' })
 
 // Spin result label
-const result = new TouchBarLabel()
+const result = new TouchBarLabel({ label: '' })
 
 // Spin button
 const spin = new TouchBarButton({

+ 137 - 55
docs/api/web-contents.md

@@ -13,7 +13,7 @@ the [`BrowserWindow`](browser-window.md) object. An example of accessing the
 const { BrowserWindow } = require('electron')
 
 const win = new BrowserWindow({ width: 800, height: 1500 })
-win.loadURL('http://github.com')
+win.loadURL('https://github.com')
 
 const contents = win.webContents
 console.log(contents)
@@ -65,28 +65,28 @@ for all windows, webviews, opened devtools, and devtools extension background pa
 
 ### `webContents.getFocusedWebContents()`
 
-Returns `WebContents` | null - The web contents that is focused in this application, otherwise
+Returns `WebContents | null` - The web contents that is focused in this application, otherwise
 returns `null`.
 
 ### `webContents.fromId(id)`
 
 * `id` Integer
 
-Returns `WebContents` | undefined - A WebContents instance with the given ID, or
+Returns `WebContents | undefined` - A WebContents instance with the given ID, or
 `undefined` if there is no WebContents associated with the given ID.
 
 ### `webContents.fromFrame(frame)`
 
 * `frame` WebFrameMain
 
-Returns `WebContents` | undefined - A WebContents instance with the given WebFrameMain, or
+Returns `WebContents | undefined` - A WebContents instance with the given WebFrameMain, or
 `undefined` if there is no WebContents associated with the given WebFrameMain.
 
 ### `webContents.fromDevToolsTargetId(targetId)`
 
 * `targetId` string - The Chrome DevTools Protocol [TargetID](https://chromedevtools.github.io/devtools-protocol/tot/Target/#type-TargetID) associated with the WebContents instance.
 
-Returns `WebContents` | undefined - A WebContents instance with the given TargetID, or
+Returns `WebContents | undefined` - A WebContents instance with the given TargetID, or
 `undefined` if there is no WebContents associated with the given TargetID.
 
 When communicating with the [Chrome DevTools Protocol](https://chromedevtools.github.io/devtools-protocol/),
@@ -98,7 +98,7 @@ async function lookupTargetId (browserWindow) {
   await wc.debugger.attach('1.3')
   const { targetInfo } = await wc.debugger.sendCommand('Target.getTargetInfo')
   const { targetId } = targetInfo
-  const targetWebContents = await webContents.fromDevToolsTargetId(targetId)
+  const targetWebContents = await wc.fromDevToolsTargetId(targetId)
 }
 ```
 
@@ -210,7 +210,7 @@ Returns:
   * `url` string - URL for the created window.
   * `frameName` string - Name given to the created window in the
      `window.open()` call.
-  * `options` BrowserWindowConstructorOptions - The options used to create the
+  * `options` [BrowserWindowConstructorOptions](structures/browser-window-options.md) - The options used to create the
     BrowserWindow. They are merged in increasing precedence: parsed options
     from the `features` string from `window.open()`, security-related
     webPreferences inherited from the parent, and options given by
@@ -239,9 +239,8 @@ 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.
+  * `isSameDocument` boolean - This event does not fire for same document navigations using window.history api and reference fragment navigations.
+    This property is always set to `false` for this event.
   * `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
@@ -273,6 +272,8 @@ Returns:
 
 * `details` Event<>
   * `url` string - The URL the frame is navigating to.
+  * `isSameDocument` boolean - This event does not fire for same document navigations using window.history api and reference fragment navigations.
+    This property is always set to `false` for this event.
   * `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
@@ -478,18 +479,7 @@ checking `reason === 'killed'` when you switch to that event.
 Returns:
 
 * `event` Event
-* `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.
+* `details` [RenderProcessGoneDetails](structures/render-process-gone-details.md)
 
 Emitted when the renderer process unexpectedly disappears.  This is normally
 because it was crashed or killed.
@@ -601,6 +591,7 @@ window.
 
 Returns:
 
+* `event` Event
 * `url` string - URL of the link that was clicked or selected.
 
 Emitted when a link is clicked in DevTools or 'Open in new tab' is selected for a link in its context menu.
@@ -736,14 +727,16 @@ Returns:
 * `size` [Size](structures/size.md) (optional) - the size of the `image`.
 * `hotspot` [Point](structures/point.md) (optional) - coordinates of the custom cursor's hotspot.
 
-Emitted when the cursor's type changes. The `type` parameter can be `default`,
-`crosshair`, `pointer`, `text`, `wait`, `help`, `e-resize`, `n-resize`,
-`ne-resize`, `nw-resize`, `s-resize`, `se-resize`, `sw-resize`, `w-resize`,
-`ns-resize`, `ew-resize`, `nesw-resize`, `nwse-resize`, `col-resize`,
-`row-resize`, `m-panning`, `e-panning`, `n-panning`, `ne-panning`, `nw-panning`,
-`s-panning`, `se-panning`, `sw-panning`, `w-panning`, `move`, `vertical-text`,
-`cell`, `context-menu`, `alias`, `progress`, `nodrop`, `copy`, `none`,
-`not-allowed`, `zoom-in`, `zoom-out`, `grab`, `grabbing` or `custom`.
+Emitted when the cursor's type changes. The `type` parameter can be `pointer`,
+`crosshair`, `hand`, `text`, `wait`, `help`, `e-resize`, `n-resize`, `ne-resize`,
+`nw-resize`, `s-resize`, `se-resize`, `sw-resize`, `w-resize`, `ns-resize`, `ew-resize`,
+`nesw-resize`, `nwse-resize`, `col-resize`, `row-resize`, `m-panning`, `m-panning-vertical`,
+`m-panning-horizontal`, `e-panning`, `n-panning`, `ne-panning`, `nw-panning`, `s-panning`,
+`se-panning`, `sw-panning`, `w-panning`, `move`, `vertical-text`, `cell`, `context-menu`,
+`alias`, `progress`, `nodrop`, `copy`, `none`, `not-allowed`, `zoom-in`, `zoom-out`, `grab`,
+`grabbing`, `custom`, `null`, `drag-drop-none`, `drag-drop-move`, `drag-drop-copy`,
+`drag-drop-link`, `ns-no-resize`, `ew-no-resize`, `nesw-no-resize`, `nwse-no-resize`,
+or `default`.
 
 If the `type` parameter is `custom`, the `image` parameter will hold the custom
 cursor image in a [`NativeImage`](native-image.md), and `scale`, `size` and `hotspot` will hold
@@ -791,7 +784,7 @@ Returns:
   * `frameCharset` string - The character encoding of the frame on which the
     menu was invoked.
   * `inputFieldType` string - If the context menu was invoked on an input
-    field, the type of that field. Possible values are `none`, `plainText`,
+    field, the type of that field. Possible values include `none`, `plainText`,
     `password`, `other`.
   * `spellcheckEnabled` boolean - If the context is editable, whether or not spellchecking is enabled.
   * `menuSourceType` string - Input source that invoked the context menu.
@@ -863,7 +856,7 @@ app.whenReady().then(() => {
     })
     if (!result) {
       // The device wasn't found so we need to either wait longer (eg until the
-      // device is turned on) or cancel the request by calling the callback 
+      // device is turned on) or cancel the request by calling the callback
       // with an empty string.
       callback('')
     } else {
@@ -891,7 +884,7 @@ const win = new BrowserWindow({ webPreferences: { offscreen: true } })
 win.webContents.on('paint', (event, dirty, image) => {
   // updateBitmap(dirty, image.getBitmap())
 })
-win.loadURL('http://github.com')
+win.loadURL('https://github.com')
 ```
 
 #### Event: 'devtools-reload-page'
@@ -903,7 +896,7 @@ Emitted when the devtools window instructs the webContents to reload
 Returns:
 
 * `event` Event
-* `webPreferences` WebPreferences - The web preferences that will be used by the guest
+* `webPreferences` [WebPreferences](structures/web-preferences.md) - The web preferences that will be used by the guest
   page. This object can be modified to adjust the preferences for the guest
   page.
 * `params` Record<string, string> - The other `<webview>` parameters such as the `src` URL.
@@ -1017,9 +1010,9 @@ e.g. the `http://` or `file://`. If the load should bypass http cache then
 use the `pragma` header to achieve it.
 
 ```javascript
-const { webContents } = require('electron')
+const win = new BrowserWindow()
 const options = { extraHeaders: 'pragma: no-cache\n' }
-webContents.loadURL('https://github.com', options)
+win.webContents.loadURL('https://github.com', options)
 ```
 
 #### `contents.loadFile(filePath[, options])`
@@ -1049,12 +1042,15 @@ an app structure like this:
 Would require code like this
 
 ```js
+const win = new BrowserWindow()
 win.loadFile('src/index.html')
 ```
 
-#### `contents.downloadURL(url)`
+#### `contents.downloadURL(url[, options])`
 
 * `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.
@@ -1066,7 +1062,7 @@ Returns `string` - The URL of the current web page.
 ```javascript
 const { BrowserWindow } = require('electron')
 const win = new BrowserWindow({ width: 800, height: 600 })
-win.loadURL('http://github.com').then(() => {
+win.loadURL('https://github.com').then(() => {
   const currentURL = win.webContents.getURL()
   console.log(currentURL)
 })
@@ -1185,7 +1181,9 @@ when this process is unstable or unusable, for instance in order to recover
 from the `unresponsive` event.
 
 ```js
-contents.on('unresponsive', async () => {
+const win = new BrowserWindow()
+
+win.webContents.on('unresponsive', async () => {
   const { response } = await dialog.showMessageBox({
     message: 'App X has become unresponsive',
     title: 'Do you want to try forcefully reloading the app?',
@@ -1193,8 +1191,8 @@ contents.on('unresponsive', async () => {
     cancelId: 1
   })
   if (response === 0) {
-    contents.forcefullyCrashRenderer()
-    contents.reload()
+    win.webContents.forcefullyCrashRenderer()
+    win.webContents.reload()
   }
 })
 ```
@@ -1221,8 +1219,9 @@ Injects CSS into the current web page and returns a unique key for the inserted
 stylesheet.
 
 ```js
-contents.on('did-finish-load', () => {
-  contents.insertCSS('html, body { background-color: #f00; }')
+const win = new BrowserWindow()
+win.webContents.on('did-finish-load', () => {
+  win.webContents.insertCSS('html, body { background-color: #f00; }')
 })
 ```
 
@@ -1236,9 +1235,11 @@ Removes the inserted CSS from the current web page. The stylesheet is identified
 by its key, which is returned from `contents.insertCSS(css)`.
 
 ```js
-contents.on('did-finish-load', async () => {
-  const key = await contents.insertCSS('html, body { background-color: #f00; }')
-  contents.removeInsertedCSS(key)
+const win = new BrowserWindow()
+
+win.webContents.on('did-finish-load', async () => {
+  const key = await win.webContents.insertCSS('html, body { background-color: #f00; }')
+  win.webContents.removeInsertedCSS(key)
 })
 ```
 
@@ -1259,7 +1260,9 @@ this limitation.
 Code execution will be suspended until web page stop loading.
 
 ```js
-contents.executeJavaScript('fetch("https://jsonplaceholder.typicode.com/users/1").then(resp => resp.json())', true)
+const win = new BrowserWindow()
+
+win.webContents.executeJavaScript('fetch("https://jsonplaceholder.typicode.com/users/1").then(resp => resp.json())', true)
   .then((result) => {
     console.log(result) // Will be the JSON object from the fetch call
   })
@@ -1370,7 +1373,8 @@ Sets the maximum and minimum pinch-to-zoom level.
 > **NOTE**: Visual zoom is disabled by default in Electron. To re-enable it, call:
 >
 > ```js
-> contents.setVisualZoomLevelLimits(1, 3)
+> const win = new BrowserWindow()
+> win.webContents.setVisualZoomLevelLimits(1, 3)
 > ```
 
 #### `contents.undo()`
@@ -1389,6 +1393,10 @@ 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
@@ -1416,6 +1424,46 @@ 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
@@ -1461,12 +1509,12 @@ can be obtained by subscribing to [`found-in-page`](web-contents.md#event-found-
 Stops any `findInPage` request for the `webContents` with the provided `action`.
 
 ```javascript
-const { webContents } = require('electron')
-webContents.on('found-in-page', (event, result) => {
-  if (result.finalUpdate) webContents.stopFindInPage('clearSelection')
+const win = new BrowserWindow()
+win.webContents.on('found-in-page', (event, result) => {
+  if (result.finalUpdate) win.webContents.stopFindInPage('clearSelection')
 })
 
-const requestId = webContents.findInPage('api')
+const requestId = win.webContents.findInPage('api')
 console.log(requestId)
 ```
 
@@ -1546,6 +1594,7 @@ Use `page-break-before: always;` CSS style to force to print to a new page.
 Example usage:
 
 ```js
+const win = new BrowserWindow()
 const options = {
   silent: true,
   deviceName: 'My-Printer',
@@ -1573,10 +1622,11 @@ win.webContents.print(options, (success, errorType) => {
     * `bottom` number (optional) - Bottom margin in inches. Defaults to 1cm (~0.4 inches).
     * `left` number (optional) - Left margin in inches. Defaults to 1cm (~0.4 inches).
     * `right` number (optional) - Right margin in inches. Defaults to 1cm (~0.4 inches).
-  * `pageRanges` string (optional) - Paper ranges to print, e.g., '1-5, 8, 11-13'. Defaults to the empty string, which means print all pages.
+  * `pageRanges` string (optional) - Page ranges to print, e.g., '1-5, 8, 11-13'. Defaults to the empty string, which means print all pages.
   * `headerTemplate` string (optional) - HTML template for the print header. Should be valid HTML markup with following classes used to inject printing values into them: `date` (formatted print date), `title` (document title), `url` (document location), `pageNumber` (current page number) and `totalPages` (total pages in the document). For example, `<span class=title></span>` would generate span containing the title.
   * `footerTemplate` string (optional) - HTML template for the print footer. Should use the same format as the `headerTemplate`.
   * `preferCSSPageSize` boolean (optional) - Whether or not to prefer page size as defined by css. Defaults to false, in which case the content will be scaled to fit the paper size.
+  * `generateTaggedPDF` boolean (optional) _Experimental_ - Whether or not to generate a tagged (accessible) PDF. Defaults to false. As this property is experimental, the generated PDF may not adhere fully to PDF/UA and WCAG standards.
 
 Returns `Promise<Buffer>` - Resolves with the generated PDF data.
 
@@ -1593,7 +1643,7 @@ const path = require('path')
 const os = require('os')
 
 const win = new BrowserWindow()
-win.loadURL('http://github.com')
+win.loadURL('https://github.com')
 
 win.webContents.on('did-finish-load', () => {
   // Use default printing options
@@ -1719,6 +1769,7 @@ app.whenReady().then(() => {
     In `undocked` mode it's possible to dock back. In `detach` mode it's not.
   * `activate` boolean (optional) - Whether to bring the opened devtools window
     to the foreground. The default is `true`.
+  * `title` string (optional) - A title for the DevTools window (only in `undocked` or `detach` mode).
 
 Opens the devtools.
 
@@ -1739,6 +1790,18 @@ Returns `boolean` - Whether the devtools is opened.
 
 Returns `boolean` - Whether the devtools view is focused .
 
+#### `contents.getDevToolsTitle()`
+
+Returns `string` - the current title of the DevTools window. This will only be visible
+if DevTools is opened in `undocked` or `detach` mode.
+
+#### `contents.setDevToolsTitle(title)`
+
+* `title` string
+
+Changes the title of the DevTools window to `title`. This will only be visible if DevTools is
+opened in `undocked` or `detach` mode.
+
 #### `contents.toggleDevTools()`
 
 Toggles the developer tools.
@@ -1842,8 +1905,9 @@ For example:
 
 ```js
 // Main process
+const win = new BrowserWindow()
 const { port1, port2 } = new MessageChannelMain()
-webContents.postMessage('port', { message: 'hello' }, [port1])
+win.webContents.postMessage('port', { message: 'hello' }, [port1])
 
 // Renderer process
 ipcRenderer.on('port', (e, msg) => {
@@ -2005,6 +2069,24 @@ Setting the WebRTC IP handling policy allows you to control which IPs are
 exposed via WebRTC. See [BrowserLeaks](https://browserleaks.com/webrtc) for
 more details.
 
+#### `contents.getWebRTCUDPPortRange()`
+
+Returns `Object`:
+
+* `min` Integer - The minimum UDP port number that WebRTC should use.
+* `max` Integer - The maximum UDP port number that WebRTC should use.
+
+By default this value is `{ min: 0, max: 0 }` , which would apply no restriction on the udp port range.
+
+#### `contents.setWebRTCUDPPortRange(udpPortRange)`
+
+* `udpPortRange` Object
+  * `min` Integer - The minimum UDP port number that WebRTC should use.
+  * `max` Integer - The maximum UDP port number that WebRTC should use.
+
+Setting the WebRTC UDP Port Range allows you to restrict the udp port range used by WebRTC. By default the port range is unrestricted.
+**Note:** To reset to an unrestricted port range this value should be set to `{ min: 0, max: 0 }`.
+
 #### `contents.getMediaSourceId(requestWebContents)`
 
 * `requestWebContents` WebContents - Web contents that the id will be registered to.

+ 2 - 1
docs/api/web-frame-main.md

@@ -128,8 +128,9 @@ For example:
 
 ```js
 // Main process
+const win = new BrowserWindow()
 const { port1, port2 } = new MessageChannelMain()
-webContents.mainFrame.postMessage('port', { message: 'hello' }, [port1])
+win.webContents.mainFrame.postMessage('port', { message: 'hello' }, [port1])
 
 // Renderer process
 ipcRenderer.on('port', (e, msg) => {

+ 1 - 2
docs/api/web-frame.md

@@ -96,13 +96,12 @@ with an array of misspelt words when complete.
 
 An example of using [node-spellchecker][spellchecker] as provider:
 
-```javascript
+```javascript @ts-expect-error=[2,6]
 const { webFrame } = require('electron')
 const spellChecker = require('spellchecker')
 webFrame.setSpellCheckProvider('en-US', {
   spellCheck (words, callback) {
     setTimeout(() => {
-      const spellchecker = require('spellchecker')
       const misspelled = words.filter(x => spellchecker.isMisspelled(x))
       callback(misspelled)
     }, 0)

+ 54 - 13
docs/api/webview-tag.md

@@ -113,7 +113,7 @@ The `src` attribute can also accept data URLs, such as
 ### `nodeintegration`
 
 ```html
-<webview src="http://www.google.com/" nodeintegration></webview>
+<webview src="https://www.google.com/" nodeintegration></webview>
 ```
 
 A `boolean`. When this attribute is present the guest page in `webview` will have node
@@ -124,7 +124,7 @@ page.
 ### `nodeintegrationinsubframes`
 
 ```html
-<webview src="http://www.google.com/" nodeintegrationinsubframes></webview>
+<webview src="https://www.google.com/" nodeintegrationinsubframes></webview>
 ```
 
 A `boolean` for the experimental option for enabling NodeJS support in sub-frames such as iframes
@@ -162,7 +162,7 @@ after this script has finished executing.
 ### `httpreferrer`
 
 ```html
-<webview src="https://www.github.com/" httpreferrer="http://cheng.guru"></webview>
+<webview src="https://www.github.com/" httpreferrer="https://example.com/"></webview>
 ```
 
 A `string` that sets the referrer URL for the guest page.
@@ -185,6 +185,8 @@ page is loaded, use the `setUserAgent` method to change the user agent.
 A `boolean`. When this attribute is present the guest page will have web security disabled.
 Web security is enabled by default.
 
+This value can only be modified before the first navigation.
+
 ### `partition`
 
 ```html
@@ -254,7 +256,7 @@ The `webview` tag has the following methods:
 
 **Example**
 
-```javascript
+```javascript @ts-expect-error=[3]
 const webview = document.querySelector('webview')
 webview.addEventListener('dom-ready', () => {
   webview.openDevTools()
@@ -279,9 +281,11 @@ 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)`
+### `<webview>.downloadURL(url[, options])`
 
 * `url` string
+* `options` Object (optional)
+  * `headers` Record<string, string> (optional) - HTTP request headers.
 
 Initiates a download of the resource at `url` without navigating.
 
@@ -464,6 +468,10 @@ 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.
@@ -484,6 +492,25 @@ 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
@@ -577,10 +604,11 @@ Prints `webview`'s web page. Same as `webContents.print([options])`.
     * `bottom` number (optional) - Bottom margin in inches. Defaults to 1cm (~0.4 inches).
     * `left` number (optional) - Left margin in inches. Defaults to 1cm (~0.4 inches).
     * `right` number (optional) - Right margin in inches. Defaults to 1cm (~0.4 inches).
-  * `pageRanges` string (optional) - Paper ranges to print, e.g., '1-5, 8, 11-13'. Defaults to the empty string, which means print all pages.
+  * `pageRanges` string (optional) - Page ranges to print, e.g., '1-5, 8, 11-13'. Defaults to the empty string, which means print all pages.
   * `headerTemplate` string (optional) - HTML template for the print header. Should be valid HTML markup with following classes used to inject printing values into them: `date` (formatted print date), `title` (document title), `url` (document location), `pageNumber` (current page number) and `totalPages` (total pages in the document). For example, `<span class=title></span>` would generate span containing the title.
   * `footerTemplate` string (optional) - HTML template for the print footer. Should use the same format as the `headerTemplate`.
   * `preferCSSPageSize` boolean (optional) - Whether or not to prefer page size as defined by css. Defaults to false, in which case the content will be scaled to fit the paper size.
+  * `generateTaggedPDF` boolean (optional) _Experimental_ - Whether or not to generate a tagged (accessible) PDF. Defaults to false. As this property is experimental, the generated PDF may not adhere fully to PDF/UA and WCAG standards.
 
 Returns `Promise<Uint8Array>` - Resolves with the generated PDF data.
 
@@ -775,7 +803,7 @@ Fired when the guest window logs a console message.
 The following example code forwards all log messages to the embedder's console
 without regard for log level or other properties.
 
-```javascript
+```javascript @ts-expect-error=[3]
 const webview = document.querySelector('webview')
 webview.addEventListener('console-message', (e) => {
   console.log('Guest page logged a message:', e.message)
@@ -796,7 +824,7 @@ Returns:
 Fired when a result is available for
 [`webview.findInPage`](#webviewfindinpagetext-options) request.
 
-```javascript
+```javascript @ts-expect-error=[3,6]
 const webview = document.querySelector('webview')
 webview.addEventListener('found-in-page', (e) => {
   webview.stopFindInPage('keepSelection')
@@ -921,7 +949,7 @@ Fired when the guest page attempts to close itself.
 The following example code navigates the `webview` to `about:blank` when the
 guest attempts to close itself.
 
-```javascript
+```javascript @ts-expect-error=[3]
 const webview = document.querySelector('webview')
 webview.addEventListener('close', () => {
   webview.src = 'about:blank'
@@ -941,7 +969,7 @@ Fired when the guest page has sent an asynchronous message to embedder page.
 With `sendToHost` method and `ipc-message` event you can communicate
 between guest page and embedder page:
 
-```javascript
+```javascript @ts-expect-error=[4,7]
 // In embedder page.
 const webview = document.querySelector('webview')
 webview.addEventListener('ipc-message', (event) => {
@@ -959,9 +987,22 @@ ipcRenderer.on('ping', () => {
 })
 ```
 
-### Event: 'crashed'
+### Event: 'crashed' _Deprecated_
+
+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 is crashed.
+Fired when the renderer process unexpectedly disappears. This is normally
+because it was crashed or killed.
 
 ### Event: 'plugin-crashed'
 
@@ -1067,7 +1108,7 @@ Returns:
   * `frameCharset` string - The character encoding of the frame on which the
     menu was invoked.
   * `inputFieldType` string - If the context menu was invoked on an input
-    field, the type of that field. Possible values are `none`, `plainText`,
+    field, the type of that field. Possible values include `none`, `plainText`,
     `password`, `other`.
   * `spellcheckEnabled` boolean - If the context is editable, whether or not spellchecking is enabled.
   * `menuSourceType` string - Input source that invoked the context menu.

+ 5 - 5
docs/api/window-open.md

@@ -33,12 +33,12 @@ because it is invoked in the main process.
 Returns [`Window`](https://developer.mozilla.org/en-US/docs/Web/API/Window) | null
 
 `features` is a comma-separated key-value list, following the standard format of
-the browser. Electron will parse `BrowserWindowConstructorOptions` out of this
+the browser. Electron will parse [`BrowserWindowConstructorOptions`](structures/browser-window-options.md) out of this
 list where possible, for convenience. For full control and better ergonomics,
 consider using `webContents.setWindowOpenHandler` to customize the
 BrowserWindow creation.
 
-A subset of `WebPreferences` can be set directly,
+A subset of [`WebPreferences`](structures/web-preferences.md) can be set directly,
 unnested, from the features string: `zoomFactor`, `nodeIntegration`, `preload`,
 `javascript`, `contextIsolation`, and `webviewTag`.
 
@@ -59,8 +59,8 @@ 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 `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
+* `frameName` follows the specification of `target` 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`](structures/web-preferences.md) will be copied
   from the parent window, and there is no way to override it because Chromium
   skips browser side navigation in this case.
 
@@ -68,7 +68,7 @@ To customize or cancel the creation of the window, you can optionally set an
 override handler with `webContents.setWindowOpenHandler()` from the main
 process. Returning `{ action: 'deny' }` cancels the window. Returning `{
 action: 'allow', overrideBrowserWindowOptions: { ... } }` will allow opening
-the window and setting the `BrowserWindowConstructorOptions` to be used when
+the window and setting the [`BrowserWindowConstructorOptions`](structures/browser-window-options.md) to be used when
 creating the window. Note that this is more powerful than passing options
 through the feature string, as the renderer has more limited privileges in
 deciding security preferences than the main process.

+ 164 - 1
docs/breaking-changes.md

@@ -12,7 +12,60 @@ 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 (26.0)
+## Planned Breaking API Changes (28.0)
+
+### Removed: `BrowserWindow.setTrafficLightPosition(position)`
+
+`BrowserWindow.setTrafficLightPosition(position)` has been removed, 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
+// Removed in Electron 28
+win.setTrafficLightPosition({ x: 10, y: 10 })
+win.setTrafficLightPosition({ x: 0, y: 0 })
+
+// Replace with
+win.setWindowButtonPosition({ x: 10, y: 10 })
+win.setWindowButtonPosition(null)
+```
+
+### Removed: `BrowserWindow.getTrafficLightPosition()`
+
+`BrowserWindow.getTrafficLightPosition()` has been removed, the
+`BrowserWindow.getWindowButtonPosition()` API should be used instead
+which returns `null` instead of `{ x: 0, y: 0 }` when there is no custom
+position.
+
+```js
+// Removed in Electron 28
+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.
+}
+```
+
+### Removed: `ipcRenderer.sendTo()`
+
+The `ipcRenderer.sendTo()` API has been removed. It should be replaced by setting up a [`MessageChannel`](tutorial/message-ports.md#setting-up-a-messagechannel-between-two-renderers) between the renderers.
+
+The `senderId` and `senderIsMainFrame` properties of `IpcRendererEvent` have been removed as well.
+
+## 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.
 
 ### Behavior Changed: `BrowserView.setAutoResize` behavior on macOS
 
@@ -24,6 +77,83 @@ In Electron 26, BrowserView is now a wrapper around the new [WebContentsView](ap
 As part of this work, the autoresizing behavior is now standardized across all platforms.
 BrowserView autoresizing on macOS now uses the same algorithm that is used on Windows and Linux.
 
+### Deprecated: `ipcRenderer.sendTo()`
+
+The `ipcRenderer.sendTo()` API has been deprecated. It should be replaced by setting up a [`MessageChannel`](tutorial/message-ports.md#setting-up-a-messagechannel-between-two-renderers) between the renderers.
+
+The `senderId` and `senderIsMainFrame` properties of `IpcRendererEvent` have been deprecated as well.
+
+### Removed: color scheme events in `systemPreferences`
+
+The following `systemPreferences` events have been removed:
+
+* `inverted-color-scheme-changed`
+* `high-contrast-color-scheme-changed`
+
+Use the new `updated` event on the `nativeTheme` module instead.
+
+```js
+// Removed
+systemPreferences.on('inverted-color-scheme-changed', () => { /* ... */ })
+systemPreferences.on('high-contrast-color-scheme-changed', () => { /* ... */ })
+
+// Replace with
+nativeTheme.on('updated', () => { /* ... */ })
+```
+
+## Planned Breaking API Changes (26.0)
+
+### Deprecated: `webContents.getPrinters`
+
+The `webContents.getPrinters` method has been deprecated. Use
+`webContents.getPrintersAsync` instead.
+
+```js
+const w = new BrowserWindow({ show: false })
+
+// Deprecated
+console.log(w.webContents.getPrinters())
+// Replace with
+w.webContents.getPrintersAsync().then((printers) => {
+  console.log(printers)
+})
+```
+
+### Deprecated: `systemPreferences.{get,set}AppLevelAppearance` and `systemPreferences.appLevelAppearance`
+
+The `systemPreferences.getAppLevelAppearance` and `systemPreferences.setAppLevelAppearance`
+methods have been deprecated, as well as the `systemPreferences.appLevelAppearance` property.
+Use the `nativeTheme` module instead.
+
+```js
+// Deprecated
+systemPreferences.getAppLevelAppearance()
+// Replace with
+nativeTheme.shouldUseDarkColors
+
+// Deprecated
+systemPreferences.appLevelAppearance
+// Replace with
+nativeTheme.shouldUseDarkColors
+
+// Deprecated
+systemPreferences.setAppLevelAppearance('dark')
+// Replace with
+nativeTheme.themeSource = 'dark'
+```
+
+### Deprecated: `alternate-selected-control-text` value for `systemPreferences.getColor`
+
+The `alternate-selected-control-text` value for `systemPreferences.getColor`
+has been deprecated. Use `selected-content-background` instead.
+
+```js
+// Deprecated
+systemPreferences.getColor('alternate-selected-control-text')
+// Replace with
+systemPreferences.getColor('selected-content-background')
+```
+
 ## Planned Breaking API Changes (25.0)
 
 ### Deprecated: `protocol.{register,intercept}{Buffer,String,Stream,File,Http}Protocol`
@@ -290,6 +420,39 @@ webContents.setWindowOpenHandler((details) => {
 })
 ```
 
+### Removed: `<webview>` `new-window` event
+
+The `new-window` event of `<webview>` has been removed. There is no direct replacement.
+
+```js
+// Removed in Electron 22
+webview.addEventListener('new-window', (event) => {})
+```
+
+```javascript fiddle='docs/fiddles/ipc/webview-new-window'
+// Replace with
+
+// main.js
+mainWindow.webContents.on('did-attach-webview', (event, wc) => {
+  wc.setWindowOpenHandler((details) => {
+    mainWindow.webContents.send('webview-new-window', wc.id, details)
+    return { action: 'deny' }
+  })
+})
+
+// preload.js
+const { ipcRenderer } = require('electron')
+ipcRenderer.on('webview-new-window', (e, webContentsId, details) => {
+  console.log('webview-new-window', webContentsId, details)
+  document.getElementById('webview').dispatchEvent(new Event('new-window'))
+})
+
+// renderer.js
+document.getElementById('webview').addEventListener('new-window', () => {
+  console.log('got new-window event')
+})
+```
+
 ### Deprecated: BrowserWindow `scroll-touch-*` events
 
 The `scroll-touch-begin`, `scroll-touch-end` and `scroll-touch-edge` events on

+ 0 - 62
docs/development/azure-vm-setup.md

@@ -1,62 +0,0 @@
-# Updating an Appveyor Azure Image
-
-Electron CI on Windows uses AppVeyor, which in turn uses Azure VM images to run.  Occasionally, these VM images need to be updated due to changes in Chromium requirements.  In order to update you will need [PowerShell](https://learn.microsoft.com/en-us/powershell/scripting/install/installing-powershell?view=powershell-7.3&viewFallbackFrom=powershell-6) and the [Azure PowerShell module](https://learn.microsoft.com/en-us/powershell/azure/install-az-ps?view=azps-9.5.0&viewFallbackFrom=azps-1.8.0).
-
-Occasionally we need to update these images owing to changes in Chromium or other miscellaneous build requirement changes.
-
-Example Use Case:
-    * We need `VS15.9` and we have `VS15.7` installed; this would require us to update an Azure image.
-
-1. Identify the image you wish to modify.
-    * In [appveyor.yml](https://github.com/electron/electron/blob/main/appveyor.yml), the image is identified by the property _image_.
-        * The names used correspond to the _"images"_ defined for a build cloud, eg the [libcc-20 cloud](https://windows-ci.electronjs.org/build-clouds/8).
-    * Find the image you wish to modify in the build cloud and make note of the **VHD Blob Path** for that image, which is the value for that corresponding key.
-        * You will need this URI path to copy into a new image.
-    * You will also need the storage account name which is labeled in AppVeyor as the **Disk Storage Account Name**
-
-2. Get the Azure storage account key
-    * Log into Azure using credentials stored in LastPass (under Azure Enterprise) and then find the storage account corresponding to the name found in AppVeyor.
-        * Example, for `appveyorlibccbuilds` **Disk Storage Account Name** you'd look for `appveyorlibccbuilds` in the list of storage accounts @ Home < Storage Accounts
-            * Click into it and look for `Access Keys`, and then you can use any of the keys present in the list.
-
-3. Get the full virtual machine image URI from Azure
-    * Navigate to Home < Storage Accounts < `$ACCT_NAME` < Blobs < Images
-        * In the following list, look for the VHD path name you got from Appveyor and then click on it.
-            * Copy the whole URL from the top of the subsequent window.
-
-4. Copy the image using the [Copy Master Image PowerShell script](https://github.com/appveyor/ci/blob/master/scripts/enterprise/copy-master-image-azure.ps1).
-    * It is essential to copy the VM because if you spin up a VM against an image that image cannot at the same time be used by AppVeyor.
-    * Use the storage account name, key, and URI obtained from Azure to run this script.
-        * See Step 3 for URI & when prompted, press enter to use same storage account as destination.
-        * Use default destination container name `(images)`
-        * Also, when naming the copy, use a name that indicates what the new image will contain (if that has changed) and date stamp.
-            * Ex. `libcc-20core-vs2017-15.9-2019-04-15.vhd`
-    * Go into Azure and get the URI for the newly created image as described in a previous step
-
-5. Spin up a new VM using the [Create Master VM from VHD PowerShell](https://github.com/appveyor/ci/blob/master/scripts/enterprise/create_master_vm_from_vhd.ps1).
-    * From PowerShell, execute `ps1` file with `./create_master_vm_from_vhd.ps1`
-    * You will need the credential information available in the AppVeyor build cloud definition.
-        * This includes:
-            * Client ID
-            * Client Secret
-            * Tenant ID
-            * Subscription ID
-            * Resource Group
-            * Virtual Network
-    * You will also need to specify
-        * Master VM name - just a unique name to identify the temporary VM
-        * Master VM size - use `Standard_F32s_v2`
-        * Master VHD URI - use URI obtained @ end of previous step
-        * Location use `East US`
-
-6. Log back into Azure and find the VM you just created in Home < Virtual Machines < `$YOUR_NEW_VM`
-    * You can download a RDP (Remote Desktop) file to access the VM.
-
-7. Using Microsoft Remote Desktop, click `Connect` to connect to the VM.
-    * Credentials for logging into the VM are found in LastPass under the `AppVeyor Enterprise master VM` credentials.
-
-8. Modify the VM as required.
-
-9. Shut down the VM and then delete it in Azure.
-
-10. Add the new image to the Appveyor Cloud settings or modify an existing image to point to the new VHD.

+ 1 - 1
docs/development/build-instructions-gn.md

@@ -225,7 +225,7 @@ generate build headers for the modules to compile against, run the following
 under `src/` directory.
 
 ```sh
-$ ninja -C out/Testing third_party/electron_node:headers
+$ ninja -C out/Testing electron:node_headers
 ```
 
 You can now [run the tests](testing.md#unit-tests).

+ 2 - 2
docs/development/build-instructions-windows.md

@@ -23,7 +23,7 @@ store from `.pdb` files.
   SDK, open Visual Studio Installer, select
   `Modify` → `Individual Components`, scroll down and select the appropriate
   Windows SDK to install. Another option would be to look at the
-  [Windows SDK and emulator archive](https://developer.microsoft.com/en-us/windows/downloads/sdk-archive)
+  [Windows SDK and emulator archive](https://developer.microsoft.com/en-us/windows/downloads/sdk-archive/)
   and download the standalone version of the SDK respectively.
   * The SDK Debugging Tools must also be installed. If the Windows 10 SDK was installed
   via the Visual Studio installer, then they can be installed by going to:
@@ -32,7 +32,7 @@ store from `.pdb` files.
   Or, you can download the standalone SDK installer and use it to install the Debugging Tools.
 
 If you don't currently have a Windows installation,
-[dev.microsoftedge.com](https://developer.microsoft.com/en-us/microsoft-edge/tools/vms/)
+[developer.microsoft.com](https://developer.microsoft.com/en-us/windows/downloads/virtual-machines/)
 has timebombed versions of Windows that you can use to build Electron.
 
 Building Electron is done entirely with command-line scripts and cannot be done

+ 1 - 1
docs/development/coding-style.md

@@ -49,7 +49,7 @@ formatted correctly.
 * Write [standard](https://www.npmjs.com/package/standard) JavaScript style.
 * File names should be concatenated with `-` instead of `_`, e.g.
   `file-name.js` rather than `file_name.js`, because in
-  [github/atom](https://github.com/github/atom) module names are usually in
+  [atom/atom](https://github.com/atom/atom) module names are usually in
   the `module-name` form. This rule only applies to `.js` files.
 * Use newer ES6/ES2015 syntax where appropriate
   * [`const`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/const)

+ 3 - 3
docs/development/creating-api.md

@@ -129,9 +129,9 @@ void Initialize(v8::Local<v8::Object> exports,
 
 In the [`typings/internal-ambient.d.ts`](https://github.com/electron/electron/blob/main/typings/internal-ambient.d.ts) file, we need to append a new property onto the `Process` interface like so:
 
-```ts title='typings/internal-ambient.d.ts'
+```ts title='typings/internal-ambient.d.ts' @ts-nocheck
 interface Process {
-    _linkedBinding(name: 'electron_browser_{api_name}', Electron.ApiName);
+    _linkedBinding(name: 'electron_browser_{api_name}'): Electron.ApiName;
 }
 ```
 
@@ -164,7 +164,7 @@ An example of the contents of this file can be found [here](https://github.com/e
 
 Add your module to the module list found at `"lib/browser/api/module-list.ts"` like so:
 
-```typescript title='lib/browser/api/module-list.ts'
+```typescript title='lib/browser/api/module-list.ts' @ts-nocheck
 export const browserModuleList: ElectronInternal.ModuleEntry[] = [
   { name: 'apiName', loader: () => require('./api-name') },
 ];

+ 1 - 1
docs/development/debugging-on-windows.md

@@ -88,7 +88,7 @@ is doing to the operating system, it can be a valuable resource.
 For an introduction to ProcMon's basic and advanced debugging features, go check
 out [this video tutorial][procmon-instructions] provided by Microsoft.
 
-[sys-internals]: https://technet.microsoft.com/en-us/sysinternals/processmonitor.aspx
+[sys-internals]: https://learn.microsoft.com/en-us/sysinternals/downloads/procmon
 [procmon-instructions]: https://learn.microsoft.com/en-us/shows/defrag-tools/4-process-monitor
 
 ## Using WinDbg

+ 1 - 1
docs/development/issues.md

@@ -24,7 +24,7 @@ contribute:
 
 ## Asking for General Help
 
-[The Electron website](https://electronjs.org/community) has a
+[The Electron website](https://www.electronjs.org/community) has a
 list of resources for getting programming help, reporting security issues,
 contributing, and more. Please use the issue tracker for bugs only!
 

+ 1 - 1
docs/development/testing.md

@@ -66,7 +66,7 @@ the Node.js source tree.
 2. Node headers have to be compiled for your configuration.
 
    ```powershell
-   ninja -C out\Testing third_party\electron_node:headers
+   ninja -C out\Testing electron:node_headers
    ```
 
 3. The electron.lib has to be copied as node.lib.

+ 2 - 2
docs/fiddles/features/dark-mode/main.js

@@ -1,5 +1,5 @@
-const { app, BrowserWindow, ipcMain, nativeTheme } = require('electron')
-const path = require('path')
+const { app, BrowserWindow, ipcMain, nativeTheme } = require('electron/main')
+const path = require('node:path')
 
 function createWindow () {
   const win = new BrowserWindow({

+ 1 - 1
docs/fiddles/features/dark-mode/preload.js

@@ -1,4 +1,4 @@
-const { contextBridge, ipcRenderer } = require('electron')
+const { contextBridge, ipcRenderer } = require('electron/renderer')
 
 contextBridge.exposeInMainWorld('darkMode', {
   toggle: () => ipcRenderer.invoke('dark-mode:toggle'),

+ 4 - 4
docs/fiddles/features/drag-and-drop/main.js

@@ -1,7 +1,7 @@
-const { app, BrowserWindow, ipcMain } = require('electron')
-const path = require('path')
-const fs = require('fs')
-const https = require('https')
+const { app, BrowserWindow, ipcMain } = require('electron/main')
+const path = require('node:path')
+const fs = require('node:fs')
+const https = require('node:https')
 
 function createWindow () {
   const win = new BrowserWindow({

+ 2 - 4
docs/fiddles/features/drag-and-drop/preload.js

@@ -1,7 +1,5 @@
-const { contextBridge, ipcRenderer } = require('electron')
+const { contextBridge, ipcRenderer } = require('electron/renderer')
 
 contextBridge.exposeInMainWorld('electron', {
-  startDrag: (fileName) => {
-    ipcRenderer.send('ondragstart', fileName)
-  }
+  startDrag: (fileName) => ipcRenderer.send('ondragstart', fileName)
 })

+ 1 - 1
docs/fiddles/features/keyboard-shortcuts/global/main.js

@@ -1,4 +1,4 @@
-const { app, BrowserWindow, globalShortcut } = require('electron')
+const { app, BrowserWindow, globalShortcut } = require('electron/main')
 
 function createWindow () {
   const win = new BrowserWindow({

+ 1 - 1
docs/fiddles/features/keyboard-shortcuts/interception-from-main/main.js

@@ -1,4 +1,4 @@
-const { app, BrowserWindow } = require('electron')
+const { app, BrowserWindow } = require('electron/main')
 
 app.whenReady().then(() => {
   const win = new BrowserWindow({ width: 800, height: 600 })

+ 1 - 1
docs/fiddles/features/keyboard-shortcuts/local/main.js

@@ -1,4 +1,4 @@
-const { app, BrowserWindow, Menu, MenuItem } = require('electron')
+const { app, BrowserWindow, Menu, MenuItem } = require('electron/main')
 
 function createWindow () {
   const win = new BrowserWindow({

+ 1 - 1
docs/fiddles/features/keyboard-shortcuts/web-apis/main.js

@@ -1,5 +1,5 @@
 // Modules to control application life and create native browser window
-const { app, BrowserWindow } = require('electron')
+const { app, BrowserWindow } = require('electron/main')
 
 function createWindow () {
   // Create the browser window.

+ 1 - 1
docs/fiddles/features/macos-dock-menu/main.js

@@ -1,4 +1,4 @@
-const { app, BrowserWindow, Menu } = require('electron')
+const { app, BrowserWindow, Menu } = require('electron/main')
 
 function createWindow () {
   const win = new BrowserWindow({

+ 1 - 1
docs/fiddles/features/notifications/main/main.js

@@ -1,4 +1,4 @@
-const { app, BrowserWindow, Notification } = require('electron')
+const { app, BrowserWindow, Notification } = require('electron/main')
 
 function createWindow () {
   const win = new BrowserWindow({

+ 1 - 1
docs/fiddles/features/notifications/renderer/main.js

@@ -1,4 +1,4 @@
-const { app, BrowserWindow } = require('electron')
+const { app, BrowserWindow } = require('electron/main')
 
 function createWindow () {
   const win = new BrowserWindow({

+ 2 - 2
docs/fiddles/features/notifications/renderer/renderer.js

@@ -2,5 +2,5 @@ const NOTIFICATION_TITLE = 'Title'
 const NOTIFICATION_BODY = 'Notification from the Renderer process. Click to log to console.'
 const CLICK_MESSAGE = 'Notification clicked!'
 
-new Notification(NOTIFICATION_TITLE, { body: NOTIFICATION_BODY })
-  .onclick = () => document.getElementById('output').innerText = CLICK_MESSAGE
+new window.Notification(NOTIFICATION_TITLE, { body: NOTIFICATION_BODY })
+  .onclick = () => { document.getElementById('output').innerText = CLICK_MESSAGE }

+ 21 - 12
docs/fiddles/features/offscreen-rendering/main.js

@@ -1,19 +1,34 @@
-const { app, BrowserWindow } = require('electron')
-const fs = require('fs')
-const path = require('path')
+const { app, BrowserWindow } = require('electron/main')
+const fs = require('node:fs')
+const path = require('node:path')
 
 app.disableHardwareAcceleration()
 
-let win
+function createWindow () {
+  const win = new BrowserWindow({
+    width: 800,
+    height: 600,
+    webPreferences: {
+      offscreen: true
+    }
+  })
 
-app.whenReady().then(() => {
-  win = new BrowserWindow({ webPreferences: { offscreen: true } })
   win.loadURL('https://github.com')
   win.webContents.on('paint', (event, dirty, image) => {
     fs.writeFileSync('ex.png', image.toPNG())
   })
   win.webContents.setFrameRate(60)
   console.log(`The screenshot has been successfully saved to ${path.join(process.cwd(), 'ex.png')}`)
+}
+
+app.whenReady().then(() => {
+  createWindow()
+
+  app.on('activate', () => {
+    if (BrowserWindow.getAllWindows().length === 0) {
+      createWindow()
+    }
+  })
 })
 
 app.on('window-all-closed', () => {
@@ -21,9 +36,3 @@ app.on('window-all-closed', () => {
     app.quit()
   }
 })
-
-app.on('activate', () => {
-  if (BrowserWindow.getAllWindows().length === 0) {
-    createWindow()
-  }
-})

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