Compare commits

...

38 Commits

Author SHA1 Message Date
Milan Burda
fd761ec8f7 chore: strip trailing whitespace (#35969) 2023-02-01 12:59:16 +01:00
Samuel Attard
dbdbb6fb3b build: bump deps to clean up yarn audit (#36535)
build: update dependencies to clean up yarn audit
2023-01-31 13:58:39 -08:00
Shelley Vohr
26ee197fe5 chore: validate .mjs spec files in Node.js smoke tests (#37073)
chore: take mjs spec files in Node.js smoke tests
2023-01-31 12:36:27 -08:00
Shelley Vohr
730a07ad62 docs: note how to clear an aspect ratio (#37074) 2023-01-31 12:36:09 -08:00
David Sanders
01b4e3b521 ci: update actions/stale to v6.0.1 (#37079) 2023-01-31 12:30:40 -08:00
David Sanders
899881457b docs: update modules list in docs/README.md (#37080) 2023-01-31 12:29:33 -08:00
John Kleinschmidt
9adbf49240 ci: fixup ninja for release (#37083) 2023-01-31 11:29:39 -05:00
Milan Burda
c6203d54d0 refactor: simplify script/lint.js (#37077)
Co-authored-by: Milan Burda <miburda@microsoft.com>
2023-01-31 14:33:50 +01:00
Shelley Vohr
23739c644b fix: crash on WebWorkerObserver script execution (#37050)
fix: crash on WebWorkerObserver script execution
2023-01-31 12:29:29 +01:00
Shelley Vohr
ce35bda805 fix: crash on window.print() (#37052)
fix: crash on window.print()
2023-01-31 12:06:11 +01:00
John Kleinschmidt
fcc7a869f2 ci: ensure correct ninja is used (#37069) 2023-01-30 12:35:38 -05:00
Jeremy Rose
85f41d59ac fix: ensure autofill popup view is > 1x1 in size (#36121)
* fix: ensure autofill popup view is > 1x1 in size

ref #26667

* Update shell/browser/ui/views/autofill_popup_view.cc

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

Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2023-01-27 10:50:19 +01:00
Shelley Vohr
0026fdb78a fix: resizing borders in nondraggable regions (#37016)
* fix: resizing borders in nondraggable regions

* chore: remove frame handling from ShouldDescendIntoChildForEventHandling
2023-01-26 14:04:19 +01:00
Mikaël Barbero
1486cbdf64 feat: add support for unlocking with Apple Watch (#36935) 2023-01-26 13:05:42 +01:00
Cheng Zhao
c303135b02 fix: fallback to GtkStatusIcon when app indicator is not supported (#36815)
* chore: get ready for multi backend tray

* fix: fallback to GtkStatusIcon when app indicator is not supported

* chore: use smart pointers
2023-01-26 19:15:55 +09:00
Shelley Vohr
7d46d3ec9d feat: emit devtools-open-url event for DevTools link selection (#36774)
* feat: emit event for DevTools link selection

* chore: devtools-open-in-new-tab -> devtools-open-url
2023-01-26 09:54:26 +01:00
Himanshu Patil
8d008c977d docs: updated deep link docs (#36952)
* removed open-url listener from windows code

* updated deep-link fiddle

* fixed url hash to app.requestSingleInstanceLock

* code linted

* updated website url to relative file path

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

Co-authored-by: David Sanders <dsanders11@ucsbalum.com>
2023-01-26 16:20:10 +09:00
Shelley Vohr
c6b9340b89 chore: fix memory leak in v8.serialize() (#37021)
chore: fix memory leak in v8.serialize()
2023-01-26 15:43:57 +09:00
Milan Burda
397aee7315 chore: update README.md (#37002)
Update README.md
2023-01-26 09:57:20 +09:00
Robo
a30a9c7c4f chore: remove crashpad related sandbox policy (#37013) 2023-01-26 09:01:34 +09:00
kyrylo-hrechykhin
a59f11fdb1 feat: enable whole-program optimization native modules by default (#36937)
* feat: enable whole-program optimization

Enable whole-program optimization in electron native modules by default.

* pass --with-ltcg to configure.py instead of setting variable

* enable ltcg only on windows

Co-authored-by: Kyrylo Hrechykhin <khrechykhin@microsoft.com>
2023-01-25 13:06:05 -08:00
Samuel Attard
58beec1da2 fix: do not error on null exports in ESM loader (#37009) 2023-01-25 13:03:47 -08:00
Milan Burda
4bc6b15f53 refactor: move spec helpers to spec/lib (#37010)
Co-authored-by: Milan Burda <miburda@microsoft.com>
2023-01-25 13:01:25 -08:00
Milan Burda
355f322dbd chore: remove unused fixture_support.md (#37011)
Co-authored-by: Milan Burda <miburda@microsoft.com>
2023-01-25 13:00:51 -08:00
Milan Burda
2f79444535 refactor: separate WEB_VIEW_ATTRIBUTES / WEB_VIEW_ERROR_MESSAGES (#36972) 2023-01-25 16:08:46 +01:00
Milan Burda
a9b6041d38 chore: remove unused files in spec/fixtures (#37012)
Co-authored-by: Milan Burda <miburda@microsoft.com>
2023-01-25 16:02:44 +01:00
Shelley Vohr
afca3ff965 chore: call ListenerDestroyed() in FileSelectHelper::RunFileChooserEnd() (#37006)
chore: call ListenerDestroyed() in FileSelectHelper::RunFileChooserEnd()
2023-01-25 15:51:01 +01:00
Shelley Vohr
86f99e9cf0 chore: cleanup ElectronContentClient::AddPlugins (#37005)
chore: cleanup ElectronContentClient::AddPlugins
2023-01-25 14:57:30 +01:00
David Sanders
ca3145a547 chore: use vscode-markdown-languageservice for link linting (#36901)
* chore: use vscode-markdown-languageservice for docs link linting

* docs: make links relative
2023-01-24 09:00:25 +01:00
Shelley Vohr
37f5881882 test: add a <datalist> spec for time type (#36953)
spec: add a datalist spec for time type
2023-01-23 11:21:28 -05:00
David Sanders
f20d0b4ecb chore: clean up .keep files (#36980) 2023-01-23 09:57:00 +01:00
Robo
cdb65c15a8 fix: make plugin helper executable unconditional (#36971) 2023-01-21 09:42:45 +09:00
Shelley Vohr
c3f02d7df2 chore: cleanup autofill agent shutdown sequence (#36954) 2023-01-20 14:35:06 -08:00
David Sanders
3b018143b4 ci: don't run stale workflow jobs in parallel (#36967) 2023-01-20 13:02:50 -08:00
David Sanders
885c1878d4 test: fix nativeTheme test when system in dark mode (#36943) 2023-01-19 21:59:20 -05:00
GGIEnrike
5ce8dfdcb5 docs: Change factuality and word choice in app.runningUnderARM64Translation (#36947)
Change factuality and word choice.

Added "or WOW" to the phrase, "when they are running the x64 version under Rosetta", to reflect the use of a supported platform, Windows, as a possible scenario.
Changed the wording of that same sentence to make it appear clearer. "incorrectly" to "mistakenly" and moved this word to before the verb instead of the end of the sentence.
2023-01-19 15:00:06 -05:00
David Sanders
4e4ae9ff53 docs: update clipboard fiddles (#36946) 2023-01-19 14:59:35 -05:00
Shelley Vohr
55c818d0a8 fix: <datalist> dropdown positioning (#36934)
fix: datalist dropdown positioning
2023-01-19 19:44:23 +01:00
195 changed files with 2129 additions and 1464 deletions

View File

@@ -13,7 +13,7 @@ parameters:
run-docs-only:
type: boolean
default: false
upload-to-storage:
type: string
default: '1'

View File

@@ -4,7 +4,7 @@ parameters:
run-docs-only:
type: boolean
default: false
upload-to-storage:
type: string
default: '1'
@@ -141,7 +141,7 @@ env-mas-apple-silicon: &env-mas-apple-silicon
env-send-slack-notifications: &env-send-slack-notifications
NOTIFY_SLACK: true
env-global: &env-global
ELECTRON_OUT_DIR: Default
@@ -486,7 +486,9 @@ step-fix-sync: &step-fix-sync
run:
name: Fix Sync
command: |
SEDOPTION="-i"
if [ "`uname`" == "Darwin" ]; then
SEDOPTION="-i ''"
# Fix Clang Install (wrong binary)
rm -rf src/third_party/llvm-build
python3 src/tools/clang/scripts/update.py
@@ -496,13 +498,16 @@ 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 ninja (wrong binary)
echo 'infra/3pp/tools/ninja/${platform}' `gclient getdep --deps-file=src/DEPS -r 'src/third_party/ninja:infra/3pp/tools/ninja/${platform}'` > ninja_ensure_file
sed -i '' "s/Updating depot_tools... //g" ninja_ensure_file
cipd ensure --root src/third_party/ninja -ensure-file ninja_ensure_file
fi
# Make sure we are using the right ninja
echo 'infra/3pp/tools/ninja/${platform}' `gclient getdep --deps-file=src/DEPS -r 'src/third_party/ninja:infra/3pp/tools/ninja/${platform}'` > ninja_ensure_file
sed $SEDOPTION "s/Updating depot_tools... //g" ninja_ensure_file
cipd ensure --root src/third_party/ninja -ensure-file ninja_ensure_file
# Explicitly add ninja to the path
echo 'export PATH="$PATH:'"$PWD"'/src/third_party/ninja"' >> $BASH_ENV
cd src/third_party/angle
rm .git/objects/info/alternates
git remote set-url origin https://chromium.googlesource.com/angle/angle.git
@@ -689,7 +694,7 @@ step-show-goma-stats: &step-show-goma-stats
run:
shell: /bin/bash
name: Check goma stats after build
command: |
command: |
set +e
set +o pipefail
$LOCAL_GOMA_DIR/goma_ctl.py stat
@@ -793,7 +798,7 @@ step-maybe-cross-arch-snapshot: &step-maybe-cross-arch-snapshot
elif [ "$TARGET_ARCH" == "arm64" ]; then
export MKSNAPSHOT_PATH="clang_x64_v8_arm64"
fi
cp "out/Default/$MKSNAPSHOT_PATH/mksnapshot" out/Default
cp "out/Default/$MKSNAPSHOT_PATH/mksnapshot" out/Default
cp "out/Default/$MKSNAPSHOT_PATH/v8_context_snapshot_generator" out/Default
if [ "`uname`" == "Linux" ]; then
cp "out/Default/$MKSNAPSHOT_PATH/libffmpeg.so" out/Default
@@ -1007,7 +1012,7 @@ commands:
else
echo 'Using Python install from cache'
fi
sudo installer -pkg python-downloads/python-2.7.18-macosx10.9.pkg -target /
sudo installer -pkg python-downloads/python-2.7.18-macosx10.9.pkg -target /
fi
- save_cache:
paths:
@@ -1415,7 +1420,7 @@ commands:
artifact-key: << parameters.artifact-key >>
build-nonproprietary-ffmpeg: << parameters.build-nonproprietary-ffmpeg >>
- steps: << parameters.after-build-and-save >>
# Save all data needed for a further tests run.
- when:
condition: << parameters.persist >>
@@ -2119,7 +2124,7 @@ jobs:
- electron-tests:
artifact-key: darwin-x64
darwin-testing-arm64-tests:
darwin-testing-arm64-tests:
executor: apple-silicon
environment:
<<: *env-mac-large
@@ -2234,9 +2239,9 @@ workflows:
filters:
branches:
# Do not run this on forked pull requests
ignore: /pull\/[0-9]+/
ignore: /pull\/[0-9]+/
requires:
- linux-arm-testing
- linux-arm-testing
- linux-arm64-testing:
requires:
- linux-make-src-cache
@@ -2244,7 +2249,7 @@ workflows:
filters:
branches:
# Do not run this on forked pull requests
ignore: /pull\/[0-9]+/
ignore: /pull\/[0-9]+/
requires:
- linux-arm64-testing
- linux-arm64-testing-gn-check:

View File

@@ -7,9 +7,9 @@ services:
volumes:
- ..:/workspaces/gclient/src/electron:cached
- /var/run/docker.sock:/var/run/docker.sock
- /var/run/docker.sock:/var/run/docker.sock
command: /bin/sh -c "while sleep 1000; do :; done"
command: /bin/sh -c "while sleep 1000; do :; done"
user: builduser

View File

@@ -19,7 +19,7 @@ body:
label: Electron Version
description: |
What version of Electron are you using?
Note: Please only report issues for [currently supported versions of Electron](https://www.electronjs.org/docs/latest/tutorial/support#currently-supported-versions).
placeholder: 17.0.0
validations:

View File

@@ -29,7 +29,7 @@ body:
- type: textarea
attributes:
label: Alternatives Considered
description: A clear and concise description of any alternative solutions or features you've considered.
description: A clear and concise description of any alternative solutions or features you've considered.
validations:
required: true
- type: textarea

View File

@@ -23,6 +23,6 @@ jobs:
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.
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.

View File

@@ -11,7 +11,7 @@ jobs:
stale:
runs-on: ubuntu-latest
steps:
- uses: actions/stale@3de2653986ebd134983c79fe2be5d45cc3d9f4e1
- uses: actions/stale@5ebf00ea0e4c1561e9b43a292ed34424fb1d4578 # tag: v6.0.1
with:
days-before-stale: 90
days-before-close: 30
@@ -25,8 +25,10 @@ jobs:
only-pr-labels: not-a-real-label
pending-repro:
runs-on: ubuntu-latest
if: ${{ always() }}
needs: stale
steps:
- uses: actions/stale@3de2653986ebd134983c79fe2be5d45cc3d9f4e1
- uses: actions/stale@5ebf00ea0e4c1561e9b43a292ed34424fb1d4578 # tag: v6.0.1
with:
days-before-stale: -1
days-before-close: 10

View File

@@ -632,8 +632,6 @@ source_set("electron_lib") {
sources += [
"shell/browser/certificate_manager_model.cc",
"shell/browser/certificate_manager_model.h",
"shell/browser/ui/gtk/menu_util.cc",
"shell/browser/ui/gtk/menu_util.h",
"shell/browser/ui/gtk_util.cc",
"shell/browser/ui/gtk_util.h",
]

View File

@@ -39,7 +39,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.
* 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 and 8 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).
* 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
* Fedora 24 and newer

View File

@@ -18,7 +18,7 @@ environment:
PYTHONIOENCODING: UTF-8
# Uncomment these lines and set APPVEYOR_RDP_PASSWORD in project settings to enable RDP before bake begins
# install:
# - ps: $blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1'))
# - ps: $blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1'))
build_script:
# Uncomment/change the following line if the hard drive/partition size needs to change
# - ps: Resize-Partition -DriveLetter C -Size (256GB) # ensure initial partition size
@@ -28,8 +28,8 @@ build_script:
if (-not (Test-Path -Path .\src)) {
New-Item -Path .\src -ItemType Directory
}
- ps: git clone --depth=1 https://chromium.googlesource.com/chromium/tools/depot_tools.git
- ps: $env:PATH="$pwd\depot_tools;$env:PATH"
- ps: git clone --depth=1 https://chromium.googlesource.com/chromium/tools/depot_tools.git
- ps: $env:PATH="$pwd\depot_tools;$env:PATH"
- update_depot_tools.bat
- ps: Move-Item $env:APPVEYOR_BUILD_FOLDER -Destination src\electron
# Uncomment the following line if windows deps change

View File

@@ -1,5 +1,5 @@
# NOTE IF CHANGING THIS FILE, ALSO APPLY THE CHANGE TO appveyor.yml
# IF APPLICABLE!!!!
# NOTE IF CHANGING THIS FILE, ALSO APPLY THE CHANGE TO appveyor.yml
# IF APPLICABLE!!!!
#
#
# The config expects the following environment variables to be set:
@@ -51,6 +51,8 @@ environment:
clone_folder: C:\projects\src\electron
skip_branch_with_pr: true
# the first failed job cancels other jobs and fails entire build
matrix:
fast_finish: true
@@ -117,7 +119,7 @@ for:
$env:NINJA_STATUS="[%r processes, %f/%t @ %o/s : %es] "
}
- gclient config --name "src\electron" --unmanaged %GCLIENT_EXTRA_ARGS% "https://github.com/electron/electron"
# Patches are applied in the image bake. Check depshash to see if patches have changed.
# Patches are applied in the image bake. Check depshash to see if patches have changed.
- ps: $env:RUN_GCLIENT_SYNC="false"
- ps: $depshash_baked = Get-Content .\src\.depshash -Raw
- ps: cd src\electron
@@ -130,6 +132,7 @@ for:
}
- if "%RUN_GCLIENT_SYNC%"=="true" ( gclient sync --with_branch_heads --with_tags ) else ( gclient runhooks )
- cd src
- ps: $env:PATH="$pwd\third_party\ninja;$env:PATH"
- set BUILD_CONFIG_PATH=//electron/build/args/%GN_CONFIG%.gn
- gn gen out/Default "--args=import(\"%BUILD_CONFIG_PATH%\") import(\"%GN_GOMA_FILE%\") %GN_EXTRA_ARGS% "
- gn check out/Default //electron:electron_lib
@@ -258,7 +261,7 @@ for:
cd src
New-Item .\out\Default\gen\node_headers\Release -Type directory
Copy-Item -path .\out\Default\electron.lib -destination .\out\Default\gen\node_headers\Release\node.lib
- set npm_config_nodedir=%cd%\out\Default\gen\node_headers
- set npm_config_nodedir=%cd%\out\Default\gen\node_headers
- set npm_config_arch=arm64
- cd electron
# Explicitly set npm_config_arch because the .env doesn't persist
@@ -269,7 +272,7 @@ for:
- echo Running main test suite & node script/yarn test --runners=main --enable-logging --disable-features=CalculateNativeWinOcclusion
- cd ..
- echo Verifying non proprietary ffmpeg & python electron\script\verify-ffmpeg.py --build-dir out\Default --source-root %cd% --ffmpeg-path out\ffmpeg
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'))

View File

@@ -1,5 +1,5 @@
# NOTE IF CHANGING THIS FILE, ALSO APPLY THE CHANGE TO appveyor-woa.yml
# IF APPLICABLE!!!!
# NOTE IF CHANGING THIS FILE, ALSO APPLY THE CHANGE TO appveyor-woa.yml
# IF APPLICABLE!!!!
#
#
# The config expects the following environment variables to be set:
@@ -49,6 +49,8 @@ environment:
clone_folder: C:\projects\src\electron
skip_branch_with_pr: true
# the first failed job cancels other jobs and fails entire build
matrix:
fast_finish: true
@@ -115,7 +117,7 @@ for:
$env:NINJA_STATUS="[%r processes, %f/%t @ %o/s : %es] "
}
- gclient config --name "src\electron" --unmanaged %GCLIENT_EXTRA_ARGS% "https://github.com/electron/electron"
# Patches are applied in the image bake. Check depshash to see if patches have changed.
# Patches are applied in the image bake. Check depshash to see if patches have changed.
- ps: $env:RUN_GCLIENT_SYNC="false"
- ps: $depshash_baked = Get-Content .\src\.depshash -Raw
- ps: cd src\electron
@@ -128,6 +130,7 @@ for:
}
- if "%RUN_GCLIENT_SYNC%"=="true" ( gclient sync --with_branch_heads --with_tags ) else ( gclient runhooks )
- cd src
- ps: $env:PATH="$pwd\third_party\ninja;$env:PATH"
- set BUILD_CONFIG_PATH=//electron/build/args/%GN_CONFIG%.gn
- gn gen out/Default "--args=import(\"%BUILD_CONFIG_PATH%\") import(\"%GN_GOMA_FILE%\") %GN_EXTRA_ARGS% "
- gn check out/Default //electron:electron_lib
@@ -269,7 +272,7 @@ for:
- echo "Done verifying mksnapshot"
- echo Verifying chromedriver & python electron\script\verify-chromedriver.py --build-dir out\Default --source-root %cd%
- echo "Done verifying chromedriver"
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'))

View File

@@ -110,6 +110,7 @@ These individual tutorials expand on topics discussed in the guide above.
* [BrowserView](api/browser-view.md)
* [BrowserWindow](api/browser-window.md)
* [contentTracing](api/content-tracing.md)
* [desktopCapturer](api/desktop-capturer.md)
* [dialog](api/dialog.md)
* [globalShortcut](api/global-shortcut.md)
* [inAppPurchase](api/in-app-purchase.md)
@@ -118,19 +119,22 @@ These individual tutorials expand on topics discussed in the guide above.
* [MenuItem](api/menu-item.md)
* [MessageChannelMain](api/message-channel-main.md)
* [MessagePortMain](api/message-port-main.md)
* [nativeTheme](api/native-theme.md)
* [net](api/net.md)
* [netLog](api/net-log.md)
* [nativeTheme](api/native-theme.md)
* [Notification](api/notification.md)
* [powerMonitor](api/power-monitor.md)
* [powerSaveBlocker](api/power-save-blocker.md)
* [protocol](api/protocol.md)
* [pushNotifications](api/push-notifications.md)
* [safeStorage](api/safe-storage.md)
* [screen](api/screen.md)
* [session](api/session.md)
* [ShareMenu](api/share-menu.md)
* [systemPreferences](api/system-preferences.md)
* [TouchBar](api/touch-bar.md)
* [Tray](api/tray.md)
* [utilityProcess](api/utility-process.md)
* [webContents](api/web-contents.md)
* [webFrameMain](api/web-frame-main.md)
@@ -142,11 +146,10 @@ These individual tutorials expand on topics discussed in the guide above.
### Modules for Both Processes:
* [clipboard](api/clipboard.md)
* [clipboard](api/clipboard.md) (non-sandboxed renderers only)
* [crashReporter](api/crash-reporter.md)
* [desktopCapturer](api/desktop-capturer.md)
* [nativeImage](api/native-image.md)
* [shell](api/shell.md)
* [shell](api/shell.md) (non-sandboxed renderers only)
## Development

View File

@@ -1566,5 +1566,4 @@ an ARM64 translator (like the macOS
or Windows [WOW](https://en.wikipedia.org/wiki/Windows_on_Windows)).
You can use this property to prompt users to download the arm64 version of
your application when they are running the x64 version under Rosetta
incorrectly.
your application when they are mistakenly running the x64 version under Rosetta or WOW.

View File

@@ -659,9 +659,9 @@ Emitted when scroll wheel event phase has begun.
> **Note**
> This event is deprecated beginning in Electron 22.0.0. See [Breaking
> Changes](breaking-changes.md#deprecated-browserwindow-scroll-touch--events)
> Changes](../breaking-changes.md#deprecated-browserwindow-scroll-touch--events)
> for details of how to migrate to using the [WebContents
> `input-event`](api/web-contents.md#event-input-event) event.
> `input-event`](./web-contents.md#event-input-event) event.
#### Event: 'scroll-touch-end' _macOS_ _Deprecated_
@@ -669,9 +669,9 @@ Emitted when scroll wheel event phase has ended.
> **Note**
> This event is deprecated beginning in Electron 22.0.0. See [Breaking
> Changes](breaking-changes.md#deprecated-browserwindow-scroll-touch--events)
> Changes](../breaking-changes.md#deprecated-browserwindow-scroll-touch--events)
> for details of how to migrate to using the [WebContents
> `input-event`](api/web-contents.md#event-input-event) event.
> `input-event`](./web-contents.md#event-input-event) event.
#### Event: 'scroll-touch-edge' _macOS_ _Deprecated_
@@ -679,9 +679,9 @@ Emitted when scroll wheel event phase filed upon reaching the edge of element.
> **Note**
> This event is deprecated beginning in Electron 22.0.0. See [Breaking
> Changes](breaking-changes.md#deprecated-browserwindow-scroll-touch--events)
> Changes](../breaking-changes.md#deprecated-browserwindow-scroll-touch--events)
> for details of how to migrate to using the [WebContents
> `input-event`](api/web-contents.md#event-input-event) event.
> `input-event`](./web-contents.md#event-input-event) event.
#### Event: 'swipe' _macOS_
@@ -1036,6 +1036,8 @@ height areas you have within the overall content view.
The aspect ratio is not respected when window is resized programmatically with
APIs like `win.setSize`.
To reset an aspect ratio, pass 0 as the `aspectRatio` value: `win.setAspectRatio(0)`.
#### `win.setBackgroundColor(backgroundColor)`
* `backgroundColor` string - Color in Hex, RGB, RGBA, HSL, HSLA or named CSS color format. The alpha channel is optional for the hex type.

View File

@@ -2,7 +2,7 @@
> Perform copy and paste operations on the system clipboard.
Process: [Main](../glossary.md#main-process), [Renderer](../glossary.md#renderer-process)
Process: [Main](../glossary.md#main-process), [Renderer](../glossary.md#renderer-process) (non-sandboxed only)
On Linux, there is also a `selection` clipboard. To manipulate it
you need to pass `selection` to each method:

View File

@@ -29,8 +29,9 @@ __Platform Considerations__
__Linux__
* Tray icon requires support of [StatusNotifierItem](https://www.freedesktop.org/wiki/Specifications/StatusNotifierItem/)
in user's desktop environment.
* Tray icon uses [StatusNotifierItem](https://www.freedesktop.org/wiki/Specifications/StatusNotifierItem/)
by default, when it is not available in user's desktop environment the
`GtkStatusIcon` will be used instead.
* The `click` event is emitted when the tray icon receives activation from
user, however the StatusNotifierItem spec does not specify which action would
cause an activation, for some environments it is left mouse click, but for

View File

@@ -492,6 +492,14 @@ The `focus` and `blur` events of `WebContents` should only be used to detect
focus change between different `WebContents` and `BrowserView` in the same
window.
#### Event: 'devtools-open-url'
Returns:
* `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.
#### Event: 'devtools-opened'
Emitted when DevTools is opened.

View File

@@ -981,6 +981,14 @@ Returns:
Emitted when mouse moves over a link or the keyboard moves the focus to a link.
### Event: 'devtools-open-url'
Returns:
* `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.
### Event: 'devtools-opened'
Emitted when DevTools is opened.

View File

@@ -1433,7 +1433,7 @@ When building native modules for windows, the `win_delay_load_hook` variable in
the module's `binding.gyp` must be true (which is the default). If this hook is
not present, then the native module will fail to load on Windows, with an error
message like `Cannot find module`. See the [native module
guide](/docs/tutorial/using-native-node-modules.md) for more.
guide](./tutorial/using-native-node-modules.md) for more.
### Removed: IA32 Linux support

View File

@@ -9,7 +9,7 @@
</head>
<body>
<h1>Hello World!</h1>
<p>Hit any key with this window focused to see it captured here.</p>
<div><span>Last Key Pressed: </span><span id="last-keypress"></span></div>
<script src="./renderer.js"></script>

View File

@@ -19,7 +19,7 @@ function createWindow () {
// Some APIs can only be used after this event occurs.
app.whenReady().then(() => {
createWindow()
app.on('activate', function () {
// On macOS it's common to re-create a window in the app when the
// dock icon is clicked and there are no other windows open.

View File

@@ -7,7 +7,7 @@
</head>
<body>
<h1>Connection status: <strong id='status'></strong></h1>
<script src="renderer.js"></script>
</body>
</html>

View File

@@ -7,14 +7,14 @@ function createWindow () {
height: 600,
webPreferences: {
preload: path.join(__dirname, 'preload.js')
}
}
})
mainWindow.webContents.on('select-bluetooth-device', (event, deviceList, callback) => {
event.preventDefault()
if (deviceList && deviceList.length > 0) {
callback(deviceList[0].deviceId)
}
}
})
// Listen for a message from the renderer to get the response for the Bluetooth pairing.
@@ -27,14 +27,14 @@ function createWindow () {
bluetoothPinCallback = callback
// Send a message to the renderer to prompt the user to confirm the pairing.
mainWindow.webContents.send('bluetooth-pairing-request', details)
})
})
mainWindow.loadFile('index.html')
}
app.whenReady().then(() => {
createWindow()
app.on('activate', function () {
if (BrowserWindow.getAllWindows().length === 0) createWindow()
})

View File

@@ -9,7 +9,7 @@ document.getElementById('clickme').addEventListener('click',testIt)
window.electronAPI.bluetoothPairingRequest((event, details) => {
const response = {}
switch (details.pairingKind) {
case 'confirm': {
response.confirmed = confirm(`Do you want to connect to device ${details.deviceId}?`)

View File

@@ -12,7 +12,7 @@
<h3>HID devices automatically granted access via <i>setDevicePermissionHandler</i></h3>
<div id="granted-devices"></div>
<h3>HID devices automatically granted access via <i>select-hid-device</i></h3>
<div id="granted-devices2"></div>

View File

@@ -6,16 +6,16 @@ function createWindow () {
width: 800,
height: 600
})
mainWindow.webContents.session.on('select-hid-device', (event, details, callback) => {
//Add events to handle devices being added or removed before the callback on
//`select-hid-device` is called.
mainWindow.webContents.session.on('hid-device-added', (event, device) => {
mainWindow.webContents.session.on('hid-device-added', (event, device) => {
console.log('hid-device-added FIRED WITH', device)
//Optionally update details.deviceList
})
mainWindow.webContents.session.on('hid-device-removed', (event, device) => {
mainWindow.webContents.session.on('hid-device-removed', (event, device) => {
console.log('hid-device-removed FIRED WITH', device)
//Optionally update details.deviceList
})
@@ -37,13 +37,13 @@ function createWindow () {
return true
}
})
mainWindow.loadFile('index.html')
}
app.whenReady().then(() => {
createWindow()
app.on('activate', function () {
if (BrowserWindow.getAllWindows().length === 0) createWindow()
})

View File

@@ -6,7 +6,7 @@ function createWindow () {
width: 800,
height: 600
})
mainWindow.webContents.session.on('select-serial-port', (event, portList, webContents, callback) => {
//Add listeners to handle ports being added or removed before the callback for `select-serial-port`
@@ -15,7 +15,7 @@ function createWindow () {
console.log('serial-port-added FIRED WITH', port)
//Optionally update portList to add the new port
})
mainWindow.webContents.session.on('serial-port-removed', (event, port) => {
console.log('serial-port-removed FIRED WITH', port)
//Optionally update portList to remove the port
@@ -33,7 +33,7 @@ function createWindow () {
if (permission === 'serial' && details.securityOrigin === 'file:///') {
return true
}
return false
})
@@ -41,10 +41,10 @@ function createWindow () {
if (details.deviceType === 'serial' && details.origin === 'file://') {
return true
}
return false
})
mainWindow.loadFile('index.html')
mainWindow.webContents.openDevTools()
@@ -52,7 +52,7 @@ function createWindow () {
app.whenReady().then(() => {
createWindow()
app.on('activate', function () {
if (BrowserWindow.getAllWindows().length === 0) createWindow()
})

View File

@@ -12,7 +12,7 @@
<h3>USB devices automatically granted access via <i>setDevicePermissionHandler</i></h3>
<div id="granted-devices"></div>
<h3>USB devices automatically granted access via <i>select-usb-device</i></h3>
<div id="granted-devices2"></div>

View File

@@ -7,17 +7,17 @@ function createWindow () {
width: 800,
height: 600
})
let grantedDeviceThroughPermHandler
mainWindow.webContents.session.on('select-usb-device', (event, details, callback) => {
//Add events to handle devices being added or removed before the callback on
//`select-usb-device` is called.
mainWindow.webContents.session.on('usb-device-added', (event, device) => {
mainWindow.webContents.session.on('usb-device-added', (event, device) => {
console.log('usb-device-added FIRED WITH', device)
//Optionally update details.deviceList
})
mainWindow.webContents.session.on('usb-device-removed', (event, device) => {
console.log('usb-device-removed FIRED WITH', device)
//Optionally update details.deviceList
@@ -31,7 +31,7 @@ function createWindow () {
}
})
if (deviceToReturn) {
callback(deviceToReturn.deviceId)
callback(deviceToReturn.deviceId)
} else {
callback()
}
@@ -44,10 +44,10 @@ function createWindow () {
}
})
mainWindow.webContents.session.setDevicePermissionHandler((details) => {
if (details.deviceType === 'usb' && details.origin === 'file://') {
if (!grantedDeviceThroughPermHandler) {
if (!grantedDeviceThroughPermHandler) {
grantedDeviceThroughPermHandler = details.device
return true
} else {
@@ -55,13 +55,13 @@ function createWindow () {
}
}
})
mainWindow.loadFile('index.html')
}
app.whenReady().then(() => {
createWindow()
app.on('activate', function () {
if (BrowserWindow.getAllWindows().length === 0) createWindow()
})

View File

@@ -6,10 +6,10 @@ async function testIt() {
const noDevicesFoundMsg = 'No devices found'
const grantedDevices = await navigator.usb.getDevices()
let grantedDeviceList = ''
if (grantedDevices.length > 0) {
if (grantedDevices.length > 0) {
grantedDevices.forEach(device => {
grantedDeviceList += `<hr>${getDeviceDetails(device)}</hr>`
})
})
} else {
grantedDeviceList = noDevicesFoundMsg
}
@@ -21,7 +21,7 @@ async function testIt() {
filters: []
})
grantedDeviceList += `<hr>${getDeviceDetails(device)}</hr>`
} catch (ex) {
if (ex.name === 'NotFoundError') {
grantedDeviceList = noDevicesFoundMsg

View File

@@ -19,7 +19,7 @@ function createWindow () {
app.whenReady().then(() => {
createWindow()
app.on('activate', function () {
if (BrowserWindow.getAllWindows().length === 0) createWindow()
})

View File

@@ -37,7 +37,7 @@ app.whenReady().then(() => {
console.log(value) // will print value to Node console
})
createWindow()
app.on('activate', function () {
if (BrowserWindow.getAllWindows().length === 0) createWindow()
})

View File

@@ -28,7 +28,7 @@
const exLinksBtn = document.getElementById('open-ex-links')
exLinksBtn.addEventListener('click', (event) => {
shell.openExternal('https://electronjs.org')
})
})
</code></pre>
<div class="demo-protip">

View File

@@ -6,7 +6,7 @@
</head>
<body>
<div>
<h1>
<h1>
Open external links and the file manager
</h1>
<h3>

View File

@@ -14,7 +14,7 @@
<p>
Electron conveniently allows developers to send notifications with the
<a href="https://notifications.spec.whatwg.org/">HTML5 Notification API</a>,
<a href="https://notifications.spec.whatwg.org/">HTML5 Notification API</a>,
using the currently running operating systems native notification
APIs to display it.
</p>

View File

@@ -2,12 +2,13 @@
<html>
<head>
<meta charset="UTF-8">
<meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline';" />
</head>
<body>
<div>
<div>
<h1>Clipboard copy</h1>
<i>Supports: Win, macOS, Linux <span>|</span> Process: Both</i>
<i>Supports: Win, macOS, Linux <span>|</span> Process: Main, Renderer (non-sandboxed only)</i>
<div>
<div>
<button id="copy-to">Copy</button>
@@ -17,8 +18,6 @@
</div>
</div>
</div>
<script src="./renderer.js"></script>
</body>
<script>
require('./renderer.js')
</script>
</html>

View File

@@ -1,4 +1,5 @@
const { app, BrowserWindow } = require('electron')
const { app, BrowserWindow, ipcMain, clipboard } = require('electron')
const path = require('path')
let mainWindow = null
@@ -8,7 +9,7 @@ function createWindow () {
height: 400,
title: 'Clipboard copy',
webPreferences: {
nodeIntegration: true
preload: path.join(__dirname, 'preload.js')
}
}
@@ -20,6 +21,18 @@ function createWindow () {
})
}
ipcMain.handle('clipboard:writeText', (event, text) => {
clipboard.writeText(text)
})
app.whenReady().then(() => {
createWindow()
app.on('activate', function () {
if (BrowserWindow.getAllWindows().length === 0) createWindow()
})
})
app.on('window-all-closed', function () {
if (process.platform !== 'darwin') app.quit()
})

View File

@@ -0,0 +1,5 @@
const { contextBridge, ipcRenderer } = require('electron')
contextBridge.exposeInMainWorld('clipboard', {
writeText: (text) => ipcRenderer.invoke('clipboard:writeText', text)
})

View File

@@ -1,5 +1,3 @@
const { clipboard } = require('electron')
const copyBtn = document.getElementById('copy-to')
const copyInput = document.getElementById('copy-to-input')

View File

@@ -2,12 +2,13 @@
<html>
<head>
<meta charset="UTF-8">
<meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline';" />
</head>
<body>
<div>
<div>
<h1>Clipboard paste</h1>
<i>Supports: Win, macOS, Linux <span>|</span> Process: Both</i>
<i>Supports: Win, macOS, Linux <span>|</span> Process: Main, Renderer (non-sandboxed only)</i>
<div>
<div>
<button id="paste-to">Paste</button>
@@ -17,8 +18,6 @@
</div>
</div>
</div>
<script src="./renderer.js"></script>
</body>
<script>
require('./renderer.js')
</script>
</html>

View File

@@ -1,4 +1,5 @@
const { app, BrowserWindow } = require('electron')
const { app, BrowserWindow, ipcMain, clipboard } = require('electron')
const path = require('path')
let mainWindow = null
@@ -8,7 +9,7 @@ function createWindow () {
height: 400,
title: 'Clipboard paste',
webPreferences: {
nodeIntegration: true
preload: path.join(__dirname, 'preload.js')
}
}
@@ -20,6 +21,22 @@ function createWindow () {
})
}
ipcMain.handle('clipboard:readText', () => {
return clipboard.readText()
})
ipcMain.handle('clipboard:writeText', (event, text) => {
clipboard.writeText(text)
})
app.whenReady().then(() => {
createWindow()
app.on('activate', function () {
if (BrowserWindow.getAllWindows().length === 0) createWindow()
})
})
app.on('window-all-closed', function () {
if (process.platform !== 'darwin') app.quit()
})

View File

@@ -0,0 +1,6 @@
const { contextBridge, ipcRenderer } = require('electron')
contextBridge.exposeInMainWorld('clipboard', {
readText: () => ipcRenderer.invoke('clipboard:readText'),
writeText: (text) => ipcRenderer.invoke('clipboard:writeText', text)
})

View File

@@ -1,9 +1,7 @@
const { clipboard } = require('electron')
const pasteBtn = document.getElementById('paste-to')
pasteBtn.addEventListener('click', () => {
clipboard.writeText('What a demo!')
const message = `Clipboard contents: ${clipboard.readText()}`
pasteBtn.addEventListener('click', async () => {
await clipboard.writeText('What a demo!')
const message = `Clipboard contents: ${await clipboard.readText()}`
document.getElementById('paste-from').innerHTML = message
})

View File

@@ -23,13 +23,15 @@ if (!gotTheLock) {
if (mainWindow.isMinimized()) mainWindow.restore()
mainWindow.focus()
}
dialog.showErrorBox('Welcome Back', `You arrived from: ${commandLine.pop().slice(0,-1)}`)
})
// Create mainWindow, load the rest of the app, etc...
app.whenReady().then(() => {
createWindow()
})
app.on('open-url', (event, url) => {
dialog.showErrorBox('Welcome Back', `You arrived from: ${url}`)
})

View File

@@ -23,4 +23,4 @@
require('./renderer.js')
</script>
</body>
</html>
</html>

View File

@@ -10,7 +10,7 @@
<i>Supports: Win, macOS, Linux <span>|</span> Process: Main</i>
<div>
<p>A frameless window is a window that has no <i>"chrome"</i>,
such as toolbars, title bars, status bars, borders, etc. You can make
such as toolbars, title bars, status bars, borders, etc. You can make
a browser window frameless by setting
<code>frame</code> to <code>false</code> when creating the window.</p>
<div>

View File

@@ -61,7 +61,7 @@ const createWindow = () => {
In this next step, we will create our `BrowserWindow` and tell our application how to handle an event in which an external protocol is clicked.
This code will be different in Windows compared to MacOS and Linux. This is due to Windows requiring additional code in order to open the contents of the protocol link within the same Electron instance. Read more about this [here](https://www.electronjs.org/docs/api/app#apprequestsingleinstancelock).
This code will be different in Windows compared to MacOS and Linux. This is due to Windows requiring additional code in order to open the contents of the protocol link within the same Electron instance. Read more about this [here](../api/app.md#apprequestsingleinstancelockadditionaldata).
#### Windows code:
@@ -77,17 +77,15 @@ if (!gotTheLock) {
if (mainWindow.isMinimized()) mainWindow.restore()
mainWindow.focus()
}
// the commandLine is array of strings in which last element is deep link url
// the url str ends with /
dialog.showErrorBox('Welcome Back', `You arrived from: ${commandLine.pop().slice(0, -1)}`)
})
// Create mainWindow, load the rest of the app, etc...
app.whenReady().then(() => {
createWindow()
})
// Handle the protocol. In this case, we choose to show an Error Box.
app.on('open-url', (event, url) => {
dialog.showErrorBox('Welcome Back', `You arrived from: ${url}`)
})
}
```

View File

@@ -35,9 +35,15 @@ filenames = {
"shell/browser/relauncher_linux.cc",
"shell/browser/ui/electron_desktop_window_tree_host_linux.cc",
"shell/browser/ui/file_dialog_gtk.cc",
"shell/browser/ui/gtk/menu_gtk.cc",
"shell/browser/ui/gtk/menu_gtk.h",
"shell/browser/ui/gtk/menu_util.cc",
"shell/browser/ui/gtk/menu_util.h",
"shell/browser/ui/message_box_gtk.cc",
"shell/browser/ui/tray_icon_gtk.cc",
"shell/browser/ui/tray_icon_gtk.h",
"shell/browser/ui/status_icon_gtk.cc",
"shell/browser/ui/status_icon_gtk.h",
"shell/browser/ui/tray_icon_linux.cc",
"shell/browser/ui/tray_icon_linux.h",
"shell/browser/ui/views/client_frame_view_linux.cc",
"shell/browser/ui/views/client_frame_view_linux.h",
"shell/common/application_info_linux.cc",

View File

@@ -9,6 +9,7 @@ export const webViewEvents: Record<string, readonly string[]> = {
'dom-ready': [],
'console-message': ['level', 'message', 'line', 'sourceId'],
'context-menu': ['params'],
'devtools-open-url': ['url'],
'devtools-opened': [],
'devtools-closed': [],
'devtools-focused': [],

View File

@@ -1,5 +1,5 @@
import type { WebViewImpl } from '@electron/internal/renderer/web-view/web-view-impl';
import { WEB_VIEW_CONSTANTS } from '@electron/internal/renderer/web-view/web-view-constants';
import { WEB_VIEW_ATTRIBUTES, WEB_VIEW_ERROR_MESSAGES } from '@electron/internal/renderer/web-view/web-view-constants';
const resolveURL = function (url?: string | null) {
return url ? new URL(url, location.href).href : '';
@@ -76,7 +76,7 @@ export class PartitionAttribute extends WebViewAttribute {
public validPartitionId = true
constructor (public webViewImpl: WebViewImpl) {
super(WEB_VIEW_CONSTANTS.ATTRIBUTE_PARTITION, webViewImpl);
super(WEB_VIEW_ATTRIBUTES.PARTITION, webViewImpl);
}
public handleMutation = (oldValue: any, newValue: any) => {
@@ -84,13 +84,13 @@ export class PartitionAttribute extends WebViewAttribute {
// The partition cannot change if the webview has already navigated.
if (!this.webViewImpl.beforeFirstNavigation) {
console.error(WEB_VIEW_CONSTANTS.ERROR_MSG_ALREADY_NAVIGATED);
console.error(WEB_VIEW_ERROR_MESSAGES.ALREADY_NAVIGATED);
this.setValueIgnoreMutation(oldValue);
return;
}
if (newValue === 'persist:') {
this.validPartitionId = false;
console.error(WEB_VIEW_CONSTANTS.ERROR_MSG_INVALID_PARTITION_ATTRIBUTE);
console.error(WEB_VIEW_ERROR_MESSAGES.INVALID_PARTITION_ATTRIBUTE);
}
}
}
@@ -100,7 +100,7 @@ export class SrcAttribute extends WebViewAttribute {
public observer!: MutationObserver;
constructor (public webViewImpl: WebViewImpl) {
super(WEB_VIEW_CONSTANTS.ATTRIBUTE_SRC, webViewImpl);
super(WEB_VIEW_ATTRIBUTES.SRC, webViewImpl);
this.setupMutationObserver();
}
@@ -162,7 +162,7 @@ export class SrcAttribute extends WebViewAttribute {
}
public parse () {
if (!this.webViewImpl.elementAttached || !(this.webViewImpl.attributes.get(WEB_VIEW_CONSTANTS.ATTRIBUTE_PARTITION) as PartitionAttribute).validPartitionId || !this.getValue()) {
if (!this.webViewImpl.elementAttached || !(this.webViewImpl.attributes.get(WEB_VIEW_ATTRIBUTES.PARTITION) as PartitionAttribute).validPartitionId || !this.getValue()) {
return;
}
if (this.webViewImpl.guestInstanceId == null) {
@@ -176,12 +176,12 @@ export class SrcAttribute extends WebViewAttribute {
// Navigate to |this.src|.
const opts: Record<string, string> = {};
const httpreferrer = this.webViewImpl.attributes.get(WEB_VIEW_CONSTANTS.ATTRIBUTE_HTTPREFERRER)!.getValue();
const httpreferrer = this.webViewImpl.attributes.get(WEB_VIEW_ATTRIBUTES.HTTPREFERRER)!.getValue();
if (httpreferrer) {
opts.httpReferrer = httpreferrer;
}
const useragent = this.webViewImpl.attributes.get(WEB_VIEW_CONSTANTS.ATTRIBUTE_USERAGENT)!.getValue();
const useragent = this.webViewImpl.attributes.get(WEB_VIEW_ATTRIBUTES.USERAGENT)!.getValue();
if (useragent) {
opts.userAgent = useragent;
}
@@ -196,21 +196,21 @@ export class SrcAttribute extends WebViewAttribute {
// Attribute specifies HTTP referrer.
class HttpReferrerAttribute extends WebViewAttribute {
constructor (webViewImpl: WebViewImpl) {
super(WEB_VIEW_CONSTANTS.ATTRIBUTE_HTTPREFERRER, webViewImpl);
super(WEB_VIEW_ATTRIBUTES.HTTPREFERRER, webViewImpl);
}
}
// Attribute specifies user agent
class UserAgentAttribute extends WebViewAttribute {
constructor (webViewImpl: WebViewImpl) {
super(WEB_VIEW_CONSTANTS.ATTRIBUTE_USERAGENT, webViewImpl);
super(WEB_VIEW_ATTRIBUTES.USERAGENT, webViewImpl);
}
}
// Attribute that set preload script.
class PreloadAttribute extends WebViewAttribute {
constructor (webViewImpl: WebViewImpl) {
super(WEB_VIEW_CONSTANTS.ATTRIBUTE_PRELOAD, webViewImpl);
super(WEB_VIEW_ATTRIBUTES.PRELOAD, webViewImpl);
}
public getValue () {
@@ -222,7 +222,7 @@ class PreloadAttribute extends WebViewAttribute {
const protocol = preload.substr(0, 5);
if (protocol !== 'file:') {
console.error(WEB_VIEW_CONSTANTS.ERROR_MSG_INVALID_PRELOAD_ATTRIBUTE);
console.error(WEB_VIEW_ERROR_MESSAGES.INVALID_PRELOAD_ATTRIBUTE);
preload = '';
}
@@ -233,39 +233,39 @@ class PreloadAttribute extends WebViewAttribute {
// Attribute that specifies the blink features to be enabled.
class BlinkFeaturesAttribute extends WebViewAttribute {
constructor (webViewImpl: WebViewImpl) {
super(WEB_VIEW_CONSTANTS.ATTRIBUTE_BLINKFEATURES, webViewImpl);
super(WEB_VIEW_ATTRIBUTES.BLINKFEATURES, webViewImpl);
}
}
// Attribute that specifies the blink features to be disabled.
class DisableBlinkFeaturesAttribute extends WebViewAttribute {
constructor (webViewImpl: WebViewImpl) {
super(WEB_VIEW_CONSTANTS.ATTRIBUTE_DISABLEBLINKFEATURES, webViewImpl);
super(WEB_VIEW_ATTRIBUTES.DISABLEBLINKFEATURES, webViewImpl);
}
}
// Attribute that specifies the web preferences to be enabled.
class WebPreferencesAttribute extends WebViewAttribute {
constructor (webViewImpl: WebViewImpl) {
super(WEB_VIEW_CONSTANTS.ATTRIBUTE_WEBPREFERENCES, webViewImpl);
super(WEB_VIEW_ATTRIBUTES.WEBPREFERENCES, webViewImpl);
}
}
// Sets up all of the webview attributes.
export function setupWebViewAttributes (self: WebViewImpl) {
return new Map<string, WebViewAttribute>([
[WEB_VIEW_CONSTANTS.ATTRIBUTE_PARTITION, new PartitionAttribute(self)],
[WEB_VIEW_CONSTANTS.ATTRIBUTE_SRC, new SrcAttribute(self)],
[WEB_VIEW_CONSTANTS.ATTRIBUTE_HTTPREFERRER, new HttpReferrerAttribute(self)],
[WEB_VIEW_CONSTANTS.ATTRIBUTE_USERAGENT, new UserAgentAttribute(self)],
[WEB_VIEW_CONSTANTS.ATTRIBUTE_NODEINTEGRATION, new BooleanAttribute(WEB_VIEW_CONSTANTS.ATTRIBUTE_NODEINTEGRATION, self)],
[WEB_VIEW_CONSTANTS.ATTRIBUTE_NODEINTEGRATIONINSUBFRAMES, new BooleanAttribute(WEB_VIEW_CONSTANTS.ATTRIBUTE_NODEINTEGRATIONINSUBFRAMES, self)],
[WEB_VIEW_CONSTANTS.ATTRIBUTE_PLUGINS, new BooleanAttribute(WEB_VIEW_CONSTANTS.ATTRIBUTE_PLUGINS, self)],
[WEB_VIEW_CONSTANTS.ATTRIBUTE_DISABLEWEBSECURITY, new BooleanAttribute(WEB_VIEW_CONSTANTS.ATTRIBUTE_DISABLEWEBSECURITY, self)],
[WEB_VIEW_CONSTANTS.ATTRIBUTE_ALLOWPOPUPS, new BooleanAttribute(WEB_VIEW_CONSTANTS.ATTRIBUTE_ALLOWPOPUPS, self)],
[WEB_VIEW_CONSTANTS.ATTRIBUTE_PRELOAD, new PreloadAttribute(self)],
[WEB_VIEW_CONSTANTS.ATTRIBUTE_BLINKFEATURES, new BlinkFeaturesAttribute(self)],
[WEB_VIEW_CONSTANTS.ATTRIBUTE_DISABLEBLINKFEATURES, new DisableBlinkFeaturesAttribute(self)],
[WEB_VIEW_CONSTANTS.ATTRIBUTE_WEBPREFERENCES, new WebPreferencesAttribute(self)]
[WEB_VIEW_ATTRIBUTES.PARTITION, new PartitionAttribute(self)],
[WEB_VIEW_ATTRIBUTES.SRC, new SrcAttribute(self)],
[WEB_VIEW_ATTRIBUTES.HTTPREFERRER, new HttpReferrerAttribute(self)],
[WEB_VIEW_ATTRIBUTES.USERAGENT, new UserAgentAttribute(self)],
[WEB_VIEW_ATTRIBUTES.NODEINTEGRATION, new BooleanAttribute(WEB_VIEW_ATTRIBUTES.NODEINTEGRATION, self)],
[WEB_VIEW_ATTRIBUTES.NODEINTEGRATIONINSUBFRAMES, new BooleanAttribute(WEB_VIEW_ATTRIBUTES.NODEINTEGRATIONINSUBFRAMES, self)],
[WEB_VIEW_ATTRIBUTES.PLUGINS, new BooleanAttribute(WEB_VIEW_ATTRIBUTES.PLUGINS, self)],
[WEB_VIEW_ATTRIBUTES.DISABLEWEBSECURITY, new BooleanAttribute(WEB_VIEW_ATTRIBUTES.DISABLEWEBSECURITY, self)],
[WEB_VIEW_ATTRIBUTES.ALLOWPOPUPS, new BooleanAttribute(WEB_VIEW_ATTRIBUTES.ALLOWPOPUPS, self)],
[WEB_VIEW_ATTRIBUTES.PRELOAD, new PreloadAttribute(self)],
[WEB_VIEW_ATTRIBUTES.BLINKFEATURES, new BlinkFeaturesAttribute(self)],
[WEB_VIEW_ATTRIBUTES.DISABLEBLINKFEATURES, new DisableBlinkFeaturesAttribute(self)],
[WEB_VIEW_ATTRIBUTES.WEBPREFERENCES, new WebPreferencesAttribute(self)]
]);
}

View File

@@ -1,23 +1,24 @@
export const enum WEB_VIEW_CONSTANTS {
// Attributes.
ATTRIBUTE_NAME = 'name',
ATTRIBUTE_PARTITION = 'partition',
ATTRIBUTE_SRC = 'src',
ATTRIBUTE_HTTPREFERRER = 'httpreferrer',
ATTRIBUTE_NODEINTEGRATION = 'nodeintegration',
ATTRIBUTE_NODEINTEGRATIONINSUBFRAMES = 'nodeintegrationinsubframes',
ATTRIBUTE_PLUGINS = 'plugins',
ATTRIBUTE_DISABLEWEBSECURITY = 'disablewebsecurity',
ATTRIBUTE_ALLOWPOPUPS = 'allowpopups',
ATTRIBUTE_PRELOAD = 'preload',
ATTRIBUTE_USERAGENT = 'useragent',
ATTRIBUTE_BLINKFEATURES = 'blinkfeatures',
ATTRIBUTE_DISABLEBLINKFEATURES = 'disableblinkfeatures',
ATTRIBUTE_WEBPREFERENCES = 'webpreferences',
// Error messages.
ERROR_MSG_ALREADY_NAVIGATED = 'The object has already navigated, so its partition cannot be changed.',
ERROR_MSG_INVALID_PARTITION_ATTRIBUTE = 'Invalid partition attribute.',
ERROR_MSG_INVALID_PRELOAD_ATTRIBUTE = 'Only "file:" protocol is supported in "preload" attribute.',
ERROR_MSG_NOT_ATTACHED = 'The WebView must be attached to the DOM and the dom-ready event emitted before this method can be called.'
export const enum WEB_VIEW_ATTRIBUTES {
NAME = 'name',
PARTITION = 'partition',
SRC = 'src',
HTTPREFERRER = 'httpreferrer',
NODEINTEGRATION = 'nodeintegration',
NODEINTEGRATIONINSUBFRAMES = 'nodeintegrationinsubframes',
PLUGINS = 'plugins',
DISABLEWEBSECURITY = 'disablewebsecurity',
ALLOWPOPUPS = 'allowpopups',
PRELOAD = 'preload',
USERAGENT = 'useragent',
BLINKFEATURES = 'blinkfeatures',
DISABLEBLINKFEATURES = 'disableblinkfeatures',
WEBPREFERENCES = 'webpreferences',
}
export const enum WEB_VIEW_ERROR_MESSAGES {
// Error messages.
ALREADY_NAVIGATED = 'The object has already navigated, so its partition cannot be changed.',
INVALID_PARTITION_ATTRIBUTE = 'Invalid partition attribute.',
INVALID_PRELOAD_ATTRIBUTE = 'Only "file:" protocol is supported in "preload" attribute.',
NOT_ATTACHED = 'The WebView must be attached to the DOM and the dom-ready event emitted before this method can be called.'
}

View File

@@ -8,7 +8,7 @@
// which runs in browserify environment instead of Node environment, all native
// modules must be passed from outside, all included files must be plain JS.
import { WEB_VIEW_CONSTANTS } from '@electron/internal/renderer/web-view/web-view-constants';
import { WEB_VIEW_ATTRIBUTES, WEB_VIEW_ERROR_MESSAGES } from '@electron/internal/renderer/web-view/web-view-constants';
import { WebViewImpl, WebViewImplHooks, setupMethods } from '@electron/internal/renderer/web-view/web-view-impl';
import type { SrcAttribute } from '@electron/internal/renderer/web-view/web-view-attributes';
@@ -19,19 +19,19 @@ const defineWebViewElement = (hooks: WebViewImplHooks) => {
return class WebViewElement extends HTMLElement {
static get observedAttributes () {
return [
WEB_VIEW_CONSTANTS.ATTRIBUTE_PARTITION,
WEB_VIEW_CONSTANTS.ATTRIBUTE_SRC,
WEB_VIEW_CONSTANTS.ATTRIBUTE_HTTPREFERRER,
WEB_VIEW_CONSTANTS.ATTRIBUTE_USERAGENT,
WEB_VIEW_CONSTANTS.ATTRIBUTE_NODEINTEGRATION,
WEB_VIEW_CONSTANTS.ATTRIBUTE_NODEINTEGRATIONINSUBFRAMES,
WEB_VIEW_CONSTANTS.ATTRIBUTE_PLUGINS,
WEB_VIEW_CONSTANTS.ATTRIBUTE_DISABLEWEBSECURITY,
WEB_VIEW_CONSTANTS.ATTRIBUTE_ALLOWPOPUPS,
WEB_VIEW_CONSTANTS.ATTRIBUTE_PRELOAD,
WEB_VIEW_CONSTANTS.ATTRIBUTE_BLINKFEATURES,
WEB_VIEW_CONSTANTS.ATTRIBUTE_DISABLEBLINKFEATURES,
WEB_VIEW_CONSTANTS.ATTRIBUTE_WEBPREFERENCES
WEB_VIEW_ATTRIBUTES.PARTITION,
WEB_VIEW_ATTRIBUTES.SRC,
WEB_VIEW_ATTRIBUTES.HTTPREFERRER,
WEB_VIEW_ATTRIBUTES.USERAGENT,
WEB_VIEW_ATTRIBUTES.NODEINTEGRATION,
WEB_VIEW_ATTRIBUTES.NODEINTEGRATIONINSUBFRAMES,
WEB_VIEW_ATTRIBUTES.PLUGINS,
WEB_VIEW_ATTRIBUTES.DISABLEWEBSECURITY,
WEB_VIEW_ATTRIBUTES.ALLOWPOPUPS,
WEB_VIEW_ATTRIBUTES.PRELOAD,
WEB_VIEW_ATTRIBUTES.BLINKFEATURES,
WEB_VIEW_ATTRIBUTES.DISABLEBLINKFEATURES,
WEB_VIEW_ATTRIBUTES.WEBPREFERENCES
];
}
@@ -43,7 +43,7 @@ const defineWebViewElement = (hooks: WebViewImplHooks) => {
getWebContentsId () {
const internal = internals.get(this);
if (!internal || !internal.guestInstanceId) {
throw new Error(WEB_VIEW_CONSTANTS.ERROR_MSG_NOT_ATTACHED);
throw new Error(WEB_VIEW_ERROR_MESSAGES.NOT_ATTACHED);
}
return internal.guestInstanceId;
}
@@ -58,7 +58,7 @@ const defineWebViewElement = (hooks: WebViewImplHooks) => {
dispatchEvent: internal.dispatchEvent.bind(internal)
});
internal.elementAttached = true;
(internal.attributes.get(WEB_VIEW_CONSTANTS.ATTRIBUTE_SRC) as SrcAttribute).parse();
(internal.attributes.get(WEB_VIEW_ATTRIBUTES.SRC) as SrcAttribute).parse();
}
}

View File

@@ -1,5 +1,5 @@
import type * as guestViewInternalModule from '@electron/internal/renderer/web-view/guest-view-internal';
import { WEB_VIEW_CONSTANTS } from '@electron/internal/renderer/web-view/web-view-constants';
import { WEB_VIEW_ATTRIBUTES } from '@electron/internal/renderer/web-view/web-view-constants';
import { syncMethods, asyncMethods, properties } from '@electron/internal/common/web-view-methods';
import type { WebViewAttribute, PartitionAttribute } from '@electron/internal/renderer/web-view/web-view-attributes';
import { setupWebViewAttributes } from '@electron/internal/renderer/web-view/web-view-attributes';
@@ -75,7 +75,7 @@ export class WebViewImpl {
}
this.beforeFirstNavigation = true;
(this.attributes.get(WEB_VIEW_CONSTANTS.ATTRIBUTE_PARTITION) as PartitionAttribute).validPartitionId = true;
(this.attributes.get(WEB_VIEW_ATTRIBUTES.PARTITION) as PartitionAttribute).validPartitionId = true;
// Since attachment swaps a local frame for a remote frame, we need our
// internal iframe element to be local again before we can reattach.
@@ -145,13 +145,13 @@ export class WebViewImpl {
// Updates state upon loadcommit.
onLoadCommit (props: Record<string, any>) {
const oldValue = this.webviewNode.getAttribute(WEB_VIEW_CONSTANTS.ATTRIBUTE_SRC);
const oldValue = this.webviewNode.getAttribute(WEB_VIEW_ATTRIBUTES.SRC);
const newValue = props.url;
if (props.isMainFrame && (oldValue !== newValue)) {
// Touching the src attribute triggers a navigation. To avoid
// triggering a page reload on every guest-initiated navigation,
// we do not handle this mutation.
this.attributes.get(WEB_VIEW_CONSTANTS.ATTRIBUTE_SRC)!.setValueIgnoreMutation(newValue);
this.attributes.get(WEB_VIEW_ATTRIBUTES.SRC)!.setValueIgnoreMutation(newValue);
}
}
@@ -165,7 +165,7 @@ export class WebViewImpl {
}
onAttach (storagePartitionId: number) {
return this.attributes.get(WEB_VIEW_CONSTANTS.ATTRIBUTE_PARTITION)!.setValue(storagePartitionId);
return this.attributes.get(WEB_VIEW_ATTRIBUTES.PARTITION)!.setValue(storagePartitionId);
}
buildParams () {

View File

@@ -5,6 +5,7 @@
"description": "Build cross platform desktop apps with JavaScript, HTML, and CSS",
"devDependencies": {
"@azure/storage-blob": "^12.9.0",
"@dsanders11/vscode-markdown-languageservice": "^0.3.0-alpha.4",
"@electron/asar": "^3.2.1",
"@electron/docs-parser": "^1.0.0",
"@electron/fiddle-core": "^1.0.4",
@@ -38,7 +39,7 @@
"check-for-leaks": "^1.2.1",
"colors": "1.4.0",
"dotenv-safe": "^4.0.4",
"dugite": "^1.103.0",
"dugite": "^2.3.0",
"eslint": "^7.4.0",
"eslint-config-standard": "^14.1.1",
"eslint-plugin-import": "^2.22.0",
@@ -56,6 +57,7 @@
"lint": "^1.1.2",
"lint-staged": "^10.2.11",
"markdownlint-cli": "^0.33.0",
"mdast-util-from-markdown": "^1.2.0",
"minimist": "^1.2.6",
"null-loader": "^4.0.0",
"pre-flight": "^1.1.0",
@@ -72,6 +74,10 @@
"ts-loader": "^8.0.2",
"ts-node": "6.2.0",
"typescript": "^4.5.5",
"unist-util-visit": "^4.1.1",
"vscode-languageserver": "^8.0.2",
"vscode-languageserver-textdocument": "^1.0.7",
"vscode-uri": "^3.0.6",
"webpack": "^5.73.0",
"webpack-cli": "^4.10.0",
"wrapper-webpack-plugin": "^2.2.0"
@@ -89,7 +95,7 @@
"lint:py": "node ./script/lint.js --py",
"lint:gn": "node ./script/lint.js --gn",
"lint:docs": "remark docs -qf && npm run lint:js-in-markdown && npm run create-typescript-definitions && npm run lint:docs-relative-links && npm run lint:markdownlint",
"lint:docs-relative-links": "python3 ./script/check-relative-doc-links.py",
"lint:docs-relative-links": "ts-node script/lint-docs-links.ts",
"lint:markdownlint": "markdownlint -r ./script/markdownlint-emd001.js \"*.md\" \"docs/**/*.md\"",
"lint:js-in-markdown": "standard-markdown docs",
"create-api-json": "node script/create-api-json.js",

View File

@@ -78,7 +78,7 @@ index 796c7f06fa6063ac409f3fef53871e18d4c07838..6575e833388bcc3ac487a409027d984b
: PdfRenderSettings::Mode::POSTSCRIPT_LEVEL3;
}
diff --git a/chrome/browser/printing/print_view_manager_base.cc b/chrome/browser/printing/print_view_manager_base.cc
index 017e421d0ca3e6154b849373abbcb8d75b369e60..463f743af273b0f2f5afe6904ed77e7e99a91f46 100644
index 017e421d0ca3e6154b849373abbcb8d75b369e60..aaadfba1735b21e17b66e8efe69f8a5ab4a312b0 100644
--- a/chrome/browser/printing/print_view_manager_base.cc
+++ b/chrome/browser/printing/print_view_manager_base.cc
@@ -29,8 +29,6 @@
@@ -264,6 +264,15 @@ index 017e421d0ca3e6154b849373abbcb8d75b369e60..463f743af273b0f2f5afe6904ed77e7e
auto callback_wrapper =
base::BindOnce(&PrintViewManagerBase::UpdatePrintSettingsReply,
@@ -630,7 +664,7 @@ void PrintViewManagerBase::UpdatePrintSettings(
void PrintViewManagerBase::IsPrintingEnabled(
IsPrintingEnabledCallback callback) {
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
- std::move(callback).Run(printing_enabled_.GetValue());
+ std::move(callback).Run(true);
}
void PrintViewManagerBase::ScriptedPrint(mojom::ScriptedPrintParamsPtr params,
@@ -646,14 +680,14 @@ void PrintViewManagerBase::ScriptedPrint(mojom::ScriptedPrintParamsPtr params,
// didn't happen for some reason.
bad_message::ReceivedBadMessage(

View File

@@ -51,7 +51,7 @@ index 7cec4e9a3e3675ba75d66a44ed4e142d13ca1821..0c7aad193442a7e5cab62638441969a7
}
}
diff --git a/lib/internal/modules/esm/translators.js b/lib/internal/modules/esm/translators.js
index 6f25b2e67ab77613c6ed63c227bb875d5461f45f..d1527b859bbea15fdf30622fc8f2700bde5b4591 100644
index 6f25b2e67ab77613c6ed63c227bb875d5461f45f..010fa8f78a21a8146879849e2e887332e2694e51 100644
--- a/lib/internal/modules/esm/translators.js
+++ b/lib/internal/modules/esm/translators.js
@@ -154,7 +154,7 @@ translators.set('commonjs', async function commonjsStrategy(url, source,
@@ -63,15 +63,19 @@ index 6f25b2e67ab77613c6ed63c227bb875d5461f45f..d1527b859bbea15fdf30622fc8f2700b
[...exportNames] : ['default', ...exportNames];
return new ModuleWrap(url, undefined, namesWithDefault, function() {
@@ -173,7 +173,7 @@ translators.set('commonjs', async function commonjsStrategy(url, source,
@@ -173,9 +173,9 @@ translators.set('commonjs', async function commonjsStrategy(url, source,
}
}
- for (const exportName of exportNames) {
- if (!ObjectPrototypeHasOwnProperty(exports, exportName) ||
- exportName === 'default')
+ for (const exportName of namesWithDefault) {
if (!ObjectPrototypeHasOwnProperty(exports, exportName) ||
exportName === 'default')
+ if (exportName === 'default' ||
+ !ObjectPrototypeHasOwnProperty(exports, exportName))
continue;
// We might trigger a getter -> dont fail.
let value;
diff --git a/lib/internal/url.js b/lib/internal/url.js
index 40b25f6890b5db721923ba2e9cc351e514ca22bc..288f3253b4c686d1b061dfcdf18dc95794943d87 100644
--- a/lib/internal/url.js

View File

@@ -7,7 +7,7 @@ Wc++98-compat-extra-semi is turned on for Electron so this
patch fixes that error in node.
diff --git a/src/node_serdes.cc b/src/node_serdes.cc
index 0cd76078218433b46c17f350e3ba6073987438cf..ba13061b6aa7fd8f877aa456db9d352a847e682a 100644
index 97917c91c06dc47dfa6be2c194944cdc93e6bd7f..177390a24eb6490b128e22c104014e80f338c9d9 100644
--- a/src/node_serdes.cc
+++ b/src/node_serdes.cc
@@ -32,7 +32,7 @@ namespace serdes {

View File

@@ -155,7 +155,7 @@ index efbdbeabf5a6afb658cbdc7888f94952e55f4f71..8b37639361e8902d7e1481071d3ec24b
// Delegate to V8's allocator for compatibility with the V8 memory cage.
diff --git a/src/node_serdes.cc b/src/node_serdes.cc
index 45a16d9de43703c2115dde85c9faae3a04be2a88..0cd76078218433b46c17f350e3ba6073987438cf 100644
index 45a16d9de43703c2115dde85c9faae3a04be2a88..97917c91c06dc47dfa6be2c194944cdc93e6bd7f 100644
--- a/src/node_serdes.cc
+++ b/src/node_serdes.cc
@@ -29,6 +29,11 @@ using v8::ValueSerializer;
@@ -219,17 +219,32 @@ index 45a16d9de43703c2115dde85c9faae3a04be2a88..0cd76078218433b46c17f350e3ba6073
Maybe<bool> SerializerContext::WriteHostObject(Isolate* isolate,
Local<Object> input) {
MaybeLocal<Value> ret;
@@ -211,7 +240,12 @@ void SerializerContext::ReleaseBuffer(const FunctionCallbackInfo<Value>& args) {
@@ -209,9 +238,14 @@ void SerializerContext::ReleaseBuffer(const FunctionCallbackInfo<Value>& args) {
// Note: Both ValueSerializer and this Buffer::New() variant use malloc()
// as the underlying allocator.
std::pair<uint8_t*, size_t> ret = ctx->serializer_.Release();
auto buf = Buffer::New(ctx->env(),
reinterpret_cast<char*>(ret.first),
- auto buf = Buffer::New(ctx->env(),
- reinterpret_cast<char*>(ret.first),
- ret.second);
+ ret.second,
+ [](char* data, void* hint){
+ if (data)
+ GetAllocator()->Free(data, reinterpret_cast<size_t>(hint));
+ },
+ reinterpret_cast<void*>(ctx->last_length_));
+ std::unique_ptr<v8::BackingStore> bs =
+ v8::ArrayBuffer::NewBackingStore(reinterpret_cast<char*>(ret.first), ret.second,
+ [](void* data, size_t length, void* deleter_data) {
+ if (data) GetAllocator()->Free(reinterpret_cast<char*>(data), length);
+ }, nullptr);
+ Local<ArrayBuffer> ab = v8::ArrayBuffer::New(ctx->env()->isolate(), std::move(bs));
+
+ auto buf = Buffer::New(ctx->env(), ab, 0, ret.second);
if (!buf.IsEmpty()) {
args.GetReturnValue().Set(buf.ToLocalChecked());
diff --git a/test/parallel/test-v8-serialize-leak.js b/test/parallel/test-v8-serialize-leak.js
index a90c398adcdaf30491a0fecdcf00895038d62e69..f5b8a1430ad2033eae06ca0157af2fb51d3f36a5 100644
--- a/test/parallel/test-v8-serialize-leak.js
+++ b/test/parallel/test-v8-serialize-leak.js
@@ -23,5 +23,5 @@ const after = process.memoryUsage.rss();
if (process.config.variables.asan) {
assert(after < before * 10, `asan: before=${before} after=${after}`);
} else {
- assert(after < before * 2, `before=${before} after=${after}`);
+ assert(after < before * 3, `before=${before} after=${after}`);
}

View File

@@ -1,130 +0,0 @@
#!/usr/bin/env python3
from __future__ import print_function
import os
import sys
import re
SOURCE_ROOT = os.path.abspath(os.path.dirname(os.path.dirname(__file__)))
DOCS_DIR = os.path.join(SOURCE_ROOT, 'docs')
def main():
os.chdir(SOURCE_ROOT)
filepaths = []
totalDirs = 0
try:
for root, dirs, files in os.walk(DOCS_DIR):
totalDirs += len(dirs)
for f in files:
if f.endswith('.md'):
filepaths.append(os.path.join(root, f))
except KeyboardInterrupt:
print('Keyboard interruption. Please try again.')
return 0
totalBrokenLinks = 0
for path in filepaths:
totalBrokenLinks += getBrokenLinks(path)
print('Parsed through ' + str(len(filepaths)) +
' files within docs directory and its ' +
str(totalDirs) + ' subdirectories.')
print('Found ' + str(totalBrokenLinks) + ' broken relative links.')
return totalBrokenLinks
def getBrokenLinks(filepath):
currentDir = os.path.dirname(filepath)
brokenLinks = []
try:
f = open(filepath, 'r', encoding="utf-8")
lines = f.readlines()
except KeyboardInterrupt:
print('Keyboard interruption while parsing. Please try again.')
finally:
f.close()
linkRegexLink = re.compile('\[(.*?)\]\((?P<link>(.*?))\)')
referenceLinkRegex = re.compile(
'^\s{0,3}\[.*?\]:\s*(?P<link>[^<\s]+|<[^<>\r\n]+>)'
)
links = []
for line in lines:
matchLinks = linkRegexLink.search(line)
matchReferenceLinks = referenceLinkRegex.search(line)
if matchLinks:
relativeLink = matchLinks.group('link')
if not str(relativeLink).startswith('http'):
links.append(relativeLink)
if matchReferenceLinks:
referenceLink = matchReferenceLinks.group('link').strip('<>')
if not str(referenceLink).startswith('http'):
links.append(referenceLink)
for link in links:
sections = link.split('#')
if len(sections) < 2:
if not os.path.isfile(os.path.join(currentDir, link)):
brokenLinks.append(link)
elif str(link).startswith('#'):
if not checkSections(sections, lines):
brokenLinks.append(link)
else:
tempFile = os.path.join(currentDir, sections[0])
if os.path.isfile(tempFile):
try:
newFile = open(tempFile, 'r', encoding="utf-8")
newLines = newFile.readlines()
except KeyboardInterrupt:
print('Keyboard interruption while parsing. Please try again.')
finally:
newFile.close()
if not checkSections(sections, newLines):
brokenLinks.append(link)
else:
brokenLinks.append(link)
print_errors(filepath, brokenLinks)
return len(brokenLinks)
def checkSections(sections, lines):
invalidCharsRegex = '[^A-Za-z0-9_ \-]'
sectionHeader = sections[1]
regexSectionTitle = re.compile('# (?P<header>.*)')
for line in lines:
matchHeader = regexSectionTitle.search(line)
if matchHeader:
# This does the following to slugify a header name:
# * Replace whitespace with dashes
# * Strip anything that's not alphanumeric or a dash
# * Anything quoted with backticks (`) is an exception and will
# not have underscores stripped
matchHeader = str(matchHeader.group('header')).replace(' ', '-')
matchHeader = ''.join(
map(
lambda match: re.sub(invalidCharsRegex, '', match[0])
+ re.sub(invalidCharsRegex + '|_', '', match[1]),
re.findall('(`[^`]+`)|([^`]+)', matchHeader),
)
)
if matchHeader.lower() == sectionHeader:
return True
return False
def print_errors(filepath, brokenLink):
if brokenLink:
print("File Location: " + filepath)
for link in brokenLink:
print("\tBroken links: " + link)
if __name__ == '__main__':
sys.exit(main())

View File

@@ -17,7 +17,7 @@ def copy_debug_from_binaries(directory, out_dir, target_cpu, compress):
def copy_debug_from_binary(binary_path, out_dir, target_cpu, compress):
if PLATFORM == 'linux' and target_cpu in ('x86', 'arm', 'arm64'):
# Skip because no objcopy binary on the given target.
return
return
debug_name = get_debug_name(binary_path)
cmd = ['objcopy', '--only-keep-debug']
if compress:

View File

@@ -21,6 +21,10 @@ def run_node_configure(target_cpu):
# Work around "No acceptable ASM compiler found" error on some System,
# it breaks nothing since Electron does not use OpenSSL.
args += ['--openssl-no-asm']
# Enable whole-program optimization for electron native modules.
if sys.platform == "win32":
args += ['--with-ltcg']
subprocess.check_call([sys.executable, configure] + args)
def read_node_config_gypi():

334
script/lib/markdown.ts Normal file
View File

@@ -0,0 +1,334 @@
import * as fs from 'fs';
import * as path from 'path';
import * as MarkdownIt from 'markdown-it';
import {
githubSlugifier,
resolveInternalDocumentLink,
ExternalHref,
FileStat,
HrefKind,
InternalHref,
IMdLinkComputer,
IMdParser,
ITextDocument,
IWorkspace,
MdLink,
MdLinkKind
} from '@dsanders11/vscode-markdown-languageservice';
import { Emitter, Range } from 'vscode-languageserver';
import { TextDocument } from 'vscode-languageserver-textdocument';
import { URI } from 'vscode-uri';
import { findMatchingFiles } from './utils';
import type { Definition, ImageReference, Link, LinkReference } from 'mdast';
import type { fromMarkdown as FromMarkdownFunction } from 'mdast-util-from-markdown';
import type { Node, Position } from 'unist';
import type { visit as VisitFunction } from 'unist-util-visit';
// Helper function to work around import issues with ESM modules and ts-node
// eslint-disable-next-line no-new-func
const dynamicImport = new Function('specifier', 'return import(specifier)');
// Helper function from `vscode-markdown-languageservice` codebase
function tryDecodeUri (str: string): string {
try {
return decodeURI(str);
} catch {
return str;
}
}
// Helper function from `vscode-markdown-languageservice` codebase
function createHref (
sourceDocUri: URI,
link: string,
workspace: IWorkspace
): ExternalHref | InternalHref | undefined {
if (/^[a-z-][a-z-]+:/i.test(link)) {
// Looks like a uri
return { kind: HrefKind.External, uri: URI.parse(tryDecodeUri(link)) };
}
const resolved = resolveInternalDocumentLink(sourceDocUri, link, workspace);
if (!resolved) {
return undefined;
}
return {
kind: HrefKind.Internal,
path: resolved.resource,
fragment: resolved.linkFragment
};
}
function positionToRange (position: Position): Range {
return {
start: {
character: position.start.column - 1,
line: position.start.line - 1
},
end: { character: position.end.column - 1, line: position.end.line - 1 }
};
}
const mdIt = MarkdownIt({ html: true });
export class MarkdownParser implements IMdParser {
slugifier = githubSlugifier;
async tokenize (document: TextDocument) {
return mdIt.parse(document.getText(), {});
}
}
export class DocsWorkspace implements IWorkspace {
private readonly documentCache: Map<string, TextDocument>;
readonly root: string;
constructor (root: string) {
this.documentCache = new Map();
this.root = root;
}
get workspaceFolders () {
return [URI.file(this.root)];
}
async getAllMarkdownDocuments (): Promise<Iterable<ITextDocument>> {
const files = await findMatchingFiles(this.root, (file) =>
file.endsWith('.md')
);
for (const file of files) {
const document = TextDocument.create(
URI.file(file).toString(),
'markdown',
1,
fs.readFileSync(file, 'utf8')
);
this.documentCache.set(file, document);
}
return this.documentCache.values();
}
hasMarkdownDocument (resource: URI) {
const relativePath = path.relative(this.root, resource.path);
return (
!relativePath.startsWith('..') &&
!path.isAbsolute(relativePath) &&
fs.existsSync(resource.path)
);
}
async openMarkdownDocument (resource: URI) {
if (!this.documentCache.has(resource.path)) {
const document = TextDocument.create(
resource.toString(),
'markdown',
1,
fs.readFileSync(resource.path, 'utf8')
);
this.documentCache.set(resource.path, document);
}
return this.documentCache.get(resource.path);
}
async stat (resource: URI): Promise<FileStat | undefined> {
if (this.hasMarkdownDocument(resource)) {
const stats = fs.statSync(resource.path);
return { isDirectory: stats.isDirectory() };
}
return undefined;
}
async readDirectory (): Promise<Iterable<readonly [string, FileStat]>> {
throw new Error('Not implemented');
}
//
// These events are defined to fulfill the interface, but are never emitted
// by this implementation since it's not meant for watching a workspace
//
#onDidChangeMarkdownDocument = new Emitter<ITextDocument>();
onDidChangeMarkdownDocument = this.#onDidChangeMarkdownDocument.event;
#onDidCreateMarkdownDocument = new Emitter<ITextDocument>();
onDidCreateMarkdownDocument = this.#onDidCreateMarkdownDocument.event;
#onDidDeleteMarkdownDocument = new Emitter<URI>();
onDidDeleteMarkdownDocument = this.#onDidDeleteMarkdownDocument.event;
}
export class MarkdownLinkComputer implements IMdLinkComputer {
private readonly workspace: IWorkspace;
constructor (workspace: IWorkspace) {
this.workspace = workspace;
}
async getAllLinks (document: ITextDocument): Promise<MdLink[]> {
const { fromMarkdown } = (await dynamicImport(
'mdast-util-from-markdown'
)) as { fromMarkdown: typeof FromMarkdownFunction };
const tree = fromMarkdown(document.getText());
const links = [
...(await this.#getInlineLinks(document, tree)),
...(await this.#getReferenceLinks(document, tree)),
...(await this.#getLinkDefinitions(document, tree))
];
return links;
}
async #getInlineLinks (
document: ITextDocument,
tree: Node
): Promise<MdLink[]> {
const { visit } = (await dynamicImport('unist-util-visit')) as {
visit: typeof VisitFunction;
};
const documentUri = URI.parse(document.uri);
const links: MdLink[] = [];
visit(
tree,
(node) => node.type === 'link',
(node: Node) => {
const link = node as Link;
const href = createHref(documentUri, link.url, this.workspace);
if (href) {
const range = positionToRange(link.position!);
// NOTE - These haven't been implemented properly, but their
// values aren't used for the link linting use-case
const targetRange = range;
const hrefRange = range;
const fragmentRange = undefined;
links.push({
kind: MdLinkKind.Link,
href,
source: {
hrefText: link.url,
resource: documentUri,
range,
targetRange,
hrefRange,
fragmentRange,
pathText: link.url.split('#')[0]
}
});
}
}
);
return links;
}
async #getReferenceLinks (
document: ITextDocument,
tree: Node
): Promise<MdLink[]> {
const { visit } = (await dynamicImport('unist-util-visit')) as {
visit: typeof VisitFunction;
};
const links: MdLink[] = [];
visit(
tree,
(node) => ['imageReference', 'linkReference'].includes(node.type),
(node: Node) => {
const link = node as ImageReference | LinkReference;
const range = positionToRange(link.position!);
// NOTE - These haven't been implemented properly, but their
// values aren't used for the link linting use-case
const targetRange = range;
const hrefRange = range;
links.push({
kind: MdLinkKind.Link,
href: {
kind: HrefKind.Reference,
ref: link.label!
},
source: {
hrefText: link.label!,
resource: URI.parse(document.uri),
range,
targetRange,
hrefRange,
fragmentRange: undefined,
pathText: link.label!
}
});
}
);
return links;
}
async #getLinkDefinitions (
document: ITextDocument,
tree: Node
): Promise<MdLink[]> {
const { visit } = (await dynamicImport('unist-util-visit')) as {
visit: typeof VisitFunction;
};
const documentUri = URI.parse(document.uri);
const links: MdLink[] = [];
visit(
tree,
(node) => node.type === 'definition',
(node: Node) => {
const definition = node as Definition;
const href = createHref(documentUri, definition.url, this.workspace);
if (href) {
const range = positionToRange(definition.position!);
// NOTE - These haven't been implemented properly, but their
// values aren't used for the link linting use-case
const targetRange = range;
const hrefRange = range;
const fragmentRange = undefined;
links.push({
kind: MdLinkKind.Definition,
href,
ref: {
range,
text: definition.label!
},
source: {
hrefText: definition.url,
resource: documentUri,
range,
targetRange,
hrefRange,
fragmentRange,
pathText: definition.url.split('#')[0]
}
});
}
}
);
return links;
}
}

View File

@@ -1,5 +1,6 @@
const { GitProcess } = require('dugite');
const fs = require('fs');
const klaw = require('klaw');
const os = require('os');
const path = require('path');
@@ -122,8 +123,29 @@ function chunkFilenames (filenames, offset = 0) {
);
}
/**
* @param {string} top
* @param {(filename: string) => boolean} test
* @returns {Promise<string[]>}
*/
async function findMatchingFiles (top, test) {
return new Promise((resolve, reject) => {
const matches = [];
klaw(top, {
filter: f => path.basename(f) !== '.bin'
})
.on('end', () => resolve(matches))
.on('data', item => {
if (test(item.path)) {
matches.push(item.path);
}
});
});
}
module.exports = {
chunkFilenames,
findMatchingFiles,
getCurrentBranch,
getElectronExec,
getOutDir,

177
script/lint-docs-links.ts Executable file
View File

@@ -0,0 +1,177 @@
#!/usr/bin/env ts-node
import * as path from 'path';
import {
createLanguageService,
DiagnosticLevel,
DiagnosticOptions,
ILogger
} from '@dsanders11/vscode-markdown-languageservice';
import * as minimist from 'minimist';
import fetch from 'node-fetch';
import { CancellationTokenSource } from 'vscode-languageserver';
import { URI } from 'vscode-uri';
import {
DocsWorkspace,
MarkdownLinkComputer,
MarkdownParser
} from './lib/markdown';
class NoOpLogger implements ILogger {
log (): void {}
}
const diagnosticOptions: DiagnosticOptions = {
ignoreLinks: [],
validateDuplicateLinkDefinitions: DiagnosticLevel.error,
validateFileLinks: DiagnosticLevel.error,
validateFragmentLinks: DiagnosticLevel.error,
validateMarkdownFileLinkFragments: DiagnosticLevel.error,
validateReferences: DiagnosticLevel.error,
validateUnusedLinkDefinitions: DiagnosticLevel.error
};
async function fetchExternalLink (link: string, checkRedirects = false) {
try {
const response = await fetch(link);
if (response.status !== 200) {
console.log('Broken link', link, response.status, response.statusText);
} else {
if (checkRedirects && response.redirected) {
const wwwUrl = new URL(link);
wwwUrl.hostname = `www.${wwwUrl.hostname}`;
// For now cut down on noise to find meaningful redirects
const wwwRedirect = wwwUrl.toString() === response.url;
const trailingSlashRedirect = `${link}/` === response.url;
if (!wwwRedirect && !trailingSlashRedirect) {
console.log('Link redirection', link, '->', response.url);
}
}
return true;
}
} catch {
console.log('Broken link', link);
}
return false;
}
async function main ({ fetchExternalLinks = false, checkRedirects = false }) {
const workspace = new DocsWorkspace(path.resolve(__dirname, '..', 'docs'));
const parser = new MarkdownParser();
const linkComputer = new MarkdownLinkComputer(workspace);
const languageService = createLanguageService({
workspace,
parser,
logger: new NoOpLogger(),
linkComputer
});
const cts = new CancellationTokenSource();
let errors = false;
const externalLinks = new Set<string>();
try {
// Collect diagnostics for all documents in the workspace
for (const document of await workspace.getAllMarkdownDocuments()) {
for (let link of await languageService.getDocumentLinks(
document,
cts.token
)) {
if (link.target === undefined) {
link =
(await languageService.resolveDocumentLink(link, cts.token)) ??
link;
}
if (
link.target &&
link.target.startsWith('http') &&
new URL(link.target).hostname !== 'localhost'
) {
externalLinks.add(link.target);
}
}
const diagnostics = await languageService.computeDiagnostics(
document,
diagnosticOptions,
cts.token
);
if (diagnostics.length) {
console.log(
'File Location:',
path.relative(workspace.root, URI.parse(document.uri).path)
);
}
for (const diagnostic of diagnostics) {
console.log(
`\tBroken link on line ${diagnostic.range.start.line + 1}:`,
diagnostic.message
);
errors = true;
}
}
} finally {
cts.dispose();
}
if (fetchExternalLinks) {
const externalLinkStates = await Promise.all(
Array.from(externalLinks).map((link) =>
fetchExternalLink(link, checkRedirects)
)
);
errors = errors || !externalLinkStates.every((x) => x);
}
return errors;
}
function parseCommandLine () {
const showUsage = (arg?: string): boolean => {
if (!arg || arg.startsWith('-')) {
console.log(
'Usage: script/lint-docs-links.ts [-h|--help] [--fetch-external-links] ' +
'[--check-redirects]'
);
process.exit(0);
}
return true;
};
const opts = minimist(process.argv.slice(2), {
boolean: ['help', 'fetch-external-links', 'check-redirects'],
stopEarly: true,
unknown: showUsage
});
if (opts.help) showUsage();
return opts;
}
if (process.mainModule === module) {
const opts = parseCommandLine();
main({
fetchExternalLinks: opts['fetch-external-links'],
checkRedirects: opts['check-redirects']
})
.then((errors) => {
if (errors) process.exit(1);
})
.catch((error) => {
console.error(error);
process.exit(1);
});
}

View File

@@ -5,11 +5,10 @@ const { GitProcess } = require('dugite');
const childProcess = require('child_process');
const { ESLint } = require('eslint');
const fs = require('fs');
const klaw = require('klaw');
const minimist = require('minimist');
const path = require('path');
const { chunkFilenames } = require('./lib/utils');
const { chunkFilenames, findMatchingFiles } = require('./lib/utils');
const ELECTRON_ROOT = path.normalize(path.dirname(__dirname));
const SOURCE_ROOT = path.resolve(ELECTRON_ROOT, '..');
@@ -87,11 +86,8 @@ const LINTERS = [{
roots: ['shell'],
test: filename => filename.endsWith('.mm') || (filename.endsWith('.h') && isObjCHeader(filename)),
run: (opts, filenames) => {
if (opts.fix) {
spawnAndCheckExitCode('python3', ['script/run-clang-format.py', '-r', '--fix', ...filenames]);
} else {
spawnAndCheckExitCode('python3', ['script/run-clang-format.py', '-r', ...filenames]);
}
const clangFormatFlags = opts.fix ? ['--fix'] : [];
spawnAndCheckExitCode('python3', ['script/run-clang-format.py', '-r', ...clangFormatFlags, ...filenames]);
const filter = [
'-readability/braces',
'-readability/casting',
@@ -279,21 +275,6 @@ async function findChangedFiles (top) {
return new Set(absolutePaths);
}
async function findMatchingFiles (top, test) {
return new Promise((resolve, reject) => {
const matches = [];
klaw(top, {
filter: f => path.basename(f) !== '.bin'
})
.on('end', () => resolve(matches))
.on('data', item => {
if (test(item.path)) {
matches.push(item.path);
}
});
});
}
async function findFiles (args, linter) {
let filenames = [];
let includelist = null;

View File

@@ -137,7 +137,6 @@
"parallel/test-worker-debug",
"parallel/test-worker-init-failure",
"parallel/test-worker-stdio",
"parallel/test-v8-serialize-leak",
"parallel/test-zlib-unused-weak",
"report/test-report-fatalerror-oomerror-set",
"report/test-report-fatalerror-oomerror-directory",

View File

@@ -57,8 +57,9 @@ async function main () {
if (args.validateDisabled) {
const missing = [];
for (const test of DISABLED_TESTS) {
const testName = test.endsWith('.js') ? test : `${test}.js`;
if (!fs.existsSync(path.join(NODE_DIR, 'test', testName))) {
const js = path.join(NODE_DIR, 'test', `${test}.js`);
const mjs = path.join(NODE_DIR, 'test', `${test}.mjs`);
if (!fs.existsSync(js) && !fs.existsSync(mjs)) {
missing.push(test);
}
}

View File

@@ -58,7 +58,7 @@ def upload_node(version):
elif get_target_arch() == 'arm64':
node_lib = os.path.join(DIST_DIR, 'arm64', 'node.lib')
iojs_lib = os.path.join(DIST_DIR, 'win-arm64', 'iojs.lib')
v4_node_lib = os.path.join(DIST_DIR, 'win-arm64', 'node.lib')
v4_node_lib = os.path.join(DIST_DIR, 'win-arm64', 'node.lib')
else:
node_lib = os.path.join(DIST_DIR, 'x64', 'node.lib')
iojs_lib = os.path.join(DIST_DIR, 'win-x64', 'iojs.lib')

View File

@@ -93,7 +93,7 @@ def main():
dsym_snapshot_zip = os.path.join(OUT_DIR, DSYM_SNAPSHOT_NAME)
shutil.copy2(os.path.join(OUT_DIR, 'dsym-snapshot.zip'), dsym_snapshot_zip)
upload_electron(release, dsym_snapshot_zip, args)
upload_electron(release, dsym_snapshot_zip, args)
elif PLATFORM == 'win32':
pdb_zip = os.path.join(OUT_DIR, PDB_NAME)
shutil.copy2(os.path.join(OUT_DIR, 'pdb.zip'), pdb_zip)

View File

@@ -20,7 +20,7 @@ function parseCommandLine () {
--bump=patch to increment patch version\n
--version={version} to set version number directly\n
--dryRun to print the next version without updating files
Note that you can use both --bump and --stable simultaneously.
Note that you can use both --bump and --stable simultaneously.
`);
process.exit(0);
}

View File

@@ -1,6 +1,5 @@
import * as childProcess from 'child_process';
import * as fs from 'fs';
import * as klaw from 'klaw';
import * as minimist from 'minimist';
import * as os from 'os';
import * as path from 'path';
@@ -9,7 +8,7 @@ import * as streamJson from 'stream-json';
import { ignore as streamJsonIgnore } from 'stream-json/filters/Ignore';
import { streamArray as streamJsonStreamArray } from 'stream-json/streamers/StreamArray';
import { chunkFilenames } from './lib/utils';
import { chunkFilenames, findMatchingFiles } from './lib/utils';
const SOURCE_ROOT = path.normalize(path.dirname(__dirname));
const LLVM_BIN = path.resolve(
@@ -204,24 +203,6 @@ async function runClangTidy (
}
}
async function findMatchingFiles (
top: string,
test: (filename: string) => boolean
): Promise<string[]> {
return new Promise((resolve) => {
const matches = [] as string[];
klaw(top, {
filter: (f) => path.basename(f) !== '.bin'
})
.on('end', () => resolve(matches))
.on('data', (item) => {
if (test(item.path)) {
matches.push(item.path);
}
});
});
}
function parseCommandLine () {
const showUsage = (arg?: string) : boolean => {
if (!arg || arg.startsWith('-')) {

View File

@@ -1,10 +1,10 @@
param([string]$gomaDir=$PWD)
$cmdPath = Join-Path -Path $gomaDir -ChildPath "goma_ctl.py"
$cmdPath = Join-Path -Path $gomaDir -ChildPath "goma_ctl.py"
Start-Process -FilePath cmd -ArgumentList "/C", "python", "$cmdPath", "ensure_start"
$timedOut = $false; $waitTime = 0; $waitIncrement = 5; $timeout=120;
Do { sleep $waitIncrement; $timedOut = (($waitTime+=$waitIncrement) -gt $timeout); iex "$gomaDir\gomacc.exe port 2" > $null; } Until(($LASTEXITCODE -eq 0) -or $timedOut)
if ($timedOut) {
write-error 'Timed out waiting for goma to start'; exit 1;
Do { sleep $waitIncrement; $timedOut = (($waitTime+=$waitIncrement) -gt $timeout); iex "$gomaDir\gomacc.exe port 2" > $null; } Until(($LASTEXITCODE -eq 0) -or $timedOut)
if ($timedOut) {
write-error 'Timed out waiting for goma to start'; exit 1;
} else {
Write-Output "Successfully started goma!"
}

View File

@@ -104,26 +104,6 @@ bool IsWidevineAvailable(
}
#endif // BUILDFLAG(ENABLE_WIDEVINE)
#if BUILDFLAG(ENABLE_PLUGINS)
void ComputeBuiltInPlugins(std::vector<content::ContentPluginInfo>* plugins) {
#if BUILDFLAG(ENABLE_PDF_VIEWER)
// TODO(upstream/thestig): Figure out how to make the PDF Viewer work without
// this PPAPI plugin registration.
content::ContentPluginInfo pdf_info;
pdf_info.is_internal = true;
pdf_info.is_out_of_process = true;
pdf_info.name = kPDFInternalPluginName;
pdf_info.description = "Portable Document Format";
// This isn't a real file path; it's just used as a unique identifier.
pdf_info.path = base::FilePath(kPdfPluginPath);
content::WebPluginMimeType pdf_mime_type(pdf::kInternalPluginMimeType, "pdf",
"Portable Document Format");
pdf_info.mime_types.push_back(pdf_mime_type);
plugins->push_back(pdf_info);
#endif // BUILDFLAG(ENABLE_PDF_VIEWER)
}
#endif // BUILDFLAG(ENABLE_PLUGINS)
void AppendDelimitedSwitchToVector(const base::StringPiece cmd_switch,
std::vector<std::string>* append_me) {
auto* command_line = base::CommandLine::ForCurrentProcess();
@@ -204,9 +184,22 @@ void ElectronContentClient::AddAdditionalSchemes(Schemes* schemes) {
void ElectronContentClient::AddPlugins(
std::vector<content::ContentPluginInfo>* plugins) {
#if BUILDFLAG(ENABLE_PLUGINS)
ComputeBuiltInPlugins(plugins);
#endif // BUILDFLAG(ENABLE_PLUGINS)
#if BUILDFLAG(ENABLE_PLUGINS) && BUILDFLAG(ENABLE_PDF_VIEWER)
static constexpr char kPDFPluginExtension[] = "pdf";
static constexpr char kPDFPluginDescription[] = "Portable Document Format";
content::ContentPluginInfo pdf_info;
pdf_info.is_internal = true;
pdf_info.is_out_of_process = true;
pdf_info.name = kPDFInternalPluginName;
pdf_info.description = kPDFPluginDescription;
// This isn't a real file path; it's just used as a unique identifier.
pdf_info.path = base::FilePath(kPdfPluginPath);
content::WebPluginMimeType pdf_mime_type(
pdf::kInternalPluginMimeType, kPDFPluginExtension, kPDFPluginDescription);
pdf_info.mime_types.push_back(pdf_mime_type);
plugins->push_back(pdf_info);
#endif // BUILDFLAG(ENABLE_PLUGINS) && BUILDFLAG(ENABLE_PDF_VIEWER)
}
void ElectronContentClient::AddContentDecryptionModules(

View File

@@ -15,7 +15,6 @@
#include "base/strings/sys_string_conversions.h"
#include "content/common/mac_helpers.h"
#include "content/public/common/content_paths.h"
#include "ppapi/buildflags/buildflags.h"
#include "shell/browser/mac/electron_application.h"
#include "shell/common/application_info.h"
#include "shell/common/mac/main_application_bundle.h"
@@ -41,11 +40,9 @@ base::FilePath GetHelperAppPath(const base::FilePath& frameworks_path,
} else if (base::EndsWith(path.value(), content::kMacHelperSuffix_gpu,
base::CompareCase::SENSITIVE)) {
helper_name += content::kMacHelperSuffix_gpu;
#if BUILDFLAG(ENABLE_PLUGINS)
} else if (base::EndsWith(path.value(), content::kMacHelperSuffix_plugin,
base::CompareCase::SENSITIVE)) {
helper_name += content::kMacHelperSuffix_plugin;
#endif
}
return frameworks_path.Append(name + " " + helper_name + ".app")

View File

@@ -425,9 +425,10 @@ std::string SystemPreferences::GetSystemColor(gin_helper::ErrorThrower thrower,
bool SystemPreferences::CanPromptTouchID() {
base::scoped_nsobject<LAContext> context([[LAContext alloc] init]);
if (![context
canEvaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics
error:nil])
LAPolicy auth_policy = LAPolicyDeviceOwnerAuthenticationWithBiometrics;
if (@available(macOS 10.15, *))
auth_policy = LAPolicyDeviceOwnerAuthenticationWithBiometricsOrWatch;
if (![context canEvaluatePolicy:auth_policy error:nil])
return false;
if (@available(macOS 10.13.2, *))
return [context biometryType] == LABiometryTypeTouchID;

View File

@@ -3825,6 +3825,10 @@ void WebContents::DevToolsStopIndexing(int request_id) {
devtools_indexing_jobs_.erase(it);
}
void WebContents::DevToolsOpenInNewTab(const std::string& url) {
Emit("devtools-open-url", url);
}
void WebContents::DevToolsSearchInPath(int request_id,
const std::string& file_system_path,
const std::string& query) {

View File

@@ -704,6 +704,7 @@ class WebContents : public ExclusiveAccessContext,
void DevToolsIndexPath(int request_id,
const std::string& file_system_path,
const std::string& excluded_folders_message) override;
void DevToolsOpenInNewTab(const std::string& url) override;
void DevToolsStopIndexing(int request_id) override;
void DevToolsSearchInPath(int request_id,
const std::string& file_system_path,

View File

@@ -120,10 +120,6 @@
#include "ui/native_theme/native_theme.h"
#include "v8/include/v8.h"
#if BUILDFLAG(IS_WIN)
#include "sandbox/win/src/sandbox_policy.h"
#endif
#if BUILDFLAG(USE_NSS_CERTS)
#include "net/ssl/client_cert_store_nss.h"
#elif BUILDFLAG(IS_WIN)
@@ -474,15 +470,10 @@ void ElectronBrowserClient::AppendExtraCommandLineSwitches(
content::ChildProcessHost::CHILD_RENDERER);
auto gpu_child_path = content::ChildProcessHost::GetChildPath(
content::ChildProcessHost::CHILD_GPU);
#if BUILDFLAG(ENABLE_PLUGINS)
auto plugin_child_path = content::ChildProcessHost::GetChildPath(
content::ChildProcessHost::CHILD_PLUGIN);
#endif
if (program != renderer_child_path && program != gpu_child_path
#if BUILDFLAG(ENABLE_PLUGINS)
&& program != plugin_child_path
#endif
) {
if (program != renderer_child_path && program != gpu_child_path &&
program != plugin_child_path) {
child_path = content::ChildProcessHost::GetChildPath(
content::ChildProcessHost::CHILD_NORMAL);
CHECK_EQ(program, child_path)
@@ -1440,19 +1431,6 @@ void ElectronBrowserClient::OverrideURLLoaderFactoryParams(
browser_context, origin, is_for_isolated_world, factory_params);
}
#if BUILDFLAG(IS_WIN)
bool ElectronBrowserClient::PreSpawnChild(sandbox::TargetPolicy* policy,
sandbox::mojom::Sandbox sandbox_type,
ChildSpawnFlags flags) {
sandbox::ResultCode result = policy->GetConfig()->AddRule(
sandbox::SubSystem::kFiles, sandbox::Semantics::kFilesAllowAny,
L"\\??\\pipe\\crashpad_*");
if (result != sandbox::SBOX_ALL_OK)
return false;
return true;
}
#endif // BUILDFLAG(IS_WIN)
void ElectronBrowserClient::
RegisterAssociatedInterfaceBindersForRenderFrameHost(
content::RenderFrameHost&

View File

@@ -242,11 +242,6 @@ class ElectronBrowserClient : public content::ContentBrowserClient,
const url::Origin& origin,
bool is_for_isolated_world,
network::mojom::URLLoaderFactoryParams* factory_params) override;
#if BUILDFLAG(IS_WIN)
bool PreSpawnChild(sandbox::TargetPolicy* policy,
sandbox::mojom::Sandbox sandbox_type,
ChildSpawnFlags flags) override;
#endif
void RegisterAssociatedInterfaceBindersForRenderFrameHost(
content::RenderFrameHost& render_frame_host,
blink::AssociatedInterfaceRegistry& associated_registry) override;

View File

@@ -180,7 +180,7 @@ void FileSelectHelper::OnListDone(int error) {
std::unique_ptr<ActiveDirectoryEnumeration> entry =
std::move(directory_enumeration_);
if (error) {
FileSelectionCanceled(NULL);
FileSelectionCanceled(nullptr);
return;
}
@@ -487,6 +487,11 @@ void FileSelectHelper::RunFileChooserEnd() {
listener_->FileSelectionCanceled();
render_frame_host_ = nullptr;
web_contents_ = nullptr;
// If the dialog was actually opened, dispose of our reference.
if (select_file_dialog_) {
select_file_dialog_->ListenerDestroyed();
select_file_dialog_.reset();
}
Release();
}
@@ -525,8 +530,6 @@ void FileSelectHelper::RenderWidgetHostDestroyed(
void FileSelectHelper::RenderFrameHostChanged(
content::RenderFrameHost* old_host,
content::RenderFrameHost* new_host) {
if (!render_frame_host_)
return;
// The |old_host| and its children are now pending deletion. Do not give them
// file access past this point.
for (content::RenderFrameHost* host = render_frame_host_; host;

View File

@@ -24,6 +24,10 @@
#include "ui/base/hit_test.h"
#include "ui/views/widget/widget.h"
#if !BUILDFLAG(IS_MAC)
#include "shell/browser/ui/views/frameless_view.h"
#endif
#if BUILDFLAG(IS_WIN)
#include "ui/base/win/shell.h"
#include "ui/display/win/screen_win.h"
@@ -693,6 +697,17 @@ void NativeWindow::NotifyWindowMessage(UINT message,
#endif
int NativeWindow::NonClientHitTest(const gfx::Point& point) {
#if !BUILDFLAG(IS_MAC)
// We need to ensure we account for resizing borders on Windows and Linux.
if ((!has_frame() || has_client_frame()) && IsResizable()) {
auto* frame =
static_cast<FramelessView*>(widget()->non_client_view()->frame_view());
int border_hit = frame->ResizingBorderHitTest(point);
if (border_hit != HTNOWHERE)
return border_hit;
}
#endif
for (auto* provider : draggable_region_providers_) {
int hit = provider->NonClientHitTest(point);
if (hit != HTNOWHERE)

View File

@@ -1592,19 +1592,7 @@ views::View* NativeWindowViews::GetContentsView() {
bool NativeWindowViews::ShouldDescendIntoChildForEventHandling(
gfx::NativeView child,
const gfx::Point& location) {
// App window should claim mouse events that fall within any BrowserViews'
// draggable region.
if (NonClientHitTest(location) != HTNOWHERE)
return false;
// And the events on border for dragging resizable frameless window.
if ((!has_frame() || has_client_frame()) && resizable_) {
auto* frame =
static_cast<FramelessView*>(widget()->non_client_view()->frame_view());
return frame->ResizingBorderHitTest(location) == HTNOWHERE;
}
return true;
return NonClientHitTest(location) == HTNOWHERE;
}
views::ClientView* NativeWindowViews::CreateClientView(views::Widget* widget) {

View File

@@ -28,7 +28,7 @@
<string>MainMenu</string>
<key>NSPrincipalClass</key>
<string>AtomApplication</string>
<key>NSAppTransportSecurity</key>
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>

View File

@@ -33,12 +33,14 @@
namespace electron {
namespace {
void CalculatePopupXAndWidthHorizontallyCentered(
int popup_preferred_width,
const gfx::Rect& content_area_bounds,
const gfx::Rect& element_bounds,
bool is_rtl,
gfx::Rect* bubble_bounds) {
gfx::Rect* popup_bounds) {
// The preferred horizontal starting point for the pop-up is at the horizontal
// center of the field.
int preferred_starting_point =
@@ -66,15 +68,15 @@ void CalculatePopupXAndWidthHorizontallyCentered(
int amount_to_grow_in_unpreferred_direction =
std::max(0, popup_width - space_to_grow_in_preferred_direction);
bubble_bounds->set_width(popup_width);
popup_bounds->set_width(popup_width);
if (is_rtl) {
// Note, in RTL the |pop_up_width| must be subtracted to achieve
// right-alignment of the pop-up with the element.
bubble_bounds->set_x(preferred_starting_point - popup_width +
amount_to_grow_in_unpreferred_direction);
popup_bounds->set_x(preferred_starting_point - popup_width +
amount_to_grow_in_unpreferred_direction);
} else {
bubble_bounds->set_x(preferred_starting_point -
amount_to_grow_in_unpreferred_direction);
popup_bounds->set_x(preferred_starting_point -
amount_to_grow_in_unpreferred_direction);
}
}
@@ -82,7 +84,7 @@ void CalculatePopupXAndWidth(int popup_preferred_width,
const gfx::Rect& content_area_bounds,
const gfx::Rect& element_bounds,
bool is_rtl,
gfx::Rect* bubble_bounds) {
gfx::Rect* popup_bounds) {
int right_growth_start = base::clamp(
element_bounds.x(), content_area_bounds.x(), content_area_bounds.right());
int left_growth_end =
@@ -107,15 +109,15 @@ void CalculatePopupXAndWidth(int popup_preferred_width,
right_available < popup_width && right_available < left_available;
}
bubble_bounds->set_width(popup_width);
bubble_bounds->set_x(grow_left ? left_growth_end - popup_width
: right_growth_start);
popup_bounds->set_width(popup_width);
popup_bounds->set_x(grow_left ? left_growth_end - popup_width
: right_growth_start);
}
void CalculatePopupYAndHeight(int popup_preferred_height,
const gfx::Rect& content_area_bounds,
const gfx::Rect& element_bounds,
gfx::Rect* bubble_bounds) {
gfx::Rect* popup_bounds) {
int top_growth_end = base::clamp(element_bounds.y(), content_area_bounds.y(),
content_area_bounds.bottom());
int bottom_growth_start =
@@ -125,18 +127,18 @@ void CalculatePopupYAndHeight(int popup_preferred_height,
int top_available = top_growth_end - content_area_bounds.y();
int bottom_available = content_area_bounds.bottom() - bottom_growth_start;
bubble_bounds->set_height(popup_preferred_height);
bubble_bounds->set_y(top_growth_end);
popup_bounds->set_height(popup_preferred_height);
popup_bounds->set_y(top_growth_end);
if (bottom_available >= popup_preferred_height ||
bottom_available >= top_available) {
bubble_bounds->AdjustToFit(
gfx::Rect(bubble_bounds->x(), element_bounds.bottom(),
bubble_bounds->width(), bottom_available));
popup_bounds->AdjustToFit(
gfx::Rect(popup_bounds->x(), element_bounds.bottom(),
popup_bounds->width(), bottom_available));
} else {
bubble_bounds->AdjustToFit(
gfx::Rect(bubble_bounds->x(), content_area_bounds.y(),
bubble_bounds->width(), top_available));
popup_bounds->AdjustToFit(gfx::Rect(popup_bounds->x(),
content_area_bounds.y(),
popup_bounds->width(), top_available));
}
}
@@ -145,22 +147,24 @@ gfx::Rect CalculatePopupBounds(const gfx::Size& desired_size,
const gfx::Rect& element_bounds,
bool is_rtl,
bool horizontally_centered) {
gfx::Rect bubble_bounds;
gfx::Rect popup_bounds;
if (horizontally_centered) {
CalculatePopupXAndWidthHorizontallyCentered(
desired_size.width(), content_area_bounds, element_bounds, is_rtl,
&bubble_bounds);
&popup_bounds);
} else {
CalculatePopupXAndWidth(desired_size.width(), content_area_bounds,
element_bounds, is_rtl, &bubble_bounds);
element_bounds, is_rtl, &popup_bounds);
}
CalculatePopupYAndHeight(desired_size.height(), content_area_bounds,
element_bounds, &bubble_bounds);
element_bounds, &popup_bounds);
return bubble_bounds;
return popup_bounds;
}
} // namespace
AutofillPopup::AutofillPopup() {
bold_font_list_ = gfx::FontList().DeriveWithWeight(gfx::Font::Weight::BOLD);
smaller_font_list_ =
@@ -242,16 +246,12 @@ void AutofillPopup::UpdatePopupBounds() {
views::View::ConvertPointToScreen(parent_, &origin);
gfx::Rect bounds(origin, element_bounds_.size());
gfx::Rect window_bounds = parent_->GetBoundsInScreen();
gfx::Size preferred_size =
gfx::Size(GetDesiredPopupWidth(), GetDesiredPopupHeight());
popup_bounds_ = CalculatePopupBounds(preferred_size, window_bounds, bounds,
base::i18n::IsRTL(), true);
CalculatePopupXAndWidthHorizontallyCentered(
preferred_size.width(), window_bounds, element_bounds_,
base::i18n::IsRTL(), &popup_bounds_);
popup_bounds_ =
CalculatePopupBounds(preferred_size, parent_->GetBoundsInScreen(), bounds,
base::i18n::IsRTL(), false);
}
gfx::Rect AutofillPopup::popup_bounds_in_view() {

View File

@@ -0,0 +1,70 @@
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "shell/browser/ui/gtk/menu_gtk.h"
#include <gtk/gtk.h>
#include "shell/browser/ui/gtk/menu_util.h"
#include "ui/base/models/menu_model.h"
namespace electron {
namespace gtkui {
MenuGtk::MenuGtk(ui::MenuModel* model)
: menu_model_(model), gtk_menu_(TakeGObject(gtk_menu_new())) {
if (menu_model_) {
BuildSubmenuFromModel(menu_model_, gtk_menu_,
G_CALLBACK(OnMenuItemActivatedThunk),
&block_activation_, this);
Refresh();
}
}
MenuGtk::~MenuGtk() {
gtk_widget_destroy(gtk_menu_);
}
void MenuGtk::Refresh() {
gtk_container_foreach(GTK_CONTAINER(gtk_menu_.get()), SetMenuItemInfo,
&block_activation_);
}
GtkMenu* MenuGtk::GetGtkMenu() {
return GTK_MENU(gtk_menu_.get());
}
void MenuGtk::OnMenuItemActivated(GtkWidget* menu_item) {
if (block_activation_)
return;
ui::MenuModel* model = ModelForMenuItem(GTK_MENU_ITEM(menu_item));
if (!model) {
// There won't be a model for "native" submenus like the "Input Methods"
// context menu. We don't need to handle activation messages for submenus
// anyway, so we can just return here.
DCHECK(gtk_menu_item_get_submenu(GTK_MENU_ITEM(menu_item)));
return;
}
// The activate signal is sent to radio items as they get deselected;
// ignore it in this case.
if (GTK_IS_RADIO_MENU_ITEM(menu_item) &&
!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menu_item))) {
return;
}
int id;
if (!GetMenuItemID(menu_item, &id))
return;
// The menu item can still be activated by hotkeys even if it is disabled.
if (model->IsEnabledAt(id))
ExecuteCommand(model, id);
}
} // namespace gtkui
} // namespace electron

View File

@@ -0,0 +1,48 @@
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef ELECTRON_SHELL_BROWSER_UI_GTK_MENU_GTK_H_
#define ELECTRON_SHELL_BROWSER_UI_GTK_MENU_GTK_H_
#include "base/callback.h"
#include "base/memory/raw_ptr.h"
#include "ui/base/glib/glib_signal.h"
#include "ui/base/glib/scoped_gobject.h"
typedef struct _GtkMenu GtkMenu;
typedef struct _GtkWidget GtkWidget;
namespace ui {
class MenuModel;
}
namespace electron {
namespace gtkui {
class MenuGtk {
public:
explicit MenuGtk(ui::MenuModel* model);
virtual ~MenuGtk();
// Refreshes all the menu item labels and menu item checked/enabled states.
void Refresh();
GtkMenu* GetGtkMenu();
private:
// Callback for when a menu item is activated.
CHROMEG_CALLBACK_0(MenuGtk, void, OnMenuItemActivated, GtkWidget*);
raw_ptr<ui::MenuModel> menu_model_; // not owned
ScopedGObject<GtkWidget> gtk_menu_;
bool block_activation_ = false;
};
} // namespace gtkui
} // namespace electron
#endif // ELECTRON_SHELL_BROWSER_UI_GTK_MENU_GTK_H_

View File

@@ -723,7 +723,10 @@ void InspectableWebContents::SetIsDocked(DispatchCallback callback,
std::move(callback).Run(nullptr);
}
void InspectableWebContents::OpenInNewTab(const std::string& url) {}
void InspectableWebContents::OpenInNewTab(const std::string& url) {
if (delegate_)
delegate_->DevToolsOpenInNewTab(url);
}
void InspectableWebContents::ShowItemInFolder(
const std::string& file_system_path) {

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