mirror of
https://github.com/electron/electron.git
synced 2026-04-10 03:01:51 -04:00
Compare commits
208 Commits
v8.5.5
...
v9.0.0-nig
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a5e84d0a2a | ||
|
|
e3f36d3e0b | ||
|
|
1f3561227d | ||
|
|
092e00f7f0 | ||
|
|
dc9beda182 | ||
|
|
4ac575416f | ||
|
|
5bc8809d64 | ||
|
|
8a06ef11cf | ||
|
|
4037b12511 | ||
|
|
6df7bd63e4 | ||
|
|
63058b8a2d | ||
|
|
9e189eac71 | ||
|
|
93802a7e6f | ||
|
|
5223d1d774 | ||
|
|
fff484d4ea | ||
|
|
0a741670a9 | ||
|
|
113b47d871 | ||
|
|
143407ea1b | ||
|
|
1b61fe780e | ||
|
|
5733507040 | ||
|
|
01ab72d8c0 | ||
|
|
c1845121e0 | ||
|
|
9526c5584e | ||
|
|
c7cbc2e6b1 | ||
|
|
f2f52c23b5 | ||
|
|
ee58d60612 | ||
|
|
66035a2448 | ||
|
|
3d2fa09db3 | ||
|
|
0a60f455a9 | ||
|
|
b26a6793ba | ||
|
|
469fc0ea36 | ||
|
|
03824ef53f | ||
|
|
74f698d7bc | ||
|
|
ba77489cb6 | ||
|
|
2129751966 | ||
|
|
0618505722 | ||
|
|
01f5e9c5c4 | ||
|
|
f09cb114e4 | ||
|
|
06e349d074 | ||
|
|
96c4c48268 | ||
|
|
5f365858c9 | ||
|
|
d25256dcf5 | ||
|
|
4149d76890 | ||
|
|
149aaeba94 | ||
|
|
8a9c7c484b | ||
|
|
ca61d2fae7 | ||
|
|
2e25999c52 | ||
|
|
d84ba30541 | ||
|
|
f26b7931eb | ||
|
|
27c764c66c | ||
|
|
ab695fb2f7 | ||
|
|
78ae5d410e | ||
|
|
d20273f95b | ||
|
|
34452ee69e | ||
|
|
a7c2f79a94 | ||
|
|
745363959a | ||
|
|
033d309874 | ||
|
|
135a64955c | ||
|
|
0cadf2846b | ||
|
|
07b94ff578 | ||
|
|
1da9959f57 | ||
|
|
3f2cb91a35 | ||
|
|
92ff39c168 | ||
|
|
41f1569c46 | ||
|
|
0111f6216c | ||
|
|
4bc85f777f | ||
|
|
af3bee742f | ||
|
|
99cafae1ec | ||
|
|
50f2d2b5ab | ||
|
|
ea23f18e94 | ||
|
|
145dd33da1 | ||
|
|
6ca7eb79bc | ||
|
|
58abc757fd | ||
|
|
d34ba76eb6 | ||
|
|
73467f00e3 | ||
|
|
c8ed22def3 | ||
|
|
4045852e6f | ||
|
|
f4371b3f03 | ||
|
|
e0dc8154b3 | ||
|
|
ae07582d0a | ||
|
|
a6a028594d | ||
|
|
b3d44dbe6f | ||
|
|
24d6743d57 | ||
|
|
fbc3bb872b | ||
|
|
46c12308cd | ||
|
|
26ecf63ab4 | ||
|
|
4f1536479e | ||
|
|
878ab916d2 | ||
|
|
b02a20e4dc | ||
|
|
af1e8a347e | ||
|
|
457b7bf24f | ||
|
|
97e2569f02 | ||
|
|
ba85d4c3bb | ||
|
|
98844c20a7 | ||
|
|
ca62264c50 | ||
|
|
821bcdef75 | ||
|
|
a15e0e0657 | ||
|
|
09533e77da | ||
|
|
97959b5e5c | ||
|
|
b8ee8c4eee | ||
|
|
8320160fe2 | ||
|
|
3c75adb236 | ||
|
|
1d596f616d | ||
|
|
c0657a4ca7 | ||
|
|
d9d89eeabc | ||
|
|
739b20bd13 | ||
|
|
601cc6e887 | ||
|
|
034f4d5734 | ||
|
|
049bd09150 | ||
|
|
bf1b1fac49 | ||
|
|
01c4bd73dc | ||
|
|
093f2dd4a6 | ||
|
|
145ecb85c2 | ||
|
|
c4cc6bd1bf | ||
|
|
caa6e65e38 | ||
|
|
6c2af8b421 | ||
|
|
fe2ca6e6e7 | ||
|
|
d3622f9c37 | ||
|
|
fd70ac1173 | ||
|
|
b06a479240 | ||
|
|
f1e7393e30 | ||
|
|
c716ecb916 | ||
|
|
7625202891 | ||
|
|
9b01bb00d2 | ||
|
|
24939e8fa4 | ||
|
|
bbfb32b136 | ||
|
|
e5ba6c5406 | ||
|
|
b563cd1235 | ||
|
|
d91cc257f9 | ||
|
|
5b7382765c | ||
|
|
9a198e8ef4 | ||
|
|
f18fca0729 | ||
|
|
ac69b89e82 | ||
|
|
05de7277ab | ||
|
|
d871598d20 | ||
|
|
00a1cd9395 | ||
|
|
15dffb3dde | ||
|
|
fcee7212ce | ||
|
|
6e5ac301ce | ||
|
|
56d6c1657a | ||
|
|
afaa1e73ab | ||
|
|
a034f5db0d | ||
|
|
584a494b83 | ||
|
|
01e18c2fc3 | ||
|
|
ee7ce3954a | ||
|
|
267821831c | ||
|
|
4de04da27a | ||
|
|
04da8a10eb | ||
|
|
85647dfced | ||
|
|
f645ca015f | ||
|
|
f808f50fa6 | ||
|
|
5f27c1fa25 | ||
|
|
ba47c9b925 | ||
|
|
b194d5d0e2 | ||
|
|
776cab96b1 | ||
|
|
38711233c5 | ||
|
|
ecd9e1f26e | ||
|
|
1fed1ed577 | ||
|
|
0fe718b1d9 | ||
|
|
dcf6f046d9 | ||
|
|
4240017cb6 | ||
|
|
d8aaaeb378 | ||
|
|
06285f0bf1 | ||
|
|
eaf2c61bef | ||
|
|
bff113760a | ||
|
|
7ae8538847 | ||
|
|
d9b058c694 | ||
|
|
6bcf67e051 | ||
|
|
23ca7e3733 | ||
|
|
b060cbf4ec | ||
|
|
2bbf32a18b | ||
|
|
206e94d20c | ||
|
|
f0b0614dd7 | ||
|
|
dfdf1b54c6 | ||
|
|
3ae3233e65 | ||
|
|
6781d5e3c8 | ||
|
|
b275273044 | ||
|
|
8dfc896cfa | ||
|
|
70fa9ff4c0 | ||
|
|
3d56e13b38 | ||
|
|
0ab9cc30d2 | ||
|
|
c03ed6d3a1 | ||
|
|
5d00494f8d | ||
|
|
79d3901859 | ||
|
|
0f7ebff81e | ||
|
|
375e612ac5 | ||
|
|
baaf058380 | ||
|
|
0c870775c4 | ||
|
|
bd5a5b3ae6 | ||
|
|
b6246dcf12 | ||
|
|
fb8b1fd1c9 | ||
|
|
d0cdd12521 | ||
|
|
0eff02dab9 | ||
|
|
73da4b7215 | ||
|
|
cdff1bde22 | ||
|
|
e8d85b6ded | ||
|
|
8f1ad8a4e5 | ||
|
|
57883eed0f | ||
|
|
4ec6d10969 | ||
|
|
0fe6767d6b | ||
|
|
0e0d4fe990 | ||
|
|
e196a397ad | ||
|
|
510a916f82 | ||
|
|
be955a9721 | ||
|
|
77414813b4 | ||
|
|
cc278cea00 | ||
|
|
fadd7e056d | ||
|
|
6dc101ffec |
File diff suppressed because it is too large
Load Diff
@@ -17,18 +17,29 @@
|
||||
"prefer-const": ["error", {
|
||||
"destructuring": "all"
|
||||
}],
|
||||
"standard/no-callback-literal": "off",
|
||||
"node/no-deprecated-api": 0
|
||||
},
|
||||
"parserOptions": {
|
||||
"ecmaVersion": 6,
|
||||
"sourceType": "module"
|
||||
},
|
||||
"globals": {
|
||||
"standardScheme": "readonly"
|
||||
},
|
||||
"overrides": [
|
||||
{
|
||||
"files": "*.js",
|
||||
"rules": {
|
||||
"@typescript-eslint/no-unused-vars": "off"
|
||||
}
|
||||
},
|
||||
{
|
||||
"files": "*.d.ts",
|
||||
"rules": {
|
||||
"no-useless-constructor": "off",
|
||||
"@typescript-eslint/no-unused-vars": "off"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
10
.github/ISSUE_TEMPLATE/security_report.md
vendored
10
.github/ISSUE_TEMPLATE/security_report.md
vendored
@@ -1,10 +0,0 @@
|
||||
---
|
||||
name: Security report
|
||||
about: Do not create an issue for security reports, send an email to security@electronjs.org
|
||||
|
||||
---
|
||||
|
||||
### Notice
|
||||
|
||||
**DO NOT** create an issue for security reports.
|
||||
Send an email to: **security@electronjs.org**.
|
||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -65,3 +65,4 @@ ts-gen
|
||||
|
||||
# Used to accelerate CI builds
|
||||
.depshash
|
||||
.depshash-target
|
||||
82
BUILD.gn
82
BUILD.gn
@@ -1,8 +1,10 @@
|
||||
import("//build/config/locales.gni")
|
||||
import("//build/config/ui.gni")
|
||||
import("//build/config/win/manifest.gni")
|
||||
import("//components/spellcheck/spellcheck_build_features.gni")
|
||||
import("//content/public/app/mac_helpers.gni")
|
||||
import("//pdf/features.gni")
|
||||
import("//ppapi/buildflags/buildflags.gni")
|
||||
import("//printing/buildflags/buildflags.gni")
|
||||
import("//testing/test.gni")
|
||||
import("//third_party/ffmpeg/ffmpeg_options.gni")
|
||||
@@ -21,6 +23,7 @@ import("buildflags/buildflags.gni")
|
||||
import("electron_paks.gni")
|
||||
import("filenames.auto.gni")
|
||||
import("filenames.gni")
|
||||
import("filenames.hunspell.gni")
|
||||
|
||||
if (is_mac) {
|
||||
import("//build/config/mac/rules.gni")
|
||||
@@ -351,19 +354,20 @@ source_set("electron_lib") {
|
||||
":resources",
|
||||
"buildflags",
|
||||
"chromium_src:chrome",
|
||||
"native_mate",
|
||||
"chromium_src:chrome_spellchecker",
|
||||
"shell/common/api:mojo",
|
||||
"//base:base_static",
|
||||
"//base/allocator:buildflags",
|
||||
"//chrome/app/resources:platform_locale_settings",
|
||||
"//chrome/services/printing/public/mojom",
|
||||
"//components/certificate_transparency",
|
||||
"//components/language/core/browser",
|
||||
"//components/net_log",
|
||||
"//components/network_hints/common",
|
||||
"//components/network_hints/browser",
|
||||
"//components/network_hints/common:mojo_bindings",
|
||||
"//components/network_hints/renderer",
|
||||
"//components/network_session_configurator/common",
|
||||
"//components/prefs",
|
||||
"//components/spellcheck/renderer",
|
||||
"//components/viz/host",
|
||||
"//components/viz/service",
|
||||
"//content/public/browser",
|
||||
@@ -546,6 +550,10 @@ source_set("electron_lib") {
|
||||
]
|
||||
|
||||
sources += filenames.lib_sources_nss
|
||||
sources += [
|
||||
"shell/browser/ui/gtk_util.cc",
|
||||
"shell/browser/ui/gtk_util.h",
|
||||
]
|
||||
}
|
||||
if (is_win) {
|
||||
libs += [ "dwmapi.lib" ]
|
||||
@@ -569,8 +577,12 @@ source_set("electron_lib") {
|
||||
deps += [ "//third_party/crashpad/crashpad/client" ]
|
||||
}
|
||||
|
||||
if (enable_pdf) {
|
||||
deps += [ "//pdf" ]
|
||||
if (enable_plugins) {
|
||||
deps += [ "chromium_src:plugins" ]
|
||||
sources += [
|
||||
"shell/renderer/pepper_helper.cc",
|
||||
"shell/renderer/pepper_helper.h",
|
||||
]
|
||||
}
|
||||
|
||||
if (enable_run_as_node) {
|
||||
@@ -654,10 +666,6 @@ source_set("electron_lib") {
|
||||
]
|
||||
}
|
||||
|
||||
if (enable_pepper_flash) {
|
||||
deps += [ "components/pepper_flash" ]
|
||||
}
|
||||
|
||||
public_deps += [ "shell/common/extensions/api:extensions_features" ]
|
||||
deps += [
|
||||
"//components/pref_registry",
|
||||
@@ -671,6 +679,22 @@ source_set("electron_lib") {
|
||||
if (enable_electron_extensions) {
|
||||
sources += filenames.lib_sources_extensions
|
||||
}
|
||||
|
||||
if (enable_pdf) {
|
||||
# Printing depends on some //pdf code, so it needs to be built even if the
|
||||
# pdf viewer isn't enabled.
|
||||
deps += [ "//pdf" ]
|
||||
}
|
||||
if (enable_pdf_viewer) {
|
||||
deps += [
|
||||
"//components/pdf/browser",
|
||||
"//components/pdf/renderer",
|
||||
]
|
||||
sources += [
|
||||
"shell/browser/electron_pdf_web_contents_helper_client.cc",
|
||||
"shell/browser/electron_pdf_web_contents_helper_client.h",
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
electron_paks("packed_resources") {
|
||||
@@ -705,7 +729,6 @@ if (is_mac) {
|
||||
public_deps += [ "//third_party/icu:icudata" ]
|
||||
}
|
||||
if (v8_use_external_startup_data) {
|
||||
sources += [ "$root_out_dir/natives_blob.bin" ]
|
||||
public_deps += [ "//v8" ]
|
||||
if (use_v8_context_snapshot) {
|
||||
sources += [ "$root_out_dir/v8_context_snapshot.bin" ]
|
||||
@@ -1265,9 +1288,14 @@ template("dist_zip") {
|
||||
"outputs",
|
||||
"testonly",
|
||||
])
|
||||
flatten = false
|
||||
if (defined(invoker.flatten)) {
|
||||
flatten = invoker.flatten
|
||||
}
|
||||
args = rebase_path(outputs + [ _runtime_deps_file ], root_build_dir) + [
|
||||
target_cpu,
|
||||
target_os,
|
||||
"$flatten",
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -1342,17 +1370,41 @@ dist_zip("electron_chromedriver_zip") {
|
||||
]
|
||||
}
|
||||
|
||||
mksnapshot_deps = [
|
||||
":licenses",
|
||||
"//tools/v8_context_snapshot:v8_context_snapshot_generator",
|
||||
"//v8:mksnapshot($v8_snapshot_toolchain)",
|
||||
]
|
||||
|
||||
group("electron_mksnapshot") {
|
||||
public_deps = mksnapshot_deps
|
||||
}
|
||||
|
||||
dist_zip("electron_mksnapshot_zip") {
|
||||
data_deps = [
|
||||
"//v8:mksnapshot($v8_snapshot_toolchain)",
|
||||
"//tools/v8_context_snapshot:v8_context_snapshot_generator",
|
||||
":licenses",
|
||||
]
|
||||
data_deps = mksnapshot_deps
|
||||
outputs = [
|
||||
"$root_build_dir/mksnapshot.zip",
|
||||
]
|
||||
}
|
||||
|
||||
copy("hunspell_dictionaries") {
|
||||
sources = hunspell_dictionaries + hunspell_licenses
|
||||
outputs = [
|
||||
"$target_gen_dir/electron_hunspell/{{source_file_part}}",
|
||||
]
|
||||
}
|
||||
|
||||
dist_zip("hunspell_dictionaries_zip") {
|
||||
data_deps = [
|
||||
":hunspell_dictionaries",
|
||||
]
|
||||
flatten = true
|
||||
|
||||
outputs = [
|
||||
"$root_build_dir/hunspell_dictionaries.zip",
|
||||
]
|
||||
}
|
||||
|
||||
group("electron") {
|
||||
public_deps = [
|
||||
":electron_app",
|
||||
|
||||
4
DEPS
4
DEPS
@@ -11,7 +11,7 @@ gclient_gn_args = [
|
||||
|
||||
vars = {
|
||||
'chromium_version':
|
||||
'c3a0220e7bde049d599a8332b9b2785b0178be74',
|
||||
'dc9525d251bf30828899e4cd7161f6dc6507023f',
|
||||
'node_version':
|
||||
'v12.13.0',
|
||||
'nan_version':
|
||||
@@ -114,7 +114,7 @@ hooks = [
|
||||
'pattern': 'src/electron/script/update-external-binaries.py',
|
||||
'condition': 'download_external_binaries',
|
||||
'action': [
|
||||
'python',
|
||||
'python3',
|
||||
'src/electron/script/update-external-binaries.py',
|
||||
],
|
||||
},
|
||||
|
||||
50
Dockerfile
50
Dockerfile
@@ -1,50 +0,0 @@
|
||||
FROM ubuntu:18.04
|
||||
|
||||
RUN groupadd --gid 1000 builduser \
|
||||
&& useradd --uid 1000 --gid builduser --shell /bin/bash --create-home builduser
|
||||
|
||||
# Set up TEMP directory
|
||||
ENV TEMP=/tmp
|
||||
RUN chmod a+rwx /tmp
|
||||
|
||||
# Install Linux packages
|
||||
ADD build/install-build-deps.sh /setup/install-build-deps.sh
|
||||
RUN echo ttf-mscorefonts-installer msttcorefonts/accepted-mscorefonts-eula select true | debconf-set-selections
|
||||
RUN dpkg --add-architecture i386
|
||||
RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y \
|
||||
curl \
|
||||
libnotify-bin \
|
||||
locales \
|
||||
lsb-release \
|
||||
nano \
|
||||
python-dbus \
|
||||
python-pip \
|
||||
python-setuptools \
|
||||
sudo \
|
||||
vim-nox \
|
||||
wget \
|
||||
g++-multilib \
|
||||
libgl1:i386 \
|
||||
&& /setup/install-build-deps.sh --syms --no-prompt --no-chromeos-fonts --lib32 --arm \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Install Node.js
|
||||
RUN curl -sL https://deb.nodesource.com/setup_10.x | bash - \
|
||||
&& DEBIAN_FRONTEND=noninteractive apt-get install -y nodejs \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# crcmod is required by gsutil, which is used for filling the gclient git cache
|
||||
RUN pip install -U crcmod
|
||||
|
||||
# dbusmock is needed for Electron tests
|
||||
RUN pip install python-dbusmock
|
||||
|
||||
RUN mkdir /tmp/workspace
|
||||
RUN chown builduser:builduser /tmp/workspace
|
||||
|
||||
# Add xvfb init script
|
||||
ADD tools/xvfb-init.sh /etc/init.d/xvfb
|
||||
RUN chmod a+x /etc/init.d/xvfb
|
||||
|
||||
USER builduser
|
||||
WORKDIR /home/builduser
|
||||
@@ -1,59 +0,0 @@
|
||||
FROM arm32v7/ubuntu:18.04
|
||||
|
||||
RUN groupadd --gid 1000 builduser \
|
||||
&& useradd --uid 1000 --gid builduser --shell /bin/bash --create-home builduser
|
||||
|
||||
# Set up TEMP directory
|
||||
ENV TEMP=/tmp
|
||||
RUN chmod a+rwx /tmp
|
||||
|
||||
RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y \
|
||||
bison \
|
||||
build-essential \
|
||||
clang \
|
||||
curl \
|
||||
gperf \
|
||||
git \
|
||||
libasound2 \
|
||||
libasound2-dev \
|
||||
libcap-dev \
|
||||
libcups2-dev \
|
||||
libdbus-1-dev \
|
||||
libgnome-keyring-dev \
|
||||
libgtk2.0-0 \
|
||||
libgtk2.0-dev \
|
||||
libgtk-3-0 \
|
||||
libgtk-3-dev \
|
||||
libnotify-bin \
|
||||
libnss3 \
|
||||
libnss3-dev \
|
||||
libxss1 \
|
||||
libxtst-dev \
|
||||
libxtst6 \
|
||||
lsb-release \
|
||||
locales \
|
||||
nano \
|
||||
python-setuptools \
|
||||
python-pip \
|
||||
python-dbusmock \
|
||||
sudo \
|
||||
unzip \
|
||||
wget \
|
||||
xvfb \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Install Node.js
|
||||
RUN curl -sL https://deb.nodesource.com/setup_10.x | bash - \
|
||||
&& DEBIAN_FRONTEND=noninteractive apt-get install -y nodejs \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# crcmod is required by gsutil, which is used for filling the gclient git cache
|
||||
RUN pip install -U crcmod
|
||||
|
||||
ADD tools/xvfb-init.sh /etc/init.d/xvfb
|
||||
RUN chmod a+x /etc/init.d/xvfb
|
||||
|
||||
RUN usermod -aG sudo builduser
|
||||
RUN echo 'builduser ALL=(ALL:ALL) NOPASSWD:ALL' >> /etc/sudoers
|
||||
|
||||
WORKDIR /home/builduser
|
||||
@@ -1,65 +0,0 @@
|
||||
FROM arm64v8/ubuntu:18.04
|
||||
|
||||
RUN groupadd --gid 1000 builduser \
|
||||
&& useradd --uid 1000 --gid builduser --shell /bin/bash --create-home builduser
|
||||
|
||||
# Set up TEMP directory
|
||||
ENV TEMP=/tmp
|
||||
RUN chmod a+rwx /tmp
|
||||
|
||||
RUN dpkg --add-architecture armhf
|
||||
|
||||
RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y \
|
||||
bison \
|
||||
build-essential \
|
||||
clang \
|
||||
curl \
|
||||
gperf \
|
||||
git \
|
||||
libasound2 \
|
||||
libasound2-dev \
|
||||
libc6:armhf \
|
||||
libcap-dev \
|
||||
libcups2-dev \
|
||||
libdbus-1-dev \
|
||||
libgnome-keyring-dev \
|
||||
libgtk2.0-0 \
|
||||
libgtk2.0-dev \
|
||||
libgtk-3-0 \
|
||||
libgtk-3-dev \
|
||||
libnotify-bin \
|
||||
libnss3 \
|
||||
libnss3-dev \
|
||||
libstdc++6:armhf \
|
||||
libxss1 \
|
||||
libxtst-dev \
|
||||
libxtst6 \
|
||||
lsb-release \
|
||||
locales \
|
||||
nano \
|
||||
python-setuptools \
|
||||
python-pip \
|
||||
sudo \
|
||||
unzip \
|
||||
wget \
|
||||
xvfb \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Install Node.js
|
||||
RUN curl -sL https://deb.nodesource.com/setup_10.x | bash - \
|
||||
&& DEBIAN_FRONTEND=noninteractive apt-get install -y nodejs \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# crcmod is required by gsutil, which is used for filling the gclient git cache
|
||||
RUN pip install -U crcmod
|
||||
|
||||
# dbusmock is needed for Electron tests
|
||||
RUN pip install python-dbusmock
|
||||
|
||||
ADD tools/xvfb-init.sh /etc/init.d/xvfb
|
||||
RUN chmod a+x /etc/init.d/xvfb
|
||||
|
||||
RUN usermod -aG sudo builduser
|
||||
RUN echo 'builduser ALL=(ALL:ALL) NOPASSWD:ALL' >> /etc/sudoers
|
||||
|
||||
WORKDIR /home/builduser
|
||||
@@ -1 +1 @@
|
||||
8.0.0-nightly.20191023
|
||||
9.0.0-nightly.20191208
|
||||
46
appveyor.yml
46
appveyor.yml
@@ -1,5 +1,5 @@
|
||||
# The config expects the following environment variables to be set:
|
||||
# - "GN_CONFIG" Build type. One of {'debug', 'testing', 'release'}.
|
||||
# - "GN_CONFIG" Build type. One of {'testing', 'release'}.
|
||||
# - "GN_EXTRA_ARGS" Additional gn arguments for a build config,
|
||||
# e.g. 'target_cpu="x86"' to build for a 32bit platform.
|
||||
# https://gn.googlesource.com/gn/+/master/docs/reference.md#target_cpu
|
||||
@@ -29,7 +29,7 @@
|
||||
|
||||
version: 1.0.{build}
|
||||
build_cloud: libcc-20
|
||||
image: vs2017-15.9-10.0.18362
|
||||
image: vs2019-16.3-10.0.18362
|
||||
environment:
|
||||
GIT_CACHE_PATH: C:\Users\electron\libcc_cache
|
||||
ELECTRON_OUT_DIR: Default
|
||||
@@ -50,6 +50,12 @@ build_script:
|
||||
- ps: >-
|
||||
if(($env:APPVEYOR_PULL_REQUEST_HEAD_REPO_NAME -split "/")[0] -eq ($env:APPVEYOR_REPO_NAME -split "/")[0]) {
|
||||
Write-warning "Skipping PR build for branch"; Exit-AppveyorBuild
|
||||
} else {
|
||||
node script/yarn.js install --frozen-lockfile
|
||||
|
||||
if ($(node script/doc-only-change.js --prNumber=$env:APPVEYOR_PULL_REQUEST_NUMBER --prBranch=$env:APPVEYOR_REPO_BRANCH;$LASTEXITCODE -eq 0)) {
|
||||
Write-warning "Skipping build for doc only change"; Exit-AppveyorBuild
|
||||
}
|
||||
}
|
||||
- echo "Building $env:GN_CONFIG build"
|
||||
- git config --global core.longpaths true
|
||||
@@ -70,10 +76,35 @@ build_script:
|
||||
--unmanaged
|
||||
%GCLIENT_EXTRA_ARGS%
|
||||
"https://github.com/electron/electron"
|
||||
- gclient sync --with_branch_heads --with_tags --reset
|
||||
- ps: >-
|
||||
if ($env:GN_CONFIG -eq 'release') {
|
||||
gclient sync --with_branch_heads --with_tags --reset
|
||||
} else {
|
||||
cd src\electron
|
||||
node script\generate-deps-hash.js
|
||||
$depshash = Get-Content .\.depshash -Raw
|
||||
$zipfile = "Z:\$depshash.7z"
|
||||
cd ..\..
|
||||
if (Test-Path -Path $zipfile) {
|
||||
# file exists, unzip and then gclient sync
|
||||
7z x -y $zipfile -mmt=30 -aoa
|
||||
# update external binaries
|
||||
python src/electron/script/update-external-binaries.py
|
||||
} else {
|
||||
# file does not exist, gclient sync, then zip
|
||||
gclient sync --with_branch_heads --with_tags --reset
|
||||
if ($env:TARGET_ARCH -ne 'ia32') {
|
||||
# archive current source for future use
|
||||
# only run on x64/woa to avoid contention saving
|
||||
if ($(7z a $zipfile src -xr!android_webview -xr!electron -xr'!*\.git' -xr!third_party\WebKit\LayoutTests! -xr!third_party\blink\web_tests -xr!third_party\blink\perf_tests -slp -t7z -mmt=30;$LASTEXITCODE -ne 0)) {
|
||||
Write-warning "Could not save source to shared drive; continuing anyway"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
- cd src
|
||||
- ps: $env:BUILD_CONFIG_PATH="//electron/build/args/%GN_CONFIG%.gn"
|
||||
- gn gen out/Default "--args=import(\"%BUILD_CONFIG_PATH%\") %GN_EXTRA_ARGS%"
|
||||
- gn gen out/Default "--args=import(\"%BUILD_CONFIG_PATH%\") %GN_EXTRA_ARGS% cc_wrapper=\"%SCCACHE_PATH%\""
|
||||
- gn check out/Default //electron:electron_lib
|
||||
- gn check out/Default //electron:electron_app
|
||||
- gn check out/Default //electron:manifests
|
||||
@@ -85,8 +116,12 @@ build_script:
|
||||
- ninja -C out/Default electron:electron_dist_zip
|
||||
- ninja -C out/Default shell_browser_ui_unittests
|
||||
- ninja -C out/Default electron:electron_mksnapshot_zip
|
||||
- ninja -C out/Default electron:hunspell_dictionaries_zip
|
||||
- ninja -C out/Default electron:electron_chromedriver_zip
|
||||
- ninja -C out/Default third_party/electron_node:headers
|
||||
- cmd /C %SCCACHE_PATH% --show-stats
|
||||
- python electron/build/profile_toolchain.py --output-json=out/Default/windows_toolchain_profile.json
|
||||
- appveyor PushArtifact out/Default/windows_toolchain_profile.json
|
||||
- appveyor PushArtifact out/Default/dist.zip
|
||||
- appveyor PushArtifact out/Default/shell_browser_ui_unittests.exe
|
||||
- appveyor PushArtifact out/Default/chromedriver.zip
|
||||
@@ -94,6 +129,7 @@ build_script:
|
||||
- 7z a node_headers.zip out\Default\gen\node_headers
|
||||
- appveyor PushArtifact node_headers.zip
|
||||
- appveyor PushArtifact out/Default/mksnapshot.zip
|
||||
- appveyor PushArtifact out/Default/hunspell_dictionaries.zip
|
||||
- appveyor PushArtifact out/Default/electron.lib
|
||||
- ps: >-
|
||||
if ($env:GN_CONFIG -eq 'release') {
|
||||
@@ -127,7 +163,7 @@ test_script:
|
||||
echo "Skipping tests for $env:GN_CONFIG build"
|
||||
}
|
||||
- cd electron
|
||||
- if "%RUN_TESTS%"=="true" ( echo Running test suite & node script/yarn test -- --ci --enable-logging)
|
||||
- if "%RUN_TESTS%"=="true" ( echo Running test suite & node script/yarn test -- --enable-logging)
|
||||
- cd ..
|
||||
- if "%RUN_TESTS%"=="true" ( echo Verifying non proprietary ffmpeg & python electron\script\verify-ffmpeg.py --build-dir out\Default --source-root %cd% --ffmpeg-path out\ffmpeg )
|
||||
- echo "About to verify mksnapshot"
|
||||
|
||||
@@ -63,7 +63,7 @@ steps:
|
||||
set npm_config_nodedir=%cd%\out\Default\gen\node_headers
|
||||
set npm_config_arch=arm64
|
||||
cd electron
|
||||
node script/yarn test -- --ci --enable-logging --verbose
|
||||
node script/yarn test -- --enable-logging --verbose
|
||||
displayName: 'Run Electron tests'
|
||||
env:
|
||||
ELECTRON_OUT_DIR: Default
|
||||
@@ -89,4 +89,4 @@ steps:
|
||||
Get-Process | Where Name –Like "electron*" | Stop-Process
|
||||
Get-Process | Where Name –Like "MicrosoftEdge*" | Stop-Process
|
||||
displayName: 'Kill processes left running from last test run'
|
||||
condition: always()
|
||||
condition: always()
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
is_electron_build = true
|
||||
use_jumbo_build = true
|
||||
root_extra_deps = [ "//electron" ]
|
||||
|
||||
# Registry of NMVs --> https://github.com/nodejs/node/blob/master/doc/abi_version_registry.json
|
||||
@@ -21,9 +20,5 @@ angle_enable_vulkan_validation_layers = false
|
||||
|
||||
is_cfi = false
|
||||
|
||||
# TODO: Remove this and update CI to contain 10.14 SDK once
|
||||
# crbug.com/986701 is fixed.
|
||||
mac_sdk_min = "10.13"
|
||||
|
||||
# TODO: disabled due to crashes. re-enable.
|
||||
enable_osr = false
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
import("all.gn")
|
||||
is_debug = true
|
||||
is_component_build = true
|
||||
|
||||
# This may be guarded behind is_chrome_branded alongside
|
||||
# proprietary_codecs https://webrtc-review.googlesource.com/c/src/+/36321,
|
||||
# explicitly override here to build OpenH264 encoder/FFmpeg decoder.
|
||||
# The initialization of the decoder depends on whether ffmpeg has
|
||||
# been built with H.264 support.
|
||||
rtc_use_h264 = proprietary_codecs
|
||||
@@ -5,4 +5,3 @@ is_debug = false
|
||||
is_component_build = false
|
||||
is_component_ffmpeg = false
|
||||
symbol_level = 1
|
||||
use_jumbo_build = true
|
||||
|
||||
@@ -6,6 +6,8 @@ is_official_build = false
|
||||
dcheck_always_on = true
|
||||
symbol_level = 1
|
||||
|
||||
strip_absolute_paths_from_debug_symbols = false
|
||||
|
||||
# This may be guarded behind is_chrome_branded alongside
|
||||
# proprietary_codecs https://webrtc-review.googlesource.com/c/src/+/36321,
|
||||
# explicitly override here to build OpenH264 encoder/FFmpeg decoder.
|
||||
|
||||
98
build/profile_toolchain.py
Executable file
98
build/profile_toolchain.py
Executable file
@@ -0,0 +1,98 @@
|
||||
from __future__ import with_statement
|
||||
import contextlib
|
||||
import sys
|
||||
import os
|
||||
import optparse
|
||||
import json
|
||||
|
||||
sys.path.append("%s/../../build" % os.path.dirname(os.path.realpath(__file__)))
|
||||
|
||||
import find_depot_tools
|
||||
from vs_toolchain import \
|
||||
SetEnvironmentAndGetRuntimeDllDirs, \
|
||||
SetEnvironmentAndGetSDKDir, \
|
||||
GetVisualStudioVersion, \
|
||||
NormalizePath
|
||||
|
||||
sys.path.append("%s/win_toolchain" % find_depot_tools.add_depot_tools_to_path())
|
||||
|
||||
from get_toolchain_if_necessary import CalculateHash
|
||||
|
||||
|
||||
@contextlib.contextmanager
|
||||
def cwd(dir):
|
||||
curdir = os.getcwd()
|
||||
try:
|
||||
os.chdir(dir)
|
||||
yield
|
||||
finally:
|
||||
os.chdir(curdir)
|
||||
|
||||
|
||||
def calculate_hash(root):
|
||||
with cwd(root):
|
||||
return CalculateHash('.', None)
|
||||
|
||||
def windows_installed_software():
|
||||
import win32com.client
|
||||
strComputer = "."
|
||||
objWMIService = win32com.client.Dispatch("WbemScripting.SWbemLocator")
|
||||
objSWbemServices = objWMIService.ConnectServer(strComputer, "root\cimv2")
|
||||
colItems = objSWbemServices.ExecQuery("Select * from Win32_Product")
|
||||
items = []
|
||||
|
||||
for objItem in colItems:
|
||||
item = {}
|
||||
if objItem.Caption:
|
||||
item['caption'] = objItem.Caption
|
||||
if objItem.Caption:
|
||||
item['description'] = objItem.Description
|
||||
if objItem.InstallDate:
|
||||
item['install_date'] = objItem.InstallDate
|
||||
if objItem.InstallDate2:
|
||||
item['install_date_2'] = objItem.InstallDate2
|
||||
if objItem.InstallLocation:
|
||||
item['install_location'] = objItem.InstallLocation
|
||||
if objItem.Name:
|
||||
item['name'] = objItem.Name
|
||||
if objItem.SKUNumber:
|
||||
item['sku_number'] = objItem.SKUNumber
|
||||
if objItem.Vendor:
|
||||
item['vendor'] = objItem.Vendor
|
||||
if objItem.Version:
|
||||
item['version'] = objItem.Version
|
||||
items.append(item)
|
||||
|
||||
return items
|
||||
|
||||
|
||||
def windows_profile():
|
||||
runtime_dll_dirs = SetEnvironmentAndGetRuntimeDllDirs()
|
||||
win_sdk_dir = SetEnvironmentAndGetSDKDir()
|
||||
path = NormalizePath(os.environ['GYP_MSVS_OVERRIDE_PATH'])
|
||||
|
||||
return {
|
||||
'pwd': os.getcwd(), # since current windows executable are symbols path dependant, profile the current directory too
|
||||
'installed_software': windows_installed_software(),
|
||||
'sdks': [
|
||||
{'name': 'vs', 'path': path, 'hash': calculate_hash(path)},
|
||||
{'name': 'wsdk', 'path': win_sdk_dir, 'hash': calculate_hash(win_sdk_dir)}
|
||||
],
|
||||
'runtime_lib_dirs': runtime_dll_dirs,
|
||||
}
|
||||
|
||||
|
||||
def main(options):
|
||||
if sys.platform == 'win32':
|
||||
with open(options.output_json, 'wb') as f:
|
||||
json.dump(windows_profile(), f)
|
||||
else:
|
||||
raise OSError("Unsupported OS")
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
parser = optparse.OptionParser()
|
||||
parser.add_option('--output-json', metavar='FILE', default='profile.json',
|
||||
help='write information about toolchain to FILE')
|
||||
options, args = parser.parse_args()
|
||||
sys.exit(main(options))
|
||||
@@ -1,9 +1,50 @@
|
||||
import("//build/config/mac/mac_sdk.gni")
|
||||
|
||||
# This is imported from /ios becuase this functionality was moved
|
||||
# after Chromium stopped using xib files for macOS menu functionality
|
||||
# See https://chromium-review.googlesource.com/c/chromium/src/+/1648695
|
||||
import("//build/config/ios/rules.gni")
|
||||
# Template to compile .xib and .storyboard files.
|
||||
# (copied from src/build/config/ios/rules.gni)
|
||||
#
|
||||
# Arguments
|
||||
#
|
||||
# sources:
|
||||
# list of string, sources to compile
|
||||
#
|
||||
# ibtool_flags:
|
||||
# (optional) list of string, additional flags to pass to the ibtool
|
||||
template("compile_ib_files") {
|
||||
action_foreach(target_name) {
|
||||
forward_variables_from(invoker,
|
||||
[
|
||||
"testonly",
|
||||
"visibility",
|
||||
])
|
||||
assert(defined(invoker.sources),
|
||||
"sources must be specified for $target_name")
|
||||
assert(defined(invoker.output_extension),
|
||||
"output_extension must be specified for $target_name")
|
||||
|
||||
ibtool_flags = []
|
||||
if (defined(invoker.ibtool_flags)) {
|
||||
ibtool_flags = invoker.ibtool_flags
|
||||
}
|
||||
|
||||
_output_extension = invoker.output_extension
|
||||
|
||||
script = "//build/config/ios/compile_ib_files.py"
|
||||
sources = invoker.sources
|
||||
outputs = [
|
||||
"$target_gen_dir/$target_name/{{source_name_part}}.$_output_extension",
|
||||
]
|
||||
args = [
|
||||
"--input",
|
||||
"{{source}}",
|
||||
"--output",
|
||||
rebase_path(
|
||||
"$target_gen_dir/$target_name/{{source_name_part}}.$_output_extension",
|
||||
root_build_dir),
|
||||
]
|
||||
args += ibtool_flags
|
||||
}
|
||||
}
|
||||
|
||||
# Template is copied here from Chromium but was removed in
|
||||
# https://chromium-review.googlesource.com/c/chromium/src/+/1637981
|
||||
|
||||
@@ -74,7 +74,10 @@ module.exports = ({
|
||||
global: ['@electron/internal/renderer/webpack-provider', '_global'],
|
||||
Buffer: ['@electron/internal/renderer/webpack-provider', 'Buffer'],
|
||||
})
|
||||
] : [])
|
||||
] : []),
|
||||
new webpack.ProvidePlugin({
|
||||
Promise: ['@electron/internal/common/webpack-globals-provider', 'Promise'],
|
||||
}),
|
||||
]
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,13 +46,14 @@ def execute(argv):
|
||||
raise e
|
||||
|
||||
def main(argv):
|
||||
dist_zip, runtime_deps, target_cpu, target_os = argv
|
||||
dist_zip, runtime_deps, target_cpu, target_os, flatten_val = argv
|
||||
should_flatten = flatten_val == "true"
|
||||
dist_files = set()
|
||||
with open(runtime_deps) as f:
|
||||
for dep in f.readlines():
|
||||
dep = dep.strip()
|
||||
dist_files.add(dep)
|
||||
if sys.platform == 'darwin':
|
||||
if sys.platform == 'darwin' and not should_flatten:
|
||||
execute(['zip', '-r', '-y', dist_zip] + list(dist_files))
|
||||
else:
|
||||
with zipfile.ZipFile(dist_zip, 'w', zipfile.ZIP_DEFLATED, allowZip64=True) as z:
|
||||
@@ -67,7 +68,7 @@ def main(argv):
|
||||
basename = os.path.basename(dep)
|
||||
dirname = os.path.dirname(dep)
|
||||
arcname = os.path.join(dirname, 'chrome-sandbox') if basename == 'chrome_sandbox' else dep
|
||||
z.write(dep, arcname)
|
||||
z.write(dep, os.path.basename(arcname) if should_flatten else arcname)
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.exit(main(sys.argv[1:]))
|
||||
|
||||
@@ -19,6 +19,7 @@ buildflag_header("buildflags") {
|
||||
"ENABLE_TTS=$enable_tts",
|
||||
"ENABLE_COLOR_CHOOSER=$enable_color_chooser",
|
||||
"ENABLE_ELECTRON_EXTENSIONS=$enable_electron_extensions",
|
||||
"ENABLE_BUILTIN_SPELLCHECKER=$enable_builtin_spellchecker",
|
||||
"ENABLE_PICTURE_IN_PICTURE=$enable_picture_in_picture",
|
||||
"OVERRIDE_LOCATION_PROVIDER=$enable_fake_location_provider",
|
||||
]
|
||||
|
||||
@@ -33,4 +33,7 @@ declare_args() {
|
||||
|
||||
# Enable Chrome extensions support.
|
||||
enable_electron_extensions = false
|
||||
|
||||
# Enable Spellchecker support
|
||||
enable_builtin_spellchecker = true
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
# found in the LICENSE file.
|
||||
|
||||
import("//build/config/ui.gni")
|
||||
import("//components/spellcheck/spellcheck_build_features.gni")
|
||||
import("//electron/buildflags/buildflags.gni")
|
||||
import("//printing/buildflags/buildflags.gni")
|
||||
import("//third_party/widevine/cdm/widevine.gni")
|
||||
@@ -31,6 +32,8 @@ static_library("chrome") {
|
||||
"//chrome/browser/icon_loader_win.cc",
|
||||
"//chrome/browser/icon_manager.cc",
|
||||
"//chrome/browser/icon_manager.h",
|
||||
"//chrome/browser/media/webrtc/system_media_capture_permissions_mac.h",
|
||||
"//chrome/browser/media/webrtc/system_media_capture_permissions_mac.mm",
|
||||
"//chrome/browser/net/chrome_mojo_proxy_resolver_factory.cc",
|
||||
"//chrome/browser/net/chrome_mojo_proxy_resolver_factory.h",
|
||||
"//chrome/browser/net/proxy_config_monitor.cc",
|
||||
@@ -39,6 +42,8 @@ static_library("chrome") {
|
||||
"//chrome/browser/net/proxy_service_factory.h",
|
||||
"//chrome/browser/predictors/preconnect_manager.cc",
|
||||
"//chrome/browser/predictors/preconnect_manager.h",
|
||||
"//chrome/browser/predictors/predictors_features.cc",
|
||||
"//chrome/browser/predictors/predictors_features.h",
|
||||
"//chrome/browser/predictors/proxy_lookup_client_impl.cc",
|
||||
"//chrome/browser/predictors/proxy_lookup_client_impl.h",
|
||||
"//chrome/browser/predictors/resolve_host_client_impl.cc",
|
||||
@@ -225,3 +230,132 @@ static_library("chrome") {
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
source_set("plugins") {
|
||||
sources = []
|
||||
deps = []
|
||||
libs = []
|
||||
|
||||
# browser side
|
||||
sources += [
|
||||
"//chrome/browser/renderer_host/pepper/chrome_browser_pepper_host_factory.cc",
|
||||
"//chrome/browser/renderer_host/pepper/chrome_browser_pepper_host_factory.h",
|
||||
"//chrome/browser/renderer_host/pepper/pepper_broker_message_filter.cc",
|
||||
"//chrome/browser/renderer_host/pepper/pepper_broker_message_filter.h",
|
||||
"//chrome/browser/renderer_host/pepper/pepper_isolated_file_system_message_filter.cc",
|
||||
"//chrome/browser/renderer_host/pepper/pepper_isolated_file_system_message_filter.h",
|
||||
]
|
||||
deps += [
|
||||
"//media:media_buildflags",
|
||||
"//ppapi/buildflags",
|
||||
"//ppapi/proxy:ipc",
|
||||
"//services/device/public/mojom",
|
||||
]
|
||||
if (enable_pepper_flash) {
|
||||
sources += [
|
||||
"//chrome/browser/renderer_host/pepper/pepper_flash_browser_host.cc",
|
||||
"//chrome/browser/renderer_host/pepper/pepper_flash_browser_host.h",
|
||||
"//chrome/browser/renderer_host/pepper/pepper_flash_clipboard_message_filter.cc",
|
||||
"//chrome/browser/renderer_host/pepper/pepper_flash_clipboard_message_filter.h",
|
||||
"//chrome/browser/renderer_host/pepper/pepper_flash_drm_host.cc",
|
||||
"//chrome/browser/renderer_host/pepper/pepper_flash_drm_host.h",
|
||||
]
|
||||
if (is_mac) {
|
||||
sources += [
|
||||
"//chrome/browser/renderer_host/pepper/monitor_finder_mac.h",
|
||||
"//chrome/browser/renderer_host/pepper/monitor_finder_mac.mm",
|
||||
]
|
||||
libs += [ "CoreGraphics.framework" ]
|
||||
}
|
||||
if (is_linux) {
|
||||
deps += [ "//components/services/font/public/cpp" ]
|
||||
}
|
||||
}
|
||||
|
||||
# renderer side
|
||||
sources += [
|
||||
"//chrome/renderer/pepper/chrome_renderer_pepper_host_factory.cc",
|
||||
"//chrome/renderer/pepper/chrome_renderer_pepper_host_factory.h",
|
||||
"//chrome/renderer/pepper/pepper_shared_memory_message_filter.cc",
|
||||
"//chrome/renderer/pepper/pepper_shared_memory_message_filter.h",
|
||||
]
|
||||
if (enable_pepper_flash) {
|
||||
sources += [
|
||||
"//chrome/renderer/pepper/pepper_flash_drm_renderer_host.cc",
|
||||
"//chrome/renderer/pepper/pepper_flash_drm_renderer_host.h",
|
||||
"//chrome/renderer/pepper/pepper_flash_font_file_host.cc",
|
||||
"//chrome/renderer/pepper/pepper_flash_font_file_host.h",
|
||||
"//chrome/renderer/pepper/pepper_flash_fullscreen_host.cc",
|
||||
"//chrome/renderer/pepper/pepper_flash_fullscreen_host.h",
|
||||
"//chrome/renderer/pepper/pepper_flash_menu_host.cc",
|
||||
"//chrome/renderer/pepper/pepper_flash_menu_host.h",
|
||||
"//chrome/renderer/pepper/pepper_flash_renderer_host.cc",
|
||||
"//chrome/renderer/pepper/pepper_flash_renderer_host.h",
|
||||
]
|
||||
}
|
||||
deps += [
|
||||
"//components/strings",
|
||||
"//media:media_buildflags",
|
||||
"//ppapi/host",
|
||||
"//ppapi/proxy",
|
||||
"//ppapi/proxy:ipc",
|
||||
"//ppapi/shared_impl",
|
||||
"//skia",
|
||||
]
|
||||
}
|
||||
|
||||
# This source set is just so we don't have to depend on all of //chrome/browser
|
||||
# You may have to add new files here during the upgrade if //chrome/browser/spellchecker
|
||||
# gets more files
|
||||
source_set("chrome_spellchecker") {
|
||||
sources = []
|
||||
deps = []
|
||||
libs = []
|
||||
|
||||
if (enable_builtin_spellchecker) {
|
||||
sources += [
|
||||
"//chrome/browser/spellchecker/spell_check_host_chrome_impl.cc",
|
||||
"//chrome/browser/spellchecker/spell_check_host_chrome_impl.h",
|
||||
"//chrome/browser/spellchecker/spellcheck_custom_dictionary.cc",
|
||||
"//chrome/browser/spellchecker/spellcheck_custom_dictionary.h",
|
||||
"//chrome/browser/spellchecker/spellcheck_factory.cc",
|
||||
"//chrome/browser/spellchecker/spellcheck_factory.h",
|
||||
"//chrome/browser/spellchecker/spellcheck_hunspell_dictionary.cc",
|
||||
"//chrome/browser/spellchecker/spellcheck_hunspell_dictionary.h",
|
||||
"//chrome/browser/spellchecker/spellcheck_language_blacklist_policy_handler.cc",
|
||||
"//chrome/browser/spellchecker/spellcheck_language_blacklist_policy_handler.h",
|
||||
"//chrome/browser/spellchecker/spellcheck_language_policy_handler.cc",
|
||||
"//chrome/browser/spellchecker/spellcheck_language_policy_handler.h",
|
||||
"//chrome/browser/spellchecker/spellcheck_service.cc",
|
||||
"//chrome/browser/spellchecker/spellcheck_service.h",
|
||||
"//chrome/common/pref_names.h",
|
||||
]
|
||||
|
||||
if (has_spellcheck_panel) {
|
||||
sources += [
|
||||
"//chrome/browser/spellchecker/spell_check_panel_host_impl.cc",
|
||||
"//chrome/browser/spellchecker/spell_check_panel_host_impl.h",
|
||||
]
|
||||
}
|
||||
|
||||
if (use_browser_spellchecker) {
|
||||
sources += [
|
||||
"//chrome/browser/spellchecker/spelling_request.cc",
|
||||
"//chrome/browser/spellchecker/spelling_request.h",
|
||||
]
|
||||
}
|
||||
|
||||
deps += [
|
||||
"//base:base_static",
|
||||
"//components/language/core/browser",
|
||||
"//components/spellcheck:buildflags",
|
||||
"//components/sync",
|
||||
]
|
||||
}
|
||||
|
||||
public_deps = [
|
||||
"//components/spellcheck/browser",
|
||||
"//components/spellcheck/common",
|
||||
"//components/spellcheck/renderer",
|
||||
]
|
||||
}
|
||||
|
||||
@@ -37,10 +37,8 @@ net::NSSCertDatabase* GetNSSCertDatabaseForResourceContext(
|
||||
// public and private slot.
|
||||
// Redirect any slot usage to this persistent slot on Linux.
|
||||
g_nss_cert_database = new net::NSSCertDatabase(
|
||||
crypto::ScopedPK11Slot(
|
||||
crypto::GetPersistentNSSKeySlot()) /* public slot */,
|
||||
crypto::ScopedPK11Slot(
|
||||
crypto::GetPersistentNSSKeySlot()) /* private slot */);
|
||||
crypto::ScopedPK11Slot(PK11_GetInternalKeySlot()) /* public slot */,
|
||||
crypto::ScopedPK11Slot(PK11_GetInternalKeySlot()) /* private slot */);
|
||||
}
|
||||
return g_nss_cert_database;
|
||||
}
|
||||
|
||||
@@ -1,62 +0,0 @@
|
||||
# Copyright (c) 2018 GitHub, Inc.
|
||||
# Use of this source code is governed by the MIT license that can be
|
||||
# found in the LICENSE file.
|
||||
|
||||
component("pepper_flash") {
|
||||
visibility = [ "//electron:electron_lib" ]
|
||||
defines = [ "IS_PEPPER_FLASH_IMPL" ]
|
||||
sources = [
|
||||
"//chrome/browser/renderer_host/pepper/chrome_browser_pepper_host_factory.cc",
|
||||
"//chrome/browser/renderer_host/pepper/chrome_browser_pepper_host_factory.h",
|
||||
"//chrome/browser/renderer_host/pepper/pepper_broker_message_filter.cc",
|
||||
"//chrome/browser/renderer_host/pepper/pepper_broker_message_filter.h",
|
||||
"//chrome/browser/renderer_host/pepper/pepper_flash_browser_host.cc",
|
||||
"//chrome/browser/renderer_host/pepper/pepper_flash_browser_host.h",
|
||||
"//chrome/browser/renderer_host/pepper/pepper_flash_clipboard_message_filter.cc",
|
||||
"//chrome/browser/renderer_host/pepper/pepper_flash_clipboard_message_filter.h",
|
||||
"//chrome/browser/renderer_host/pepper/pepper_flash_drm_host.cc",
|
||||
"//chrome/browser/renderer_host/pepper/pepper_flash_drm_host.h",
|
||||
"//chrome/browser/renderer_host/pepper/pepper_isolated_file_system_message_filter.cc",
|
||||
"//chrome/browser/renderer_host/pepper/pepper_isolated_file_system_message_filter.h",
|
||||
"//chrome/renderer/pepper/chrome_renderer_pepper_host_factory.cc",
|
||||
"//chrome/renderer/pepper/chrome_renderer_pepper_host_factory.h",
|
||||
"//chrome/renderer/pepper/pepper_flash_drm_renderer_host.cc",
|
||||
"//chrome/renderer/pepper/pepper_flash_drm_renderer_host.h",
|
||||
"//chrome/renderer/pepper/pepper_flash_font_file_host.cc",
|
||||
"//chrome/renderer/pepper/pepper_flash_font_file_host.h",
|
||||
"//chrome/renderer/pepper/pepper_flash_fullscreen_host.cc",
|
||||
"//chrome/renderer/pepper/pepper_flash_fullscreen_host.h",
|
||||
"//chrome/renderer/pepper/pepper_flash_menu_host.cc",
|
||||
"//chrome/renderer/pepper/pepper_flash_menu_host.h",
|
||||
"//chrome/renderer/pepper/pepper_flash_renderer_host.cc",
|
||||
"//chrome/renderer/pepper/pepper_flash_renderer_host.h",
|
||||
"//chrome/renderer/pepper/pepper_helper.cc",
|
||||
"//chrome/renderer/pepper/pepper_helper.h",
|
||||
"//chrome/renderer/pepper/pepper_shared_memory_message_filter.cc",
|
||||
"//chrome/renderer/pepper/pepper_shared_memory_message_filter.h",
|
||||
]
|
||||
deps = [
|
||||
"//content/public/browser",
|
||||
"//content/public/renderer",
|
||||
"//media:media_buildflags",
|
||||
"//ppapi/host",
|
||||
"//ppapi/proxy",
|
||||
"//ppapi/proxy:ipc",
|
||||
"//ppapi/shared_impl",
|
||||
"//services/device/public/mojom",
|
||||
"//skia",
|
||||
"//third_party/adobe/flash:flapper_version_h",
|
||||
"//ui/base",
|
||||
"//ui/base/clipboard",
|
||||
]
|
||||
if (is_mac) {
|
||||
sources += [
|
||||
"//chrome/browser/renderer_host/pepper/monitor_finder_mac.h",
|
||||
"//chrome/browser/renderer_host/pepper/monitor_finder_mac.mm",
|
||||
]
|
||||
libs = [ "CoreGraphics.framework" ]
|
||||
}
|
||||
if (is_linux) {
|
||||
deps += [ "//components/services/font/public/cpp" ]
|
||||
}
|
||||
}
|
||||
@@ -39,6 +39,7 @@ an issue:
|
||||
* [Using Electron's APIs](tutorial/application-architecture.md#using-electron-apis)
|
||||
* [Using Node.js APIs](tutorial/application-architecture.md#using-nodejs-apis)
|
||||
* [Using Native Node.js Modules](tutorial/using-native-node-modules.md)
|
||||
* [Performance Strategies](tutorial/performance.md)
|
||||
* Adding Features to Your App
|
||||
* [Notifications](tutorial/notifications.md)
|
||||
* [Recent Documents](tutorial/recent-documents.md)
|
||||
|
||||
@@ -314,10 +314,8 @@ Returns:
|
||||
|
||||
* `event` Event
|
||||
* `webContents` [WebContents](web-contents.md)
|
||||
* `request` Object
|
||||
* `method` String
|
||||
* `authenticationResponseDetails` Object
|
||||
* `url` URL
|
||||
* `referrer` URL
|
||||
* `authInfo` Object
|
||||
* `isProxy` Boolean
|
||||
* `scheme` String
|
||||
@@ -325,8 +323,8 @@ Returns:
|
||||
* `port` Integer
|
||||
* `realm` String
|
||||
* `callback` Function
|
||||
* `username` String
|
||||
* `password` String
|
||||
* `username` String (optional)
|
||||
* `password` String (optional)
|
||||
|
||||
Emitted when `webContents` wants to do basic auth.
|
||||
|
||||
@@ -337,12 +335,16 @@ should prevent the default behavior with `event.preventDefault()` and call
|
||||
```javascript
|
||||
const { app } = require('electron')
|
||||
|
||||
app.on('login', (event, webContents, request, authInfo, callback) => {
|
||||
app.on('login', (event, webContents, details, authInfo, callback) => {
|
||||
event.preventDefault()
|
||||
callback('username', 'secret')
|
||||
})
|
||||
```
|
||||
|
||||
If `callback` is called without a username or password, the authentication
|
||||
request will be cancelled and the authentication error will be returned to the
|
||||
page.
|
||||
|
||||
### Event: 'gpu-info-update'
|
||||
|
||||
Emitted whenever there is a GPU info update.
|
||||
@@ -485,18 +487,6 @@ Emitted when `remote.getCurrentWebContents()` is called in the renderer process
|
||||
Calling `event.preventDefault()` will prevent the object from being returned.
|
||||
Custom value can be returned by setting `event.returnValue`.
|
||||
|
||||
### Event: 'remote-get-guest-web-contents'
|
||||
|
||||
Returns:
|
||||
|
||||
* `event` Event
|
||||
* `webContents` [WebContents](web-contents.md)
|
||||
* `guestWebContents` [WebContents](web-contents.md)
|
||||
|
||||
Emitted when `<webview>.getWebContents()` is called in the renderer process of `webContents`.
|
||||
Calling `event.preventDefault()` will prevent the object from being returned.
|
||||
Custom value can be returned by setting `event.returnValue`.
|
||||
|
||||
## Methods
|
||||
|
||||
The `app` object has the following methods:
|
||||
@@ -770,6 +760,21 @@ macOS machine. Please refer to
|
||||
|
||||
The API uses the Windows Registry and LSCopyDefaultHandlerForURLScheme internally.
|
||||
|
||||
### `app.getApplicationNameForProtocol(url)`
|
||||
|
||||
* `url` String - a URL with the protocol name to check. Unlike the other
|
||||
methods in this family, this accepts an entire URL, including `://` at a
|
||||
minimum (e.g. `https://`).
|
||||
|
||||
Returns `String` - Name of the application handling the protocol, or an empty
|
||||
string if there is no handler. For instance, if Electron is the default
|
||||
handler of the URL, this could be `Electron` on Windows and Mac. However,
|
||||
don't rely on the precise format which is not guaranteed to remain unchanged.
|
||||
Expect a different format on Linux, possibly with a `.desktop` suffix.
|
||||
|
||||
This method returns the application name of the default handler for the protocol
|
||||
(aka URI scheme) of a URL.
|
||||
|
||||
### `app.setUserTasks(tasks)` _Windows_
|
||||
|
||||
* `tasks` [Task[]](structures/task.md) - Array of `Task` objects
|
||||
@@ -1298,7 +1303,7 @@ command line arguments that Chromium uses.
|
||||
|
||||
### `app.dock` _macOS_ _Readonly_
|
||||
|
||||
A [`Dock`](./dock.md) object that allows you to perform actions on your app icon in the user's
|
||||
A [`Dock`](./dock.md) `| undefined` object that allows you to perform actions on your app icon in the user's
|
||||
dock on macOS.
|
||||
|
||||
### `app.isPackaged` _Readonly_
|
||||
|
||||
@@ -6,6 +6,28 @@ Breaking changes will be documented here, and deprecation warnings added to JS c
|
||||
|
||||
The `FIXME` string is used in code comments to denote things that should be fixed for future releases. See https://github.com/electron/electron/search?q=fixme
|
||||
|
||||
## Planned Breaking API Changes (9.0)
|
||||
|
||||
### `<webview>.getWebContents()`
|
||||
|
||||
This API, which was deprecated in Electron 8.0, is now removed.
|
||||
|
||||
```js
|
||||
// Removed in Electron 9.0
|
||||
webview.getWebContents()
|
||||
// Replace with
|
||||
const { remote } = require('electron')
|
||||
remote.webContents.fromId(webview.getWebContentsId())
|
||||
```
|
||||
|
||||
### `webFrame.setLayoutZoomLevelLimits()`
|
||||
|
||||
Chromium has removed support for changing the layout zoom level limits, and it
|
||||
is beyond Electron's capacity to maintain it. The function was deprecated in
|
||||
Electron 8.x, and has been removed in Electron 9.x. The layout zoom level limits
|
||||
are now fixed at a minimum of 0.25 and a maximum of 5.0, as defined
|
||||
[here](https://chromium.googlesource.com/chromium/src/+/938b37a6d2886bf8335fc7db792f1eb46c65b2ae/third_party/blink/common/page/page_zoom.cc#11).
|
||||
|
||||
## Planned Breaking API Changes (8.0)
|
||||
|
||||
### Values sent over IPC are now serialized with Structured Clone Algorithm
|
||||
@@ -59,6 +81,55 @@ these kinds of objects will throw a 'could not be cloned' error.
|
||||
|
||||
[SCA]: https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Structured_clone_algorithm
|
||||
|
||||
### `<webview>.getWebContents()`
|
||||
|
||||
This API is implemented using the `remote` module, which has both performance
|
||||
and security implications. Therefore its usage should be explicit.
|
||||
|
||||
```js
|
||||
// Deprecated
|
||||
webview.getWebContents()
|
||||
// Replace with
|
||||
const { remote } = require('electron')
|
||||
remote.webContents.fromId(webview.getWebContentsId())
|
||||
```
|
||||
|
||||
However, it is recommended to avoid using the `remote` module altogether.
|
||||
|
||||
```js
|
||||
// main
|
||||
const { ipcMain, webContents } = require('electron')
|
||||
|
||||
const getGuestForWebContents = function (webContentsId, contents) {
|
||||
const guest = webContents.fromId(webContentsId)
|
||||
if (!guest) {
|
||||
throw new Error(`Invalid webContentsId: ${webContentsId}`)
|
||||
}
|
||||
if (guest.hostWebContents !== contents) {
|
||||
throw new Error(`Access denied to webContents`)
|
||||
}
|
||||
return guest
|
||||
}
|
||||
|
||||
ipcMain.handle('openDevTools', (event, webContentsId) => {
|
||||
const guest = getGuestForWebContents(webContentsId, event.sender)
|
||||
guest.openDevTools()
|
||||
})
|
||||
|
||||
// renderer
|
||||
const { ipcRenderer } = require('electron')
|
||||
|
||||
ipcRenderer.invoke('openDevTools', webview.getWebContentsId())
|
||||
```
|
||||
|
||||
### `webFrame.setLayoutZoomLevelLimits()`
|
||||
|
||||
Chromium has removed support for changing the layout zoom level limits, and it
|
||||
is beyond Electron's capacity to maintain it. The function will emit a warning
|
||||
in Electron 8.x, and cease to exist in Electron 9.x. The layout zoom level
|
||||
limits are now fixed at a minimum of 0.25 and a maximum of 5.0, as defined
|
||||
[here](https://chromium.googlesource.com/chromium/src/+/938b37a6d2886bf8335fc7db792f1eb46c65b2ae/third_party/blink/common/page/page_zoom.cc#11).
|
||||
|
||||
## Planned Breaking API Changes (7.0)
|
||||
|
||||
### Node Headers URL
|
||||
@@ -103,7 +174,7 @@ const idleTime = getSystemIdleTime()
|
||||
### webFrame Isolated World APIs
|
||||
|
||||
```js
|
||||
// Removed in Elecron 7.0
|
||||
// Removed in Electron 7.0
|
||||
webFrame.setIsolatedWorldContentSecurityPolicy(worldId, csp)
|
||||
webFrame.setIsolatedWorldHumanReadableName(worldId, name)
|
||||
webFrame.setIsolatedWorldSecurityOrigin(worldId, securityOrigin)
|
||||
@@ -121,6 +192,39 @@ webFrame.setIsolatedWorldInfo(
|
||||
|
||||
This property was removed in Chromium 77, and as such is no longer available.
|
||||
|
||||
### `webkitdirectory` attribute for `<input type="file"/>`
|
||||
|
||||
The `webkitdirectory` property on HTML file inputs allows them to select folders.
|
||||
Previous versions of Electron had an incorrect implementation where the `event.target.files`
|
||||
of the input returned a `FileList` that returned one `File` corresponding to the selected folder.
|
||||
|
||||
As of Electron 7, that `FileList` is now list of all files contained within
|
||||
the folder, similarly to Chrome, Firefox, and Edge
|
||||
([link to MDN docs](https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement/webkitdirectory)).
|
||||
|
||||
As an illustration, take a folder with this structure:
|
||||
```console
|
||||
folder
|
||||
├── file1
|
||||
├── file2
|
||||
└── file3
|
||||
```
|
||||
|
||||
In Electron <=6, this would return a `FileList` with a `File` object for:
|
||||
```console
|
||||
path/to/folder
|
||||
```
|
||||
|
||||
In Electron 7, this now returns a `FileList` with a `File` object for:
|
||||
```console
|
||||
/path/to/folder/file3
|
||||
/path/to/folder/file2
|
||||
/path/to/folder/file1
|
||||
```
|
||||
|
||||
Note that `webkitdirectory` no longer exposes the path to the selected folder.
|
||||
If you require the path to the selected folder rather than the folder contents,
|
||||
see the `dialog.showOpenDialog` API ([link](https://github.com/electron/electron/blob/master/docs/api/dialog.md#dialogshowopendialogbrowserwindow-options)).
|
||||
## Planned Breaking API Changes (6.0)
|
||||
|
||||
### `win.setMenu(null)`
|
||||
|
||||
@@ -385,6 +385,8 @@ It creates a new `BrowserWindow` with native properties as set by the `options`.
|
||||
* `accessibleTitle` String (optional) - An alternative title string provided only
|
||||
to accessibility tools such as screen readers. This string is not directly
|
||||
visible to users.
|
||||
* `spellcheck` Boolean (optional) - Whether to enable the builtin spellchecker.
|
||||
Default is `true`.
|
||||
|
||||
When setting minimum or maximum window size with `minWidth`/`maxWidth`/
|
||||
`minHeight`/`maxHeight`, it only constrains the users. It won't prevent you from
|
||||
@@ -515,7 +517,7 @@ Emitted when the window is restored from a minimized state.
|
||||
Returns:
|
||||
|
||||
* `event` Event
|
||||
* `newBounds` [`Rectangle`](structures/rectangle.md) - Size the window is being resized to.
|
||||
* `newBounds` [Rectangle](structures/rectangle.md) - Size the window is being resized to.
|
||||
|
||||
Emitted before the window is resized. Calling `event.preventDefault()` will prevent the window from being resized.
|
||||
|
||||
@@ -530,7 +532,7 @@ Emitted after the window has been resized.
|
||||
Returns:
|
||||
|
||||
* `event` Event
|
||||
* `newBounds` [`Rectangle`](structures/rectangle.md) - Location the window is being moved to.
|
||||
* `newBounds` [Rectangle](structures/rectangle.md) - Location the window is being moved to.
|
||||
|
||||
Emitted before the window is moved. On Windows, calling `event.preventDefault()` will prevent the window from being moved.
|
||||
|
||||
@@ -770,7 +772,7 @@ events.
|
||||
|
||||
#### `win.id` _Readonly_
|
||||
|
||||
A `Integer` property representing the unique ID of the window.
|
||||
A `Integer` property representing the unique ID of the window. Each ID is unique among all `BrowserWindow` instances of the entire Electron application.
|
||||
|
||||
#### `win.autoHideMenuBar`
|
||||
|
||||
@@ -944,11 +946,11 @@ Returns `Boolean` - Whether the window is in simple (pre-Lion) fullscreen mode.
|
||||
|
||||
Returns `Boolean` - Whether the window is in normal state (not maximized, not minimized, not in fullscreen mode).
|
||||
|
||||
#### `win.setAspectRatio(aspectRatio[, extraSize])` _macOS_
|
||||
#### `win.setAspectRatio(aspectRatio[, extraSize])` _macOS_ _Linux_
|
||||
|
||||
* `aspectRatio` Float - The aspect ratio to maintain for some portion of the
|
||||
content view.
|
||||
* `extraSize` [Size](structures/size.md) (optional) - The extra size not to be included while
|
||||
* `extraSize` [Size](structures/size.md) (optional) _macOS_ - The extra size not to be included while
|
||||
maintaining the aspect ratio.
|
||||
|
||||
This will make a window maintain an aspect ratio. The extra size allows a
|
||||
@@ -1579,7 +1581,7 @@ Same as `webContents.showDefinitionForSelection()`.
|
||||
|
||||
#### `win.setIcon(icon)` _Windows_ _Linux_
|
||||
|
||||
* `icon` [NativeImage](native-image.md)
|
||||
* `icon` [NativeImage](native-image.md) | String
|
||||
|
||||
Changes window icon.
|
||||
|
||||
|
||||
@@ -32,8 +32,8 @@ the hostname and the port number 'hostname:port'.
|
||||
* `redirect` String (optional) - The redirect mode for this request. Should be
|
||||
one of `follow`, `error` or `manual`. Defaults to `follow`. When mode is `error`,
|
||||
any redirection will be aborted. When mode is `manual` the redirection will be
|
||||
deferred until [`request.followRedirect`](#requestfollowredirect) is invoked. Listen for the [`redirect`](#event-redirect) event in
|
||||
this mode to get more details about the redirect request.
|
||||
cancelled unless [`request.followRedirect`](#requestfollowredirect) is invoked
|
||||
synchronously during the [`redirect`](#event-redirect) event.
|
||||
|
||||
`options` properties such as `protocol`, `host`, `hostname`, `port` and `path`
|
||||
strictly follow the Node.js model as described in the
|
||||
@@ -70,8 +70,8 @@ Returns:
|
||||
* `port` Integer
|
||||
* `realm` String
|
||||
* `callback` Function
|
||||
* `username` String
|
||||
* `password` String
|
||||
* `username` String (optional)
|
||||
* `password` String (optional)
|
||||
|
||||
Emitted when an authenticating proxy is asking for user credentials.
|
||||
|
||||
@@ -136,8 +136,11 @@ Returns:
|
||||
* `redirectUrl` String
|
||||
* `responseHeaders` Record<String, String[]>
|
||||
|
||||
Emitted when there is redirection and the mode is `manual`. Calling
|
||||
[`request.followRedirect`](#requestfollowredirect) will continue with the redirection.
|
||||
Emitted when the server returns a redirect response (e.g. 301 Moved
|
||||
Permanently). Calling [`request.followRedirect`](#requestfollowredirect) will
|
||||
continue with the redirection. If this event is handled,
|
||||
[`request.followRedirect`](#requestfollowredirect) must be called
|
||||
**synchronously**, otherwise the request will be cancelled.
|
||||
|
||||
### Instance Properties
|
||||
|
||||
@@ -214,7 +217,8 @@ response object,it will emit the `aborted` event.
|
||||
|
||||
#### `request.followRedirect()`
|
||||
|
||||
Continues any deferred redirection request when the redirection mode is `manual`.
|
||||
Continues any pending redirection. Can only be called during a `'redirect'`
|
||||
event.
|
||||
|
||||
#### `request.getUploadProgress()`
|
||||
|
||||
|
||||
@@ -190,7 +190,6 @@ Enables caller stack logging for the following APIs (filtering events):
|
||||
- `remote.getBuiltin()` / `remote-get-global`
|
||||
- `remote.getCurrentWindow()` / `remote-get-current-window`
|
||||
- `remote.getCurrentWebContents()` / `remote-get-current-web-contents`
|
||||
- `remote.getGuestWebContents()` / `remote-get-guest-web-contents`
|
||||
|
||||
## --no-sandbox
|
||||
|
||||
|
||||
@@ -38,6 +38,9 @@ Get a set of category groups. The category groups can change as new code paths
|
||||
are reached. See also the [list of built-in tracing
|
||||
categories](https://chromium.googlesource.com/chromium/src/+/master/base/trace_event/builtin_categories.h).
|
||||
|
||||
> **NOTE:** Electron adds a non-default tracing category called `"electron"`.
|
||||
> This category can be used to capture Electron-specific tracing events.
|
||||
|
||||
### `contentTracing.startRecording(options)`
|
||||
|
||||
* `options` ([TraceConfig](structures/trace-config.md) | [TraceCategoriesAndOptions](structures/trace-categories-and-options.md))
|
||||
|
||||
@@ -91,7 +91,11 @@ The `desktopCapturer` module has the following methods:
|
||||
|
||||
Returns `Promise<DesktopCapturerSource[]>` - Resolves with an array of [`DesktopCapturerSource`](structures/desktop-capturer-source.md) objects, each `DesktopCapturerSource` represents a screen or an individual window that can be captured.
|
||||
|
||||
**Note** Capturing the screen contents requires user consent on macOS 10.15 Catalina or higher,
|
||||
which can detected by [`systemPreferences.getMediaAccessStatus`].
|
||||
|
||||
[`navigator.mediaDevices.getUserMedia`]: https://developer.mozilla.org/en/docs/Web/API/MediaDevices/getUserMedia
|
||||
[`systemPreferences.getMediaAccessStatus`]: system-preferences.md#systempreferencesgetmediaaccessstatusmediatype-macos
|
||||
|
||||
## Caveats
|
||||
|
||||
|
||||
@@ -44,7 +44,11 @@ Unsupported options are:
|
||||
--use-openssl-ca
|
||||
```
|
||||
|
||||
`NODE_OPTIONS` are explicitly disallowed in packaged apps.
|
||||
`NODE_OPTIONS` are explicitly disallowed in packaged apps, except for the following:
|
||||
|
||||
```sh
|
||||
--max-http-header-size
|
||||
```
|
||||
|
||||
### `GOOGLE_API_KEY`
|
||||
|
||||
@@ -121,5 +125,5 @@ the `electron` command to use the specified build of Electron instead of
|
||||
the one downloaded by `npm install`. Usage:
|
||||
|
||||
```sh
|
||||
export ELECTRON_OVERRIDE_DIST_PATH=/Users/username/projects/electron/out/Debug
|
||||
export ELECTRON_OVERRIDE_DIST_PATH=/Users/username/projects/electron/out/Testing
|
||||
```
|
||||
|
||||
@@ -77,6 +77,7 @@ only the next time a message is sent to `channel`, after which it is removed.
|
||||
|
||||
* `channel` String
|
||||
* `listener` Function
|
||||
* `...args` any[]
|
||||
|
||||
Removes the specified `listener` from the listener array for the specified
|
||||
`channel`.
|
||||
|
||||
@@ -14,7 +14,7 @@ See [`Menu`](menu.md) for examples.
|
||||
* `menuItem` MenuItem
|
||||
* `browserWindow` [BrowserWindow](browser-window.md)
|
||||
* `event` [KeyboardEvent](structures/keyboard-event.md)
|
||||
* `role` String (optional) - Can be `undo`, `redo`, `cut`, `copy`, `paste`, `pasteAndMatchStyle`, `delete`, `selectAll`, `reload`, `forceReload`, `toggleDevTools`, `resetZoom`, `zoomIn`, `zoomOut`, `togglefullscreen`, `window`, `minimize`, `close`, `help`, `about`, `services`, `hide`, `hideOthers`, `unhide`, `quit`, `startSpeaking`, `stopSpeaking`, `close`, `minimize`, `zoom`, `front`, `appMenu`, `fileMenu`, `editMenu`, `viewMenu`, `recentDocuments`, `toggleTabBar`, `selectNextTab`, `selectPreviousTab`, `mergeAllWindows`, `clearRecentDocuments`, `moveTabToNewWindow` or `windowMenu` - Define the action of the menu item, when specified the
|
||||
* `role` String (optional) - Can be `undo`, `redo`, `cut`, `copy`, `paste`, `pasteAndMatchStyle`, `delete`, `selectAll`, `reload`, `forceReload`, `toggleDevTools`, `resetZoom`, `zoomIn`, `zoomOut`, `togglefullscreen`, `window`, `minimize`, `close`, `help`, `about`, `services`, `hide`, `hideOthers`, `unhide`, `quit`, `startSpeaking`, `stopSpeaking`, `minimize`, `zoom`, `front`, `appMenu`, `fileMenu`, `editMenu`, `viewMenu`, `recentDocuments`, `toggleTabBar`, `selectNextTab`, `selectPreviousTab`, `mergeAllWindows`, `clearRecentDocuments`, `moveTabToNewWindow` or `windowMenu` - Define the action of the menu item, when specified the
|
||||
`click` property will be ignored. See [roles](#roles).
|
||||
* `type` String (optional) - Can be `normal`, `separator`, `submenu`, `checkbox` or
|
||||
`radio`.
|
||||
|
||||
@@ -1,17 +1,6 @@
|
||||
## Promisification
|
||||
|
||||
The Electron team is currently undergoing an initiative to convert callback-based functions in Electron to return Promises. During this transition period, both the callback and Promise-based versions of these functions will work correctly, and will both be documented.
|
||||
|
||||
To enable deprecation warnings for these updated functions, use the [`process.enablePromiseAPIs` runtime flag](../process.md#processenablepromiseapis).
|
||||
|
||||
When a majority of affected functions are migrated, this flag will be enabled by default and all developers will be able to see these deprecation warnings. At that time, the callback-based versions will also be removed from documentation. This document will be continuously updated as more functions are converted.
|
||||
|
||||
### Candidate Functions
|
||||
|
||||
- [app.importCertificate(options, callback)](https://github.com/electron/electron/blob/master/docs/api/app.md#importCertificate)
|
||||
- [contents.print([options], [callback])](https://github.com/electron/electron/blob/master/docs/api/web-contents.md#print)
|
||||
|
||||
### Converted Functions
|
||||
The Electron team recently underwent an initiative to convert callback-based APIs to Promise-based ones. See converted functions below:
|
||||
|
||||
- [app.getFileIcon(path[, options], callback)](https://github.com/electron/electron/blob/master/docs/api/app.md#getFileIcon)
|
||||
- [contents.capturePage([rect, ]callback)](https://github.com/electron/electron/blob/master/docs/api/web-contents.md#capturePage)
|
||||
|
||||
@@ -329,9 +329,9 @@ can be called on empty images.
|
||||
|
||||
[buffer]: https://nodejs.org/api/buffer.html#buffer_class_buffer
|
||||
|
||||
## Properties
|
||||
### Instance Properties
|
||||
|
||||
### `nativeImage.isMacTemplateImage` _macOS_
|
||||
#### `nativeImage.isMacTemplateImage` _macOS_
|
||||
|
||||
A `Boolean` property that determines whether the image is considered a [template image](https://developer.apple.com/documentation/appkit/nsimage/1520017-template).
|
||||
|
||||
|
||||
@@ -82,12 +82,6 @@ A `Boolean` that controls whether or not deprecation warnings are printed to `st
|
||||
Setting this to `true` will silence deprecation warnings. This property is used
|
||||
instead of the `--no-deprecation` command line flag.
|
||||
|
||||
### `process.enablePromiseAPIs`
|
||||
|
||||
A `Boolean` that controls whether or not deprecation warnings are printed to `stderr` when
|
||||
formerly callback-based APIs converted to Promises are invoked using callbacks. Setting this to `true`
|
||||
will enable deprecation warnings.
|
||||
|
||||
### `process.resourcesPath` _Readonly_
|
||||
|
||||
A `String` representing the path to the resources directory.
|
||||
@@ -217,11 +211,15 @@ that all statistics are reported in Kilobytes.
|
||||
|
||||
Returns `String` - The version of the host operating system.
|
||||
|
||||
Examples:
|
||||
Example:
|
||||
|
||||
* `macOS` -> `10.13.6`
|
||||
* `Windows` -> `10.0.17763`
|
||||
* `Linux` -> `4.15.0-45-generic`
|
||||
```js
|
||||
const version = process.getSystemVersion()
|
||||
console.log(version)
|
||||
// On macOS -> '10.13.6'
|
||||
// On Windows -> '10.0.17763'
|
||||
// On Linux -> '4.15.0-45-generic'
|
||||
```
|
||||
|
||||
**Note:** It returns the actual operating system version instead of kernel version on macOS unlike `os.release()`.
|
||||
|
||||
|
||||
@@ -389,9 +389,7 @@ which sends a `Buffer` as a response.
|
||||
* `url` String
|
||||
* `method` String (optional)
|
||||
* `session` Session | null (optional)
|
||||
* `uploadData` Object (optional)
|
||||
* `contentType` String - MIME type of the content.
|
||||
* `data` String - Content to be sent.
|
||||
* `uploadData` [ProtocolResponseUploadData](structures/protocol-response-upload-data.md) (optional)
|
||||
* `completion` Function (optional)
|
||||
* `error` Error
|
||||
|
||||
|
||||
@@ -456,10 +456,52 @@ this session just before normal `preload` scripts run.
|
||||
Returns `String[]` an array of paths to preload scripts that have been
|
||||
registered.
|
||||
|
||||
#### `ses.setSpellCheckerLanguages(languages)`
|
||||
|
||||
* `languages` String[] - An array of language codes to enable the spellchecker for.
|
||||
|
||||
The built in spellchecker does not automatically detect what language a user is typing in. In order for the
|
||||
spell checker to correctly check their words you must call this API with an array of language codes. You can
|
||||
get the list of supported language codes with the `ses.availableSpellCheckerLanguages` property.
|
||||
|
||||
**Note:** On macOS the OS spellchecker is used and will detect your language automatically. This API is a no-op on macOS.
|
||||
|
||||
#### `ses.getSpellCheckerLanguages()`
|
||||
|
||||
Returns `String[]` - An array of language codes the spellchecker is enabled for. If this list is empty the spellchecker
|
||||
will fallback to using `en-US`. By default on launch if this setting is an empty list Electron will try to populate this
|
||||
setting with the current OS locale. This setting is persisted across restarts.
|
||||
|
||||
**Note:** On macOS the OS spellchecker is used and has it's own list of languages. This API is a no-op on macOS.
|
||||
|
||||
#### `ses.setSpellCheckerDictionaryDownloadURL(url)`
|
||||
|
||||
* `url` String - A base URL for Electron to download hunspell dictionaries from.
|
||||
|
||||
By default Electron will download hunspell dictionaries from the Chromium CDN. If you want to override this
|
||||
behavior you can use this API to point the dictionary downloader at your own hosted version of the hunspell
|
||||
dictionaries. We publish a `hunspell_dictionaries.zip` file with each release which contains the files you need
|
||||
to host here.
|
||||
|
||||
**Note:** On macOS the OS spellchecker is used and therefore we do not download any dictionary files. This API is a no-op on macOS.
|
||||
|
||||
#### `ses.addWordToSpellCheckerDictionary(word)`
|
||||
|
||||
* `word` String - The word you want to add to the dictionary
|
||||
|
||||
Returns `Boolean` - Whether the word was successfully written to the custom dictionary.
|
||||
|
||||
**Note:** On macOS and Windows 10 this word will be written to the OS custom dictionary as well
|
||||
|
||||
### Instance Properties
|
||||
|
||||
The following properties are available on instances of `Session`:
|
||||
|
||||
#### `ses.availableSpellCheckerLanguages` _Readonly_
|
||||
|
||||
A `String[]` array which consists of all the known available spell checker languages. Providing a language
|
||||
code to the `setSpellCheckerLanaguages` API that isn't in this array will result in an error.
|
||||
|
||||
#### `ses.cookies` _Readonly_
|
||||
|
||||
A [`Cookies`](cookies.md) object for this session.
|
||||
|
||||
@@ -24,11 +24,14 @@ The `shell` module has the following methods:
|
||||
|
||||
Show the given file in a file manager. If possible, select the file.
|
||||
|
||||
### `shell.openItem(fullPath)`
|
||||
### `shell.openPath(path)`
|
||||
|
||||
* `fullPath` String
|
||||
* `path` String
|
||||
|
||||
Returns `Boolean` - Whether the item was successfully opened.
|
||||
Returns `Promise<Object>` - Resolve with an object containing the following:
|
||||
|
||||
* `success` Boolean - whether or not the path was successfully opened in the desktop's default manner.
|
||||
* `errorMessage` String (optional) - The error message corresponding to the failure if a failure occurred, otherwise empty string.
|
||||
|
||||
Open the given file in the desktop's default manner.
|
||||
|
||||
|
||||
@@ -4,4 +4,5 @@
|
||||
* `returnValue` any - Set this to the value to be returned in a synchronous message
|
||||
* `sender` WebContents - Returns the `webContents` that sent the message
|
||||
* `reply` Function - A function that will send an IPC message to the renderer frame that sent the original message that you are currently handling. You should use this method to "reply" to the sent message in order to guarantee the reply will go to the correct process and frame.
|
||||
* `channel` String
|
||||
* `...args` any[]
|
||||
|
||||
@@ -1,9 +1,13 @@
|
||||
# PrinterInfo Object
|
||||
|
||||
* `name` String
|
||||
* `description` String
|
||||
* `status` Number
|
||||
* `isDefault` Boolean
|
||||
* `name` String - the name of the printer as understood by the OS.
|
||||
* `displayName` String - the name of the printer as shown in Print Preview.
|
||||
* `description` String - a longer description of the printer's type.
|
||||
* `status` Number - the current status of the printer.
|
||||
* `isDefault` Boolean - whether or not a given printer is set as the default printer on the OS.
|
||||
* `options` Object - an object containing a variable number of platform-specific printer information.
|
||||
|
||||
The number represented by `status` means different things on different platforms: on Windows it's potential values can be found [here](https://docs.microsoft.com/en-us/windows/win32/printdocs/printer-info-2), and on Linux and macOS they can be found [here](https://www.cups.org/doc/cupspm.html).
|
||||
|
||||
## Example
|
||||
|
||||
@@ -12,13 +16,14 @@ may be different on each platform.
|
||||
|
||||
```javascript
|
||||
{
|
||||
name: 'Zebra_LP2844',
|
||||
description: 'Zebra LP2844',
|
||||
name: 'Austin_4th_Floor_Printer___C02XK13BJHD4',
|
||||
displayName: 'Austin 4th Floor Printer @ C02XK13BJHD4',
|
||||
description: 'TOSHIBA ColorMFP',
|
||||
status: 3,
|
||||
isDefault: false,
|
||||
options: {
|
||||
copies: '1',
|
||||
'device-uri': 'usb://Zebra/LP2844?location=14200000',
|
||||
'device-uri': 'dnssd://Austin%204th%20Floor%20Printer%20%40%20C02XK13BJHD4._ipps._tcp.local./?uuid=71687f1e-1147-3274-6674-22de61b110bd',
|
||||
finishings: '3',
|
||||
'job-cancel-after': '10800',
|
||||
'job-hold-until': 'no-hold',
|
||||
@@ -26,18 +31,19 @@ may be different on each platform.
|
||||
'job-sheets': 'none,none',
|
||||
'marker-change-time': '0',
|
||||
'number-up': '1',
|
||||
'printer-commands': 'none',
|
||||
'printer-info': 'Zebra LP2844',
|
||||
'printer-commands': 'ReportLevels,PrintSelfTestPage,com.toshiba.ColourProfiles.update,com.toshiba.EFiling.update,com.toshiba.EFiling.checkPassword',
|
||||
'printer-info': 'Austin 4th Floor Printer @ C02XK13BJHD4',
|
||||
'printer-is-accepting-jobs': 'true',
|
||||
'printer-is-shared': 'true',
|
||||
'printer-is-shared': 'false',
|
||||
'printer-is-temporary': 'false',
|
||||
'printer-location': '',
|
||||
'printer-make-and-model': 'Zebra EPL2 Label Printer',
|
||||
'printer-make-and-model': 'TOSHIBA ColorMFP',
|
||||
'printer-state': '3',
|
||||
'printer-state-change-time': '1484872644',
|
||||
'printer-state-reasons': 'offline-report',
|
||||
'printer-type': '36932',
|
||||
'printer-uri-supported': 'ipp://localhost/printers/Zebra_LP2844',
|
||||
system_driverinfo: 'Z'
|
||||
'printer-state-change-time': '1573472937',
|
||||
'printer-state-reasons': 'offline-report,com.toshiba.snmp.failed',
|
||||
'printer-type': '10531038',
|
||||
'printer-uri-supported': 'ipp://localhost/printers/Austin_4th_Floor_Printer___C02XK13BJHD4',
|
||||
system_driverinfo: 'T'
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# ProtocolResponseUploadData Object
|
||||
|
||||
* `contentType` String - MIME type of the content.
|
||||
* `data` String - Content to be sent.
|
||||
* `data` String | Buffer - Content to be sent.
|
||||
|
||||
@@ -434,11 +434,13 @@ Returns `Boolean` - `true` if the current process is a trusted accessibility cli
|
||||
|
||||
### `systemPreferences.getMediaAccessStatus(mediaType)` _macOS_
|
||||
|
||||
* `mediaType` String - `microphone` or `camera`.
|
||||
* `mediaType` String - Can be `microphone`, `camera` or `screen`.
|
||||
|
||||
Returns `String` - Can be `not-determined`, `granted`, `denied`, `restricted` or `unknown`.
|
||||
|
||||
This user consent was not required until macOS 10.14 Mojave, so this method will always return `granted` if your system is running 10.13 High Sierra or lower.
|
||||
This user consent was not required on macOS 10.13 High Sierra or lower so this method will always return `granted`.
|
||||
macOS 10.14 Mojave or higher requires consent for `microphone` and `camera` access.
|
||||
macOS 10.15 Catalina or higher requires consent for `screen` access.
|
||||
|
||||
### `systemPreferences.askForMediaAccess(mediaType)` _macOS_
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@ Process: [Main](../tutorial/application-architecture.md#main-and-renderer-proces
|
||||
* `icon` [NativeImage](native-image.md) | String (optional) - Button icon.
|
||||
* `iconPosition` String (optional) - Can be `left`, `right` or `overlay`. Defaults to `overlay`.
|
||||
* `click` Function (optional) - Function to call when the button is clicked.
|
||||
* `enabled` Boolean (optional) - Whether the button is in an enabled state. Default is `true`.
|
||||
|
||||
When defining `accessibilityLabel`, ensure you have considered macOS [best practices](https://developer.apple.com/documentation/appkit/nsaccessibilitybutton/1524910-accessibilitylabel?language=objc).
|
||||
|
||||
@@ -39,3 +40,7 @@ the button in the touch bar.
|
||||
|
||||
A `NativeImage` representing the button's current icon. Changing this value immediately updates the button
|
||||
in the touch bar.
|
||||
|
||||
#### `touchBarButton.enabled`
|
||||
|
||||
A `Boolean` representing whether the button is in an enabled state.
|
||||
|
||||
@@ -454,10 +454,8 @@ The usage is the same with [the `select-client-certificate` event of
|
||||
Returns:
|
||||
|
||||
* `event` Event
|
||||
* `request` Object
|
||||
* `method` String
|
||||
* `authenticationResponseDetails` Object
|
||||
* `url` URL
|
||||
* `referrer` URL
|
||||
* `authInfo` Object
|
||||
* `isProxy` Boolean
|
||||
* `scheme` String
|
||||
@@ -465,8 +463,8 @@ Returns:
|
||||
* `port` Integer
|
||||
* `realm` String
|
||||
* `callback` Function
|
||||
* `username` String
|
||||
* `password` String
|
||||
* `username` String (optional)
|
||||
* `password` String (optional)
|
||||
|
||||
Emitted when `webContents` wants to do basic auth.
|
||||
|
||||
@@ -570,6 +568,9 @@ Returns:
|
||||
* `titleText` String - Title or alt text of the selection that the context
|
||||
was invoked on.
|
||||
* `misspelledWord` String - The misspelled word under the cursor, if any.
|
||||
* `dictionarySuggestions` String[] - An array of suggested words to show the
|
||||
user to replace the `misspelledWord`. Only available if there is a misspelled
|
||||
word and spellchecker is enabled.
|
||||
* `frameCharset` String - The character encoding of the frame on which the
|
||||
menu was invoked.
|
||||
* `inputFieldType` String - If the context menu was invoked on an input
|
||||
@@ -799,17 +800,6 @@ Emitted when `remote.getCurrentWebContents()` is called in the renderer process.
|
||||
Calling `event.preventDefault()` will prevent the object from being returned.
|
||||
Custom value can be returned by setting `event.returnValue`.
|
||||
|
||||
#### Event: 'remote-get-guest-web-contents'
|
||||
|
||||
Returns:
|
||||
|
||||
* `event` IpcMainEvent
|
||||
* `guestWebContents` [WebContents](web-contents.md)
|
||||
|
||||
Emitted when `<webview>.getWebContents()` is called in the renderer process.
|
||||
Calling `event.preventDefault()` will prevent the object from being returned.
|
||||
Custom value can be returned by setting `event.returnValue`.
|
||||
|
||||
### Instance Methods
|
||||
|
||||
#### `contents.loadURL(url[, options])`
|
||||
@@ -1041,6 +1031,17 @@ contents.executeJavaScript('fetch("https://jsonplaceholder.typicode.com/users/1"
|
||||
})
|
||||
```
|
||||
|
||||
#### `contents.executeJavaScriptInIsolatedWorld(worldId, scripts[, userGesture])`
|
||||
|
||||
* `worldId` Integer - The ID of the world to run the javascript in, `0` is the default world, `999` is the world used by Electron's `contextIsolation` feature. You can provide any integer here.
|
||||
* `scripts` [WebSource[]](structures/web-source.md)
|
||||
* `userGesture` Boolean (optional) - Default is `false`.
|
||||
|
||||
Returns `Promise<any>` - A promise that resolves with the result of the executed code
|
||||
or is rejected if the result of the code is a rejected promise.
|
||||
|
||||
Works like `executeJavaScript` but evaluates `scripts` in an isolated context.
|
||||
|
||||
#### `contents.setIgnoreMenuShortcuts(ignore)` _Experimental_
|
||||
|
||||
* `ignore` Boolean
|
||||
@@ -1112,15 +1113,6 @@ Sets the maximum and minimum pinch-to-zoom level.
|
||||
> contents.setVisualZoomLevelLimits(1, 3)
|
||||
> ```
|
||||
|
||||
#### `contents.setLayoutZoomLevelLimits(minimumLevel, maximumLevel)`
|
||||
|
||||
* `minimumLevel` Number
|
||||
* `maximumLevel` Number
|
||||
|
||||
Returns `Promise<void>`
|
||||
|
||||
Sets the maximum and minimum layout-based (i.e. non-visual) zoom level.
|
||||
|
||||
#### `contents.undo()`
|
||||
|
||||
Executes the editing command `undo` in web page.
|
||||
@@ -1237,7 +1229,7 @@ Captures a snapshot of the page within `rect`. Omitting `rect` will capture the
|
||||
|
||||
Get the system printer list.
|
||||
|
||||
Returns [`PrinterInfo[]`](structures/printer-info.md).
|
||||
Returns [`PrinterInfo[]`](structures/printer-info.md)
|
||||
|
||||
#### `contents.print([options], [callback])`
|
||||
|
||||
@@ -1388,13 +1380,20 @@ An example of showing devtools in a `<webview>` tag:
|
||||
</head>
|
||||
<body>
|
||||
<webview id="browser" src="https://github.com"></webview>
|
||||
<webview id="devtools"></webview>
|
||||
<webview id="devtools" src="about:blank"></webview>
|
||||
<script>
|
||||
const { webContents } = require('electron').remote
|
||||
const emittedOnce = (element, eventName) => new Promise(resolve => {
|
||||
element.addEventListener(eventName, event => resolve(event), { once: true })
|
||||
})
|
||||
const browserView = document.getElementById('browser')
|
||||
const devtoolsView = document.getElementById('devtools')
|
||||
browserView.addEventListener('dom-ready', () => {
|
||||
const browser = browserView.getWebContents()
|
||||
browser.setDevToolsWebContents(devtoolsView.getWebContents())
|
||||
const browserReady = emittedOnce(browserView, 'dom-ready')
|
||||
const devtoolsReady = emittedOnce(devtoolsView, 'dom-ready')
|
||||
Promise.all([browserReady, devtoolsReady]).then(() => {
|
||||
const browser = webContents.fromId(browserView.getWebContentsId())
|
||||
const devtools = webContents.fromId(devtoolsView.getWebContentsId())
|
||||
browser.setDevToolsWebContents(devtools)
|
||||
browser.openDevTools()
|
||||
})
|
||||
</script>
|
||||
@@ -1774,7 +1773,7 @@ Only applicable if *offscreen rendering* is enabled.
|
||||
|
||||
#### `contents.id` _Readonly_
|
||||
|
||||
A `Integer` representing the unique ID of this WebContents.
|
||||
A `Integer` representing the unique ID of this WebContents. Each ID is unique among all `WebContents` instances of the entire Electron application.
|
||||
|
||||
#### `contents.session` _Readonly_
|
||||
|
||||
|
||||
@@ -56,13 +56,6 @@ Sets the maximum and minimum pinch-to-zoom level.
|
||||
> webFrame.setVisualZoomLevelLimits(1, 3)
|
||||
> ```
|
||||
|
||||
### `webFrame.setLayoutZoomLevelLimits(minimumLevel, maximumLevel)`
|
||||
|
||||
* `minimumLevel` Number
|
||||
* `maximumLevel` Number
|
||||
|
||||
Sets the maximum and minimum layout-based (i.e. non-visual) zoom level.
|
||||
|
||||
### `webFrame.setSpellCheckProvider(language, provider)`
|
||||
|
||||
* `language` String
|
||||
@@ -74,6 +67,17 @@ Sets the maximum and minimum layout-based (i.e. non-visual) zoom level.
|
||||
|
||||
Sets a provider for spell checking in input fields and text areas.
|
||||
|
||||
If you want to use this method you must disable the builtin spellchecker when you
|
||||
construct the window.
|
||||
|
||||
```js
|
||||
const mainWindow = new BrowserWindow({
|
||||
webPreferences: {
|
||||
spellcheck: false
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
The `provider` must be an object that has a `spellCheck` method that accepts
|
||||
an array of individual words for spellchecking.
|
||||
The `spellCheck` function runs asynchronously and calls the `callback` function
|
||||
|
||||
@@ -635,27 +635,10 @@ Returns `Promise<void>`
|
||||
|
||||
Sets the maximum and minimum pinch-to-zoom level.
|
||||
|
||||
### `<webview>.setLayoutZoomLevelLimits(minimumLevel, maximumLevel)`
|
||||
|
||||
* `minimumLevel` Number
|
||||
* `maximumLevel` Number
|
||||
|
||||
Returns `Promise<void>`
|
||||
|
||||
Sets the maximum and minimum layout-based (i.e. non-visual) zoom level.
|
||||
|
||||
### `<webview>.showDefinitionForSelection()` _macOS_
|
||||
|
||||
Shows pop-up dictionary that searches the selected word on the page.
|
||||
|
||||
### `<webview>.getWebContents()`
|
||||
|
||||
Returns [`WebContents`](web-contents.md) - The web contents associated with
|
||||
this `webview`.
|
||||
|
||||
It depends on the [`remote`](remote.md) module,
|
||||
it is therefore not available when this module is disabled.
|
||||
|
||||
### `<webview>.getWebContentsId()`
|
||||
|
||||
Returns `Number` - The WebContents ID of this `webview`.
|
||||
|
||||
@@ -96,30 +96,30 @@ $ cd src
|
||||
$ export CHROMIUM_BUILDTOOLS_PATH=`pwd`/buildtools
|
||||
# this next line is needed only if building with sccache
|
||||
$ export GN_EXTRA_ARGS="${GN_EXTRA_ARGS} cc_wrapper=\"${PWD}/electron/external_binaries/sccache\""
|
||||
$ gn gen out/Debug --args="import(\"//electron/build/args/debug.gn\") $GN_EXTRA_ARGS"
|
||||
$ gn gen out/Testing --args="import(\"//electron/build/args/testing.gn\") $GN_EXTRA_ARGS"
|
||||
```
|
||||
|
||||
Or on Windows (without the optional argument):
|
||||
```sh
|
||||
$ cd src
|
||||
$ set CHROMIUM_BUILDTOOLS_PATH=%cd%\buildtools
|
||||
$ gn gen out/Debug --args="import(\"//electron/build/args/debug.gn\")"
|
||||
$ gn gen out/Testing --args="import(\"//electron/build/args/testing.gn\")"
|
||||
```
|
||||
|
||||
This will generate a build directory `out/Debug` under `src/` with
|
||||
debug build configuration. You can replace `Debug` with another name,
|
||||
This will generate a build directory `out/Testing` under `src/` with
|
||||
the testing build configuration. You can replace `Testing` with another name,
|
||||
but it should be a subdirectory of `out`.
|
||||
Also you shouldn't have to run `gn gen` again—if you want to change the
|
||||
build arguments, you can run `gn args out/Debug` to bring up an editor.
|
||||
build arguments, you can run `gn args out/Testing` to bring up an editor.
|
||||
|
||||
To see the list of available build configuration options, run `gn args
|
||||
out/Debug --list`.
|
||||
out/Testing --list`.
|
||||
|
||||
**For generating Debug (aka "component" or "shared") build config of
|
||||
**For generating Testing build config of
|
||||
Electron:**
|
||||
|
||||
```sh
|
||||
$ gn gen out/Debug --args="import(\"//electron/build/args/debug.gn\") $GN_EXTRA_ARGS"
|
||||
$ gn gen out/Testing --args="import(\"//electron/build/args/testing.gn\") $GN_EXTRA_ARGS"
|
||||
```
|
||||
|
||||
**For generating Release (aka "non-component" or "static") build config of
|
||||
@@ -132,9 +132,9 @@ $ gn gen out/Release --args="import(\"//electron/build/args/release.gn\") $GN_EX
|
||||
**To build, run `ninja` with the `electron` target:**
|
||||
Nota Bene: This will also take a while and probably heat up your lap.
|
||||
|
||||
For the debug configuration:
|
||||
For the testing configuration:
|
||||
```sh
|
||||
$ ninja -C out/Debug electron
|
||||
$ ninja -C out/Testing electron
|
||||
```
|
||||
|
||||
For the release configuration:
|
||||
@@ -147,19 +147,19 @@ This will build all of what was previously 'libchromiumcontent' (i.e. the
|
||||
so it will take a while.
|
||||
|
||||
To speed up subsequent builds, you can use [sccache][sccache]. Add the GN arg
|
||||
`cc_wrapper = "sccache"` by running `gn args out/Debug` to bring up an
|
||||
`cc_wrapper = "sccache"` by running `gn args out/Testing` to bring up an
|
||||
editor and adding a line to the end of the file.
|
||||
|
||||
[sccache]: https://github.com/mozilla/sccache
|
||||
|
||||
The built executable will be under `./out/Debug`:
|
||||
The built executable will be under `./out/Testing`:
|
||||
|
||||
```sh
|
||||
$ ./out/Debug/Electron.app/Contents/MacOS/Electron
|
||||
$ ./out/Testing/Electron.app/Contents/MacOS/Electron
|
||||
# or, on Windows
|
||||
$ ./out/Debug/electron.exe
|
||||
$ ./out/Testing/electron.exe
|
||||
# or, on Linux
|
||||
$ ./out/Debug/electron
|
||||
$ ./out/Testing/electron
|
||||
```
|
||||
|
||||
### Packaging
|
||||
@@ -181,7 +181,7 @@ set the `target_cpu` and `target_os` GN arguments. For example, to compile an
|
||||
x86 target from an x64 host, specify `target_cpu = "x86"` in `gn args`.
|
||||
|
||||
```sh
|
||||
$ gn gen out/Debug-x86 --args='... target_cpu = "x86"'
|
||||
$ gn gen out/Testing-x86 --args='... target_cpu = "x86"'
|
||||
```
|
||||
|
||||
Not all combinations of source and target CPU/OS are supported by Chromium.
|
||||
@@ -226,7 +226,7 @@ generate build headers for the modules to compile against, run the following
|
||||
under `src/` directory.
|
||||
|
||||
```sh
|
||||
$ ninja -C out/Debug third_party/electron_node:headers
|
||||
$ ninja -C out/Testing third_party/electron_node:headers
|
||||
```
|
||||
|
||||
You can now [run the tests](testing.md#unit-tests).
|
||||
@@ -235,8 +235,8 @@ If you're debugging something, it can be helpful to pass some extra flags to
|
||||
the Electron binary:
|
||||
|
||||
```sh
|
||||
$ ./out/Debug/Electron.app/Contents/MacOS/Electron electron/spec \
|
||||
--ci --enable-logging -g 'BrowserWindow module'
|
||||
$ npm run test -- \
|
||||
--enable-logging -g 'BrowserWindow module'
|
||||
```
|
||||
|
||||
## Sharing the git cache between multiple machines
|
||||
|
||||
@@ -79,7 +79,7 @@ And to cross-compile for `arm` or `ia32` targets, you should pass the
|
||||
`target_cpu` parameter to `gn gen`:
|
||||
|
||||
```sh
|
||||
$ gn gen out/Debug --args='import(...) target_cpu="arm"'
|
||||
$ gn gen out/Testing --args='import(...) target_cpu="arm"'
|
||||
```
|
||||
|
||||
## Building
|
||||
@@ -114,7 +114,7 @@ GN args.
|
||||
For example if you installed `clang` under `/usr/local/bin/clang`:
|
||||
|
||||
```sh
|
||||
$ gn gen out/Debug --args='import("//electron/build/args/debug.gn") clang_base_path = "/usr/local/bin"'
|
||||
$ gn gen out/Testing --args='import("//electron/build/args/testing.gn") clang_base_path = "/usr/local/bin"'
|
||||
```
|
||||
|
||||
### Using compilers other than `clang`
|
||||
|
||||
@@ -11,9 +11,8 @@ Follow the guidelines below for building Electron on Windows.
|
||||
components are required.
|
||||
* If your Visual Studio is installed in a directory other than the default, you'll need to
|
||||
set a few environment variables to point the toolchains to your installation path.
|
||||
* `vs2019_install = DRIVE:\path\to\Microsoft Visual Studio\2019\Community`
|
||||
(replace `2019` and `Community` with your installed versions)
|
||||
* `WINDOWSSDKDIR = DRIVE:\path\to\Windows Kits\10`
|
||||
* `vs2019_install = DRIVE:\path\to\Microsoft Visual Studio\2019\Community`, replacing `2019` and `Community` with your installed versions and replacing `DRIVE:` with the drive that Visual Studio is on. Often, this will be `C:`.
|
||||
* `WINDOWSSDKDIR = DRIVE:\path\to\Windows Kits\10`, replacing `DRIVE:` with the drive that Windows Kits is on. Often, this will be `C:`.
|
||||
* [Python 2.7.10 or higher](http://www.python.org/download/releases/2.7/)
|
||||
* Contrary to the `depot_tools` setup instructions linked below, you will need
|
||||
to use your locally installed Python with at least version 2.7.10 (with
|
||||
@@ -74,7 +73,7 @@ To generate a Visual Studio project, you can pass the `--ide=vs2017` parameter
|
||||
to `gn gen`:
|
||||
|
||||
```powershell
|
||||
$ gn gen out/Debug --ide=vs2017
|
||||
$ gn gen out/Testing --ide=vs2017
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
@@ -54,7 +54,7 @@ formatted correctly.
|
||||
the `module-name` form. This rule only applies to `.js` files.
|
||||
* Use newer ES6/ES2015 syntax where appropriate
|
||||
* [`const`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/const)
|
||||
for requires and other constants
|
||||
for requires and other constants. If the value is a primitive, use uppercase naming (eg `const NUMBER_OF_RETRIES = 5`).
|
||||
* [`let`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let)
|
||||
for defining variables
|
||||
* [Arrow functions](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions)
|
||||
|
||||
@@ -36,7 +36,7 @@ To start a debugging session, open up PowerShell/CMD and execute your debug
|
||||
build of Electron, using the application to open as a parameter.
|
||||
|
||||
```powershell
|
||||
$ ./out/Debug/electron.exe ~/my-electron-app/
|
||||
$ ./out/Testing/electron.exe ~/my-electron-app/
|
||||
```
|
||||
|
||||
### Setting Breakpoints
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
### Generate xcode project for debugging sources (cannot build code from xcode)
|
||||
Run `gn gen` with the --ide=xcode argument.
|
||||
```sh
|
||||
$ gn gen out/Debug --ide=xcode
|
||||
$ gn gen out/Testing --ide=xcode
|
||||
```
|
||||
This will generate the electron.ninja.xcworkspace. You will have to open this workspace
|
||||
to set breakpoints and inspect.
|
||||
|
||||
@@ -25,13 +25,13 @@ you prefer a graphical interface.
|
||||
|
||||
## Attaching to and Debugging Electron
|
||||
|
||||
To start a debugging session, open up Terminal and start `lldb`, passing a debug
|
||||
To start a debugging session, open up Terminal and start `lldb`, passing a non-release
|
||||
build of Electron as a parameter.
|
||||
|
||||
```sh
|
||||
$ lldb ./out/Debug/Electron.app
|
||||
(lldb) target create "./out/Debug/Electron.app"
|
||||
Current executable set to './out/Debug/Electron.app' (x86_64).
|
||||
$ lldb ./out/Testing/Electron.app
|
||||
(lldb) target create "./out/Testing/Electron.app"
|
||||
Current executable set to './out/Testing/Electron.app' (x86_64).
|
||||
```
|
||||
|
||||
### Setting Breakpoints
|
||||
@@ -62,7 +62,7 @@ The app will immediately be paused, since Electron sets the app's name on launch
|
||||
|
||||
```sh
|
||||
(lldb) run
|
||||
Process 25244 launched: '/Users/fr/Code/electron/out/Debug/Electron.app/Contents/MacOS/Electron' (x86_64)
|
||||
Process 25244 launched: '/Users/fr/Code/electron/out/Testing/Electron.app/Contents/MacOS/Electron' (x86_64)
|
||||
Process 25244 stopped
|
||||
* thread #1: tid = 0x839a4c, 0x0000000100162db4 Electron Framework`atom::Browser::SetName(this=0x0000000108b14f20, name="Electron") + 20 at browser.cc:118, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
|
||||
frame #0: 0x0000000100162db4 Electron Framework`atom::Browser::SetName(this=0x0000000108b14f20, name="Electron") + 20 at browser.cc:118
|
||||
|
||||
@@ -41,7 +41,7 @@ To help manage these patch sets, we provide two tools: `git-import-patches` and
|
||||
### Usage
|
||||
|
||||
#### Adding a new patch
|
||||
```bash session
|
||||
```bash
|
||||
$ cd src/third_party/electron_node
|
||||
$ vim some/code/file.cc
|
||||
$ git commit
|
||||
@@ -53,7 +53,7 @@ $ ../../electron/script/git-export-patches -o ../../electron/patches/node
|
||||
Re-exporting patches will sometimes cause shasums in unrelated patches to change. This is generally harmless and can be ignored (but go ahead and add those changes to your PR, it'll stop them from showing up for other people).
|
||||
|
||||
#### Editing an existing patch
|
||||
```bash session
|
||||
```bash
|
||||
$ cd src/v8
|
||||
$ vim some/code/file.cc
|
||||
$ git log
|
||||
@@ -64,7 +64,7 @@ $ ../electron/script/git-export-patches -o ../electron/patches/v8
|
||||
```
|
||||
|
||||
#### Removing a patch
|
||||
```bash session
|
||||
```bash
|
||||
$ vim src/electron/patches/node/.patches
|
||||
# Delete the line with the name of the patch you want to remove
|
||||
$ cd src/third_party/electron_node
|
||||
@@ -78,7 +78,7 @@ Note that `git-import-patches` will mark the commit that was `HEAD` when it was
|
||||
#### Resolving conflicts
|
||||
When updating an upstream dependency, patches may fail to apply cleanly. Often, the conflict can be resolved automatically by git with a 3-way merge. You can instruct `git-import-patches` to use the 3-way merge algorithm by passing the `-3` argument:
|
||||
|
||||
```bash session
|
||||
```bash
|
||||
$ cd src/third_party/electron_node
|
||||
# If the patch application failed midway through, you can reset it with:
|
||||
$ git am --abort
|
||||
|
||||
@@ -42,8 +42,6 @@ Electron
|
||||
| | └── api/ - Javascript API implementation.
|
||||
| └── renderer/ - Javascript renderer process initialization code.
|
||||
| └── api/ - Javascript API implementation.
|
||||
├── native_mate/ - A fork of Chromium's gin library that makes it easier to marshal
|
||||
| types between C++ and JavaScript.
|
||||
├── spec/ - Automatic tests.
|
||||
└── BUILD.gn - Building rules of Electron.
|
||||
```
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
</head>
|
||||
<body>
|
||||
<div>
|
||||
<div>
|
||||
<h1>Synchronous messages</h1>
|
||||
<i>Supports: Win, macOS, Linux <span>|</span> Process: Both</i>
|
||||
<div>
|
||||
<div>
|
||||
<button id="sync-msg">Ping</button>
|
||||
<span id="sync-reply"></span>
|
||||
</div>
|
||||
<p>You can use the <code>ipc</code> module to send synchronous messages between processes as well, but note that the synchronous nature of this method means that it <b>will block</b> other operations while completing its task.</p>
|
||||
|
||||
<p>This example sends a synchronous message, "ping", from this process (renderer) to the main process. The main process then replies with "pong".</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
// You can also require other files to run in this process
|
||||
require('./renderer.js')
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,29 @@
|
||||
const { app, BrowserWindow, ipcMain } = require('electron')
|
||||
|
||||
let mainWindow = null
|
||||
|
||||
function createWindow () {
|
||||
const windowOptions = {
|
||||
width: 600,
|
||||
height: 400,
|
||||
title: 'Synchronous Messages',
|
||||
webPreferences: {
|
||||
nodeIntegration: true
|
||||
}
|
||||
}
|
||||
|
||||
mainWindow = new BrowserWindow(windowOptions)
|
||||
mainWindow.loadFile('index.html')
|
||||
|
||||
mainWindow.on('closed', () => {
|
||||
mainWindow = null
|
||||
})
|
||||
}
|
||||
|
||||
app.on('ready', () => {
|
||||
createWindow()
|
||||
})
|
||||
|
||||
ipcMain.on('synchronous-message', (event, arg) => {
|
||||
event.returnValue = 'pong'
|
||||
})
|
||||
@@ -0,0 +1,9 @@
|
||||
const { ipcRenderer } = require('electron')
|
||||
|
||||
const syncMsgBtn = document.getElementById('sync-msg')
|
||||
|
||||
syncMsgBtn.addEventListener('click', () => {
|
||||
const reply = ipcRenderer.sendSync('synchronous-message', 'ping')
|
||||
const message = `Synchronous message reply: ${reply}`
|
||||
document.getElementById('sync-reply').innerHTML = message
|
||||
})
|
||||
@@ -1,360 +1,360 @@
|
||||
// Modules to control application life and create native browser window
|
||||
const {
|
||||
BrowserWindow,
|
||||
Menu,
|
||||
MenuItem,
|
||||
ipcMain,
|
||||
app,
|
||||
shell,
|
||||
dialog
|
||||
} = require('electron')
|
||||
|
||||
const menu = new Menu()
|
||||
menu.append(new MenuItem({ label: 'Hello' }))
|
||||
menu.append(new MenuItem({ type: 'separator' }))
|
||||
menu.append(
|
||||
new MenuItem({ label: 'Electron', type: 'checkbox', checked: true })
|
||||
)
|
||||
|
||||
const template = [
|
||||
{
|
||||
label: 'Edit',
|
||||
submenu: [
|
||||
{
|
||||
label: 'Undo',
|
||||
accelerator: 'CmdOrCtrl+Z',
|
||||
role: 'undo'
|
||||
},
|
||||
{
|
||||
label: 'Redo',
|
||||
accelerator: 'Shift+CmdOrCtrl+Z',
|
||||
role: 'redo'
|
||||
},
|
||||
{
|
||||
type: 'separator'
|
||||
},
|
||||
{
|
||||
label: 'Cut',
|
||||
accelerator: 'CmdOrCtrl+X',
|
||||
role: 'cut'
|
||||
},
|
||||
{
|
||||
label: 'Copy',
|
||||
accelerator: 'CmdOrCtrl+C',
|
||||
role: 'copy'
|
||||
},
|
||||
{
|
||||
label: 'Paste',
|
||||
accelerator: 'CmdOrCtrl+V',
|
||||
role: 'paste'
|
||||
},
|
||||
{
|
||||
label: 'Select All',
|
||||
accelerator: 'CmdOrCtrl+A',
|
||||
role: 'selectall'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
label: 'View',
|
||||
submenu: [
|
||||
{
|
||||
label: 'Reload',
|
||||
accelerator: 'CmdOrCtrl+R',
|
||||
click: (item, focusedWindow) => {
|
||||
if (focusedWindow) {
|
||||
// on reload, start fresh and close any old
|
||||
// open secondary windows
|
||||
if (focusedWindow.id === 1) {
|
||||
BrowserWindow.getAllWindows().forEach(win => {
|
||||
if (win.id > 1) win.close()
|
||||
})
|
||||
}
|
||||
focusedWindow.reload()
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
label: 'Toggle Full Screen',
|
||||
accelerator: (() => {
|
||||
if (process.platform === 'darwin') {
|
||||
return 'Ctrl+Command+F'
|
||||
} else {
|
||||
return 'F11'
|
||||
}
|
||||
})(),
|
||||
click: (item, focusedWindow) => {
|
||||
if (focusedWindow) {
|
||||
focusedWindow.setFullScreen(!focusedWindow.isFullScreen())
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
label: 'Toggle Developer Tools',
|
||||
accelerator: (() => {
|
||||
if (process.platform === 'darwin') {
|
||||
return 'Alt+Command+I'
|
||||
} else {
|
||||
return 'Ctrl+Shift+I'
|
||||
}
|
||||
})(),
|
||||
click: (item, focusedWindow) => {
|
||||
if (focusedWindow) {
|
||||
focusedWindow.toggleDevTools()
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
type: 'separator'
|
||||
},
|
||||
{
|
||||
label: 'App Menu Demo',
|
||||
click: function (item, focusedWindow) {
|
||||
if (focusedWindow) {
|
||||
const options = {
|
||||
type: 'info',
|
||||
title: 'Application Menu Demo',
|
||||
buttons: ['Ok'],
|
||||
message:
|
||||
'This demo is for the Menu section, showing how to create a clickable menu item in the application menu.'
|
||||
}
|
||||
dialog.showMessageBox(focusedWindow, options, function () {})
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
label: 'Window',
|
||||
role: 'window',
|
||||
submenu: [
|
||||
{
|
||||
label: 'Minimize',
|
||||
accelerator: 'CmdOrCtrl+M',
|
||||
role: 'minimize'
|
||||
},
|
||||
{
|
||||
label: 'Close',
|
||||
accelerator: 'CmdOrCtrl+W',
|
||||
role: 'close'
|
||||
},
|
||||
{
|
||||
type: 'separator'
|
||||
},
|
||||
{
|
||||
label: 'Reopen Window',
|
||||
accelerator: 'CmdOrCtrl+Shift+T',
|
||||
enabled: false,
|
||||
key: 'reopenMenuItem',
|
||||
click: () => {
|
||||
app.emit('activate')
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
label: 'Help',
|
||||
role: 'help',
|
||||
submenu: [
|
||||
{
|
||||
label: 'Learn More',
|
||||
click: () => {
|
||||
shell.openExternal('http://electron.atom.io')
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
function addUpdateMenuItems (items, position) {
|
||||
if (process.mas) return
|
||||
|
||||
const version = app.getVersion()
|
||||
const updateItems = [
|
||||
{
|
||||
label: `Version ${version}`,
|
||||
enabled: false
|
||||
},
|
||||
{
|
||||
label: 'Checking for Update',
|
||||
enabled: false,
|
||||
key: 'checkingForUpdate'
|
||||
},
|
||||
{
|
||||
label: 'Check for Update',
|
||||
visible: false,
|
||||
key: 'checkForUpdate',
|
||||
click: () => {
|
||||
require('electron').autoUpdater.checkForUpdates()
|
||||
}
|
||||
},
|
||||
{
|
||||
label: 'Restart and Install Update',
|
||||
enabled: true,
|
||||
visible: false,
|
||||
key: 'restartToUpdate',
|
||||
click: () => {
|
||||
require('electron').autoUpdater.quitAndInstall()
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
items.splice.apply(items, [position, 0].concat(updateItems))
|
||||
}
|
||||
|
||||
function findReopenMenuItem () {
|
||||
const menu = Menu.getApplicationMenu()
|
||||
if (!menu) return
|
||||
|
||||
let reopenMenuItem
|
||||
menu.items.forEach(item => {
|
||||
if (item.submenu) {
|
||||
item.submenu.items.forEach(item => {
|
||||
if (item.key === 'reopenMenuItem') {
|
||||
reopenMenuItem = item
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
return reopenMenuItem
|
||||
}
|
||||
|
||||
if (process.platform === 'darwin') {
|
||||
const name = app.getName()
|
||||
template.unshift({
|
||||
label: name,
|
||||
submenu: [
|
||||
{
|
||||
label: `About ${name}`,
|
||||
role: 'about'
|
||||
},
|
||||
{
|
||||
type: 'separator'
|
||||
},
|
||||
{
|
||||
label: 'Services',
|
||||
role: 'services',
|
||||
submenu: []
|
||||
},
|
||||
{
|
||||
type: 'separator'
|
||||
},
|
||||
{
|
||||
label: `Hide ${name}`,
|
||||
accelerator: 'Command+H',
|
||||
role: 'hide'
|
||||
},
|
||||
{
|
||||
label: 'Hide Others',
|
||||
accelerator: 'Command+Alt+H',
|
||||
role: 'hideothers'
|
||||
},
|
||||
{
|
||||
label: 'Show All',
|
||||
role: 'unhide'
|
||||
},
|
||||
{
|
||||
type: 'separator'
|
||||
},
|
||||
{
|
||||
label: 'Quit',
|
||||
accelerator: 'Command+Q',
|
||||
click: () => {
|
||||
app.quit()
|
||||
}
|
||||
}
|
||||
]
|
||||
})
|
||||
|
||||
// Window menu.
|
||||
template[3].submenu.push(
|
||||
{
|
||||
type: 'separator'
|
||||
},
|
||||
{
|
||||
label: 'Bring All to Front',
|
||||
role: 'front'
|
||||
}
|
||||
)
|
||||
|
||||
addUpdateMenuItems(template[0].submenu, 1)
|
||||
}
|
||||
|
||||
if (process.platform === 'win32') {
|
||||
const helpMenu = template[template.length - 1].submenu
|
||||
addUpdateMenuItems(helpMenu, 0)
|
||||
}
|
||||
// Keep a global reference of the window object, if you don't, the window will
|
||||
// be closed automatically when the JavaScript object is garbage collected.
|
||||
let mainWindow
|
||||
|
||||
function createWindow () {
|
||||
// Create the browser window.
|
||||
mainWindow = new BrowserWindow({
|
||||
width: 800,
|
||||
height: 600,
|
||||
webPreferences: {
|
||||
nodeIntegration: true
|
||||
}
|
||||
})
|
||||
|
||||
// and load the index.html of the app.
|
||||
mainWindow.loadFile('index.html')
|
||||
|
||||
// Open the DevTools.
|
||||
// mainWindow.webContents.openDevTools()
|
||||
|
||||
// Emitted when the window is closed.
|
||||
mainWindow.on('closed', function () {
|
||||
// Dereference the window object, usually you would store windows
|
||||
// in an array if your app supports multi windows, this is the time
|
||||
// when you should delete the corresponding element.
|
||||
mainWindow = null
|
||||
})
|
||||
}
|
||||
|
||||
// This method will be called when Electron has finished
|
||||
// initialization and is ready to create browser windows.
|
||||
// Some APIs can only be used after this event occurs.
|
||||
app.on('ready', () => {
|
||||
createWindow()
|
||||
const menu = Menu.buildFromTemplate(template)
|
||||
Menu.setApplicationMenu(menu)
|
||||
})
|
||||
|
||||
// Quit when all windows are closed.
|
||||
app.on('window-all-closed', function () {
|
||||
// On OS X it is common for applications and their menu bar
|
||||
// to stay active until the user quits explicitly with Cmd + Q
|
||||
const reopenMenuItem = findReopenMenuItem()
|
||||
if (reopenMenuItem) reopenMenuItem.enabled = true
|
||||
|
||||
if (process.platform !== 'darwin') {
|
||||
app.quit()
|
||||
}
|
||||
})
|
||||
|
||||
app.on('activate', function () {
|
||||
// On OS X it's common to re-create a window in the app when the
|
||||
// dock icon is clicked and there are no other windows open.
|
||||
if (mainWindow === null) {
|
||||
createWindow()
|
||||
}
|
||||
})
|
||||
|
||||
app.on('browser-window-created', (event, win) => {
|
||||
const reopenMenuItem = findReopenMenuItem()
|
||||
if (reopenMenuItem) reopenMenuItem.enabled = false
|
||||
|
||||
win.webContents.on('context-menu', (e, params) => {
|
||||
menu.popup(win, params.x, params.y)
|
||||
})
|
||||
})
|
||||
|
||||
ipcMain.on('show-context-menu', event => {
|
||||
const win = BrowserWindow.fromWebContents(event.sender)
|
||||
menu.popup(win)
|
||||
})
|
||||
|
||||
// In this file you can include the rest of your app's specific main process
|
||||
// code. You can also put them in separate files and require them here.
|
||||
// Modules to control application life and create native browser window
|
||||
const {
|
||||
BrowserWindow,
|
||||
Menu,
|
||||
MenuItem,
|
||||
ipcMain,
|
||||
app,
|
||||
shell,
|
||||
dialog
|
||||
} = require('electron')
|
||||
|
||||
const menu = new Menu()
|
||||
menu.append(new MenuItem({ label: 'Hello' }))
|
||||
menu.append(new MenuItem({ type: 'separator' }))
|
||||
menu.append(
|
||||
new MenuItem({ label: 'Electron', type: 'checkbox', checked: true })
|
||||
)
|
||||
|
||||
const template = [
|
||||
{
|
||||
label: 'Edit',
|
||||
submenu: [
|
||||
{
|
||||
label: 'Undo',
|
||||
accelerator: 'CmdOrCtrl+Z',
|
||||
role: 'undo'
|
||||
},
|
||||
{
|
||||
label: 'Redo',
|
||||
accelerator: 'Shift+CmdOrCtrl+Z',
|
||||
role: 'redo'
|
||||
},
|
||||
{
|
||||
type: 'separator'
|
||||
},
|
||||
{
|
||||
label: 'Cut',
|
||||
accelerator: 'CmdOrCtrl+X',
|
||||
role: 'cut'
|
||||
},
|
||||
{
|
||||
label: 'Copy',
|
||||
accelerator: 'CmdOrCtrl+C',
|
||||
role: 'copy'
|
||||
},
|
||||
{
|
||||
label: 'Paste',
|
||||
accelerator: 'CmdOrCtrl+V',
|
||||
role: 'paste'
|
||||
},
|
||||
{
|
||||
label: 'Select All',
|
||||
accelerator: 'CmdOrCtrl+A',
|
||||
role: 'selectall'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
label: 'View',
|
||||
submenu: [
|
||||
{
|
||||
label: 'Reload',
|
||||
accelerator: 'CmdOrCtrl+R',
|
||||
click: (item, focusedWindow) => {
|
||||
if (focusedWindow) {
|
||||
// on reload, start fresh and close any old
|
||||
// open secondary windows
|
||||
if (focusedWindow.id === 1) {
|
||||
BrowserWindow.getAllWindows().forEach(win => {
|
||||
if (win.id > 1) win.close()
|
||||
})
|
||||
}
|
||||
focusedWindow.reload()
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
label: 'Toggle Full Screen',
|
||||
accelerator: (() => {
|
||||
if (process.platform === 'darwin') {
|
||||
return 'Ctrl+Command+F'
|
||||
} else {
|
||||
return 'F11'
|
||||
}
|
||||
})(),
|
||||
click: (item, focusedWindow) => {
|
||||
if (focusedWindow) {
|
||||
focusedWindow.setFullScreen(!focusedWindow.isFullScreen())
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
label: 'Toggle Developer Tools',
|
||||
accelerator: (() => {
|
||||
if (process.platform === 'darwin') {
|
||||
return 'Alt+Command+I'
|
||||
} else {
|
||||
return 'Ctrl+Shift+I'
|
||||
}
|
||||
})(),
|
||||
click: (item, focusedWindow) => {
|
||||
if (focusedWindow) {
|
||||
focusedWindow.toggleDevTools()
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
type: 'separator'
|
||||
},
|
||||
{
|
||||
label: 'App Menu Demo',
|
||||
click: function (item, focusedWindow) {
|
||||
if (focusedWindow) {
|
||||
const options = {
|
||||
type: 'info',
|
||||
title: 'Application Menu Demo',
|
||||
buttons: ['Ok'],
|
||||
message:
|
||||
'This demo is for the Menu section, showing how to create a clickable menu item in the application menu.'
|
||||
}
|
||||
dialog.showMessageBox(focusedWindow, options, function () {})
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
label: 'Window',
|
||||
role: 'window',
|
||||
submenu: [
|
||||
{
|
||||
label: 'Minimize',
|
||||
accelerator: 'CmdOrCtrl+M',
|
||||
role: 'minimize'
|
||||
},
|
||||
{
|
||||
label: 'Close',
|
||||
accelerator: 'CmdOrCtrl+W',
|
||||
role: 'close'
|
||||
},
|
||||
{
|
||||
type: 'separator'
|
||||
},
|
||||
{
|
||||
label: 'Reopen Window',
|
||||
accelerator: 'CmdOrCtrl+Shift+T',
|
||||
enabled: false,
|
||||
key: 'reopenMenuItem',
|
||||
click: () => {
|
||||
app.emit('activate')
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
label: 'Help',
|
||||
role: 'help',
|
||||
submenu: [
|
||||
{
|
||||
label: 'Learn More',
|
||||
click: () => {
|
||||
shell.openExternal('http://electron.atom.io')
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
function addUpdateMenuItems (items, position) {
|
||||
if (process.mas) return
|
||||
|
||||
const version = app.getVersion()
|
||||
const updateItems = [
|
||||
{
|
||||
label: `Version ${version}`,
|
||||
enabled: false
|
||||
},
|
||||
{
|
||||
label: 'Checking for Update',
|
||||
enabled: false,
|
||||
key: 'checkingForUpdate'
|
||||
},
|
||||
{
|
||||
label: 'Check for Update',
|
||||
visible: false,
|
||||
key: 'checkForUpdate',
|
||||
click: () => {
|
||||
require('electron').autoUpdater.checkForUpdates()
|
||||
}
|
||||
},
|
||||
{
|
||||
label: 'Restart and Install Update',
|
||||
enabled: true,
|
||||
visible: false,
|
||||
key: 'restartToUpdate',
|
||||
click: () => {
|
||||
require('electron').autoUpdater.quitAndInstall()
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
items.splice.apply(items, [position, 0].concat(updateItems))
|
||||
}
|
||||
|
||||
function findReopenMenuItem () {
|
||||
const menu = Menu.getApplicationMenu()
|
||||
if (!menu) return
|
||||
|
||||
let reopenMenuItem
|
||||
menu.items.forEach(item => {
|
||||
if (item.submenu) {
|
||||
item.submenu.items.forEach(item => {
|
||||
if (item.key === 'reopenMenuItem') {
|
||||
reopenMenuItem = item
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
return reopenMenuItem
|
||||
}
|
||||
|
||||
if (process.platform === 'darwin') {
|
||||
const name = app.getName()
|
||||
template.unshift({
|
||||
label: name,
|
||||
submenu: [
|
||||
{
|
||||
label: `About ${name}`,
|
||||
role: 'about'
|
||||
},
|
||||
{
|
||||
type: 'separator'
|
||||
},
|
||||
{
|
||||
label: 'Services',
|
||||
role: 'services',
|
||||
submenu: []
|
||||
},
|
||||
{
|
||||
type: 'separator'
|
||||
},
|
||||
{
|
||||
label: `Hide ${name}`,
|
||||
accelerator: 'Command+H',
|
||||
role: 'hide'
|
||||
},
|
||||
{
|
||||
label: 'Hide Others',
|
||||
accelerator: 'Command+Alt+H',
|
||||
role: 'hideothers'
|
||||
},
|
||||
{
|
||||
label: 'Show All',
|
||||
role: 'unhide'
|
||||
},
|
||||
{
|
||||
type: 'separator'
|
||||
},
|
||||
{
|
||||
label: 'Quit',
|
||||
accelerator: 'Command+Q',
|
||||
click: () => {
|
||||
app.quit()
|
||||
}
|
||||
}
|
||||
]
|
||||
})
|
||||
|
||||
// Window menu.
|
||||
template[3].submenu.push(
|
||||
{
|
||||
type: 'separator'
|
||||
},
|
||||
{
|
||||
label: 'Bring All to Front',
|
||||
role: 'front'
|
||||
}
|
||||
)
|
||||
|
||||
addUpdateMenuItems(template[0].submenu, 1)
|
||||
}
|
||||
|
||||
if (process.platform === 'win32') {
|
||||
const helpMenu = template[template.length - 1].submenu
|
||||
addUpdateMenuItems(helpMenu, 0)
|
||||
}
|
||||
// Keep a global reference of the window object, if you don't, the window will
|
||||
// be closed automatically when the JavaScript object is garbage collected.
|
||||
let mainWindow
|
||||
|
||||
function createWindow () {
|
||||
// Create the browser window.
|
||||
mainWindow = new BrowserWindow({
|
||||
width: 800,
|
||||
height: 600,
|
||||
webPreferences: {
|
||||
nodeIntegration: true
|
||||
}
|
||||
})
|
||||
|
||||
// and load the index.html of the app.
|
||||
mainWindow.loadFile('index.html')
|
||||
|
||||
// Open the DevTools.
|
||||
// mainWindow.webContents.openDevTools()
|
||||
|
||||
// Emitted when the window is closed.
|
||||
mainWindow.on('closed', function () {
|
||||
// Dereference the window object, usually you would store windows
|
||||
// in an array if your app supports multi windows, this is the time
|
||||
// when you should delete the corresponding element.
|
||||
mainWindow = null
|
||||
})
|
||||
}
|
||||
|
||||
// This method will be called when Electron has finished
|
||||
// initialization and is ready to create browser windows.
|
||||
// Some APIs can only be used after this event occurs.
|
||||
app.on('ready', () => {
|
||||
createWindow()
|
||||
const menu = Menu.buildFromTemplate(template)
|
||||
Menu.setApplicationMenu(menu)
|
||||
})
|
||||
|
||||
// Quit when all windows are closed.
|
||||
app.on('window-all-closed', function () {
|
||||
// On OS X it is common for applications and their menu bar
|
||||
// to stay active until the user quits explicitly with Cmd + Q
|
||||
const reopenMenuItem = findReopenMenuItem()
|
||||
if (reopenMenuItem) reopenMenuItem.enabled = true
|
||||
|
||||
if (process.platform !== 'darwin') {
|
||||
app.quit()
|
||||
}
|
||||
})
|
||||
|
||||
app.on('activate', function () {
|
||||
// On OS X it's common to re-create a window in the app when the
|
||||
// dock icon is clicked and there are no other windows open.
|
||||
if (mainWindow === null) {
|
||||
createWindow()
|
||||
}
|
||||
})
|
||||
|
||||
app.on('browser-window-created', (event, win) => {
|
||||
const reopenMenuItem = findReopenMenuItem()
|
||||
if (reopenMenuItem) reopenMenuItem.enabled = false
|
||||
|
||||
win.webContents.on('context-menu', (e, params) => {
|
||||
menu.popup(win, params.x, params.y)
|
||||
})
|
||||
})
|
||||
|
||||
ipcMain.on('show-context-menu', event => {
|
||||
const win = BrowserWindow.fromWebContents(event.sender)
|
||||
menu.popup(win)
|
||||
})
|
||||
|
||||
// In this file you can include the rest of your app's specific main process
|
||||
// code. You can also put them in separate files and require them here.
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
const { ipcRenderer } = require('electron')
|
||||
|
||||
// Tell main process to show the menu when demo button is clicked
|
||||
const contextMenuBtn = document.getElementById('context-menu')
|
||||
|
||||
contextMenuBtn.addEventListener('click', () => {
|
||||
ipcRenderer.send('show-context-menu')
|
||||
})
|
||||
const { ipcRenderer } = require('electron')
|
||||
|
||||
// Tell main process to show the menu when demo button is clicked
|
||||
const contextMenuBtn = document.getElementById('context-menu')
|
||||
|
||||
contextMenuBtn.addEventListener('click', () => {
|
||||
ipcRenderer.send('show-context-menu')
|
||||
})
|
||||
|
||||
81
docs/fiddles/native-ui/dialogs/error-dialog/index.html
Normal file
81
docs/fiddles/native-ui/dialogs/error-dialog/index.html
Normal file
@@ -0,0 +1,81 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>Error Dialog</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div>
|
||||
<h1>Use system dialogs</h1>
|
||||
|
||||
<h3>
|
||||
The <code>dialog</code> module in Electron allows you to use native
|
||||
system dialogs for opening files or directories, saving a file or
|
||||
displaying informational messages.
|
||||
</h3>
|
||||
|
||||
<p>
|
||||
This is a main process module because this process is more efficient
|
||||
with native utilities and it allows the call to happen without
|
||||
interrupting the visible elements in your page's renderer process.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Open the
|
||||
<a href="http://electron.atom.io/docs/api/dialog/">
|
||||
full API documentation (opens in new window)
|
||||
</a>
|
||||
in your browser.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div>
|
||||
<h2>Error Dialog</h2>
|
||||
<div>
|
||||
<div>
|
||||
<button id="error-dialog">View Demo</button>
|
||||
</div>
|
||||
<p>
|
||||
In this demo, the <code>ipc</code> module is used to send a message
|
||||
from the renderer process instructing the main process to launch the
|
||||
error dialog.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
You can use an error dialog before the app's
|
||||
<code>ready</code> event, which is useful for showing errors upon
|
||||
startup.
|
||||
</p>
|
||||
<h5>Renderer Process</h5>
|
||||
<pre>
|
||||
<code>
|
||||
const {ipcRenderer} = require('electron')
|
||||
|
||||
const errorBtn = document.getElementById('error-dialog')
|
||||
|
||||
errorBtn.addEventListener('click', (event) => {
|
||||
ipcRenderer.send('open-error-dialog')
|
||||
})
|
||||
</code></pre>
|
||||
<h5>Main Process</h5>
|
||||
<pre>
|
||||
<code>
|
||||
const {ipcMain, dialog} = require('electron')
|
||||
|
||||
ipcMain.on('open-error-dialog', (event) => {
|
||||
dialog.showErrorBox('An Error Message', 'Demonstrating an error message.')
|
||||
})
|
||||
</code>
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
// You can also require other files to run in this process
|
||||
require("./renderer.js");
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
95
docs/fiddles/native-ui/dialogs/error-dialog/main.js
Normal file
95
docs/fiddles/native-ui/dialogs/error-dialog/main.js
Normal file
@@ -0,0 +1,95 @@
|
||||
// Modules to control application life and create native browser window
|
||||
const { app, BrowserWindow, ipcMain, dialog } = require('electron')
|
||||
|
||||
// Keep a global reference of the window object, if you don't, the window will
|
||||
// be closed automatically when the JavaScript object is garbage collected.
|
||||
let mainWindow
|
||||
|
||||
function createWindow () {
|
||||
// Create the browser window.
|
||||
mainWindow = new BrowserWindow({
|
||||
width: 800,
|
||||
height: 600,
|
||||
webPreferences: {
|
||||
nodeIntegration: true
|
||||
}
|
||||
})
|
||||
|
||||
// and load the index.html of the app.
|
||||
mainWindow.loadFile('index.html')
|
||||
|
||||
// Open the DevTools.
|
||||
// mainWindow.webContents.openDevTools()
|
||||
|
||||
// Emitted when the window is closed.
|
||||
mainWindow.on('closed', function () {
|
||||
// Dereference the window object, usually you would store windows
|
||||
// in an array if your app supports multi windows, this is the time
|
||||
// when you should delete the corresponding element.
|
||||
mainWindow = null
|
||||
})
|
||||
}
|
||||
|
||||
// This method will be called when Electron has finished
|
||||
// initialization and is ready to create browser windows.
|
||||
// Some APIs can only be used after this event occurs.
|
||||
app.on('ready', createWindow)
|
||||
|
||||
// Quit when all windows are closed.
|
||||
app.on('window-all-closed', function () {
|
||||
// On OS X it is common for applications and their menu bar
|
||||
// to stay active until the user quits explicitly with Cmd + Q
|
||||
if (process.platform !== 'darwin') {
|
||||
app.quit()
|
||||
}
|
||||
})
|
||||
|
||||
app.on('activate', function () {
|
||||
// On OS X it's common to re-create a window in the app when the
|
||||
// dock icon is clicked and there are no other windows open.
|
||||
if (mainWindow === null) {
|
||||
createWindow()
|
||||
}
|
||||
})
|
||||
|
||||
ipcMain.on('open-error-dialog', event => {
|
||||
dialog.showErrorBox('An Error Message', 'Demonstrating an error message.')
|
||||
})
|
||||
|
||||
ipcMain.on('open-information-dialog', event => {
|
||||
const options = {
|
||||
type: 'info',
|
||||
title: 'Information',
|
||||
message: "This is an information dialog. Isn't it nice?",
|
||||
buttons: ['Yes', 'No']
|
||||
}
|
||||
dialog.showMessageBox(options, index => {
|
||||
event.sender.send('information-dialog-selection', index)
|
||||
})
|
||||
})
|
||||
|
||||
ipcMain.on('open-file-dialog', event => {
|
||||
dialog.showOpenDialog(
|
||||
{
|
||||
properties: ['openFile', 'openDirectory']
|
||||
},
|
||||
files => {
|
||||
if (files) {
|
||||
event.sender.send('selected-directory', files)
|
||||
}
|
||||
}
|
||||
)
|
||||
})
|
||||
|
||||
ipcMain.on('save-dialog', event => {
|
||||
const options = {
|
||||
title: 'Save an Image',
|
||||
filters: [{ name: 'Images', extensions: ['jpg', 'png', 'gif'] }]
|
||||
}
|
||||
dialog.showSaveDialog(options, filename => {
|
||||
event.sender.send('saved-file', filename)
|
||||
})
|
||||
})
|
||||
|
||||
// In this file you can include the rest of your app's specific main process
|
||||
// code. You can also put them in separate files and require them here.
|
||||
18
docs/fiddles/native-ui/dialogs/error-dialog/renderer.js
Normal file
18
docs/fiddles/native-ui/dialogs/error-dialog/renderer.js
Normal file
@@ -0,0 +1,18 @@
|
||||
const { ipcRenderer, shell } = require('electron')
|
||||
|
||||
const links = document.querySelectorAll('a[href]')
|
||||
const errorBtn = document.getElementById('error-dialog')
|
||||
|
||||
errorBtn.addEventListener('click', event => {
|
||||
ipcRenderer.send('open-error-dialog')
|
||||
})
|
||||
|
||||
Array.prototype.forEach.call(links, (link) => {
|
||||
const url = link.getAttribute('href')
|
||||
if (url.indexOf('http') === 0) {
|
||||
link.addEventListener('click', (e) => {
|
||||
e.preventDefault()
|
||||
shell.openExternal(url)
|
||||
})
|
||||
}
|
||||
})
|
||||
104
docs/fiddles/native-ui/dialogs/information-dialog/index.html
Normal file
104
docs/fiddles/native-ui/dialogs/information-dialog/index.html
Normal file
@@ -0,0 +1,104 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>Information Dialog</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="section-wrapper">
|
||||
<h1>Use system dialogs</h1>
|
||||
|
||||
<h3>
|
||||
The <code>dialog</code> module in Electron allows you to use native
|
||||
system dialogs for opening files or directories, saving a file or
|
||||
displaying informational messages.
|
||||
</h3>
|
||||
|
||||
<p>
|
||||
This is a main process module because this process is more efficient
|
||||
with native utilities and it allows the call to happen without
|
||||
interrupting the visible elements in your page's renderer process.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Open the
|
||||
<a href="http://electron.atom.io/docs/api/dialog/">
|
||||
full API documentation (opens in new window)
|
||||
</a>
|
||||
in your browser.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div>
|
||||
<h2>Information Dialog</h2>
|
||||
<div>
|
||||
<div>
|
||||
<button id="information-dialog">
|
||||
View Demo
|
||||
</button>
|
||||
<span id="info-selection"></span>
|
||||
</div>
|
||||
<p>
|
||||
In this demo, the <code>ipc</code> module is used to send a message
|
||||
from the renderer process instructing the main process to launch the
|
||||
information dialog. Options may be provided for responses which can
|
||||
then be relayed back to the renderer process.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Note: The <code>title</code> property is not displayed in macOS.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
An information dialog can contain an icon, your choice of buttons,
|
||||
title and message.
|
||||
</p>
|
||||
<h5>Renderer Process</h5>
|
||||
<pre>
|
||||
<code>
|
||||
const {ipcRenderer} = require('electron')
|
||||
|
||||
const informationBtn = document.getElementById('information-dialog')
|
||||
|
||||
informationBtn.addEventListener('click', (event) => {
|
||||
ipcRenderer.send('open-information-dialog')
|
||||
})
|
||||
|
||||
ipcRenderer.on('information-dialog-selection', (event, index) => {
|
||||
let message = 'You selected '
|
||||
if (index === 0) message += 'yes.'
|
||||
else message += 'no.'
|
||||
document.getElementById('info-selection').innerHTML = message
|
||||
})
|
||||
</code>
|
||||
</pre>
|
||||
<h5>Main Process</h5>
|
||||
<pre>
|
||||
<code>
|
||||
const {ipcMain, dialog} = require('electron')
|
||||
|
||||
ipcMain.on('open-information-dialog', (event) => {
|
||||
const options = {
|
||||
type: 'info',
|
||||
title: 'Information',
|
||||
message: "This is an information dialog. Isn't it nice?",
|
||||
buttons: ['Yes', 'No']
|
||||
}
|
||||
dialog.showMessageBox(options, (index) => {
|
||||
event.sender.send('information-dialog-selection', index)
|
||||
})
|
||||
})
|
||||
</code>
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
// You can also require other files to run in this process
|
||||
require("./renderer.js");
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
70
docs/fiddles/native-ui/dialogs/information-dialog/main.js
Normal file
70
docs/fiddles/native-ui/dialogs/information-dialog/main.js
Normal file
@@ -0,0 +1,70 @@
|
||||
// Modules to control application life and create native browser window
|
||||
const { app, BrowserWindow, ipcMain, dialog } = require('electron')
|
||||
|
||||
// Keep a global reference of the window object, if you don't, the window will
|
||||
// be closed automatically when the JavaScript object is garbage collected.
|
||||
let mainWindow
|
||||
|
||||
function createWindow () {
|
||||
// Create the browser window.
|
||||
mainWindow = new BrowserWindow({
|
||||
width: 800,
|
||||
height: 600,
|
||||
webPreferences: {
|
||||
nodeIntegration: true
|
||||
}
|
||||
})
|
||||
|
||||
// and load the index.html of the app.
|
||||
mainWindow.loadFile('index.html')
|
||||
|
||||
// Open the DevTools.
|
||||
// mainWindow.webContents.openDevTools()
|
||||
|
||||
// Emitted when the window is closed.
|
||||
mainWindow.on('closed', function () {
|
||||
// Dereference the window object, usually you would store windows
|
||||
// in an array if your app supports multi windows, this is the time
|
||||
// when you should delete the corresponding element.
|
||||
mainWindow = null
|
||||
})
|
||||
}
|
||||
|
||||
// This method will be called when Electron has finished
|
||||
// initialization and is ready to create browser windows.
|
||||
// Some APIs can only be used after this event occurs.
|
||||
app.on('ready', createWindow)
|
||||
|
||||
// Quit when all windows are closed.
|
||||
app.on('window-all-closed', function () {
|
||||
// On OS X it is common for applications and their menu bar
|
||||
// to stay active until the user quits explicitly with Cmd + Q
|
||||
if (process.platform !== 'darwin') {
|
||||
app.quit()
|
||||
}
|
||||
})
|
||||
|
||||
app.on('activate', function () {
|
||||
// On OS X it's common to re-create a window in the app when the
|
||||
// dock icon is clicked and there are no other windows open.
|
||||
if (mainWindow === null) {
|
||||
createWindow()
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
ipcMain.on('open-information-dialog', event => {
|
||||
const options = {
|
||||
type: 'info',
|
||||
title: 'Information',
|
||||
message: "This is an information dialog. Isn't it nice?",
|
||||
buttons: ['Yes', 'No']
|
||||
}
|
||||
dialog.showMessageBox(options, index => {
|
||||
event.sender.send('information-dialog-selection', index)
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
// In this file you can include the rest of your app's specific main process
|
||||
// code. You can also put them in separate files and require them here.
|
||||
@@ -0,0 +1,25 @@
|
||||
const { ipcRenderer, shell } = require('electron')
|
||||
|
||||
const informationBtn = document.getElementById('information-dialog')
|
||||
const links = document.querySelectorAll('a[href]')
|
||||
|
||||
informationBtn.addEventListener('click', event => {
|
||||
ipcRenderer.send('open-information-dialog')
|
||||
})
|
||||
|
||||
ipcRenderer.on('information-dialog-selection', (event, index) => {
|
||||
let message = 'You selected '
|
||||
if (index === 0) message += 'yes.'
|
||||
else message += 'no.'
|
||||
document.getElementById('info-selection').innerHTML = message
|
||||
})
|
||||
|
||||
Array.prototype.forEach.call(links, (link) => {
|
||||
const url = link.getAttribute('href')
|
||||
if (url.indexOf('http') === 0) {
|
||||
link.addEventListener('click', (e) => {
|
||||
e.preventDefault()
|
||||
shell.openExternal(url)
|
||||
})
|
||||
}
|
||||
})
|
||||
108
docs/fiddles/native-ui/dialogs/open-file-or-directory/index.html
Normal file
108
docs/fiddles/native-ui/dialogs/open-file-or-directory/index.html
Normal file
@@ -0,0 +1,108 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>Open File or Directory</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="section-wrapper">
|
||||
<h1>Use system dialogs</h1>
|
||||
|
||||
<h3>
|
||||
The <code>dialog</code> module in Electron allows you to use native
|
||||
system dialogs for opening files or directories, saving a file or
|
||||
displaying informational messages.
|
||||
</h3>
|
||||
|
||||
<p>
|
||||
This is a main process module because this process is more efficient
|
||||
with native utilities and it allows the call to happen without
|
||||
interrupting the visible elements in your page's renderer process.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Open the
|
||||
<a href="http://electron.atom.io/docs/api/dialog/">
|
||||
full API documentation (opens in new window)
|
||||
</a>
|
||||
in your browser.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div>
|
||||
<h2>Open a File or Directory</h2>
|
||||
<div>
|
||||
<div>
|
||||
<button id="select-directory">View Demo</button>
|
||||
<span id="selected-file"></span>
|
||||
</div>
|
||||
<p>
|
||||
In this demo, the <code>ipc</code> module is used to send a message
|
||||
from the renderer process instructing the main process to launch the
|
||||
open file (or directory) dialog. If a file is selected, the main
|
||||
process can send that information back to the renderer process.
|
||||
</p>
|
||||
<h5>Renderer Process</h5>
|
||||
<pre>
|
||||
<code>
|
||||
const {ipcRenderer} = require('electron')
|
||||
|
||||
const selectDirBtn = document.getElementById('select-directory')
|
||||
|
||||
selectDirBtn.addEventListener('click', (event) => {
|
||||
ipcRenderer.send('open-file-dialog')
|
||||
})
|
||||
|
||||
ipcRenderer.on('selected-directory', (event, path) => {
|
||||
document.getElementById('selected-file').innerHTML = `You selected: ${path}`
|
||||
})
|
||||
</code>
|
||||
</pre>
|
||||
<h5>Main Process</h5>
|
||||
<pre>
|
||||
<code>
|
||||
const {ipcMain, dialog} = require('electron')
|
||||
|
||||
ipcMain.on('open-file-dialog', (event) => {
|
||||
dialog.showOpenDialog({
|
||||
properties: ['openFile', 'openDirectory']
|
||||
}, (files) => {
|
||||
if (files) {
|
||||
event.sender.send('selected-directory', files)
|
||||
}
|
||||
})
|
||||
})
|
||||
</code>
|
||||
</pre>
|
||||
|
||||
<div>
|
||||
<h2>ProTip</h2>
|
||||
<strong>The sheet-style dialog on macOS.</strong>
|
||||
<p>
|
||||
On macOS you can choose between a "sheet" dialog or a default
|
||||
dialog. The sheet version descends from the top of the window. To
|
||||
use sheet version, pass the <code>window</code> as the first
|
||||
argument in the dialog method.
|
||||
</p>
|
||||
<pre><code class="language-js">const ipc = require('electron').ipcMain
|
||||
const dialog = require('electron').dialog
|
||||
const BrowserWindow = require('electron').BrowserWindow
|
||||
|
||||
|
||||
ipc.on('open-file-dialog-sheet', function (event) {
|
||||
const window = BrowserWindow.fromWebContents(event.sender)
|
||||
const files = dialog.showOpenDialog(window, { properties: [ 'openFile' ]})
|
||||
})</code></pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
// You can also require other files to run in this process
|
||||
require("./renderer.js");
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,70 @@
|
||||
// Modules to control application life and create native browser window
|
||||
const { app, BrowserWindow, ipcMain, dialog } = require('electron')
|
||||
|
||||
// Keep a global reference of the window object, if you don't, the window will
|
||||
// be closed automatically when the JavaScript object is garbage collected.
|
||||
let mainWindow
|
||||
|
||||
function createWindow () {
|
||||
// Create the browser window.
|
||||
mainWindow = new BrowserWindow({
|
||||
width: 800,
|
||||
height: 600,
|
||||
webPreferences: {
|
||||
nodeIntegration: true
|
||||
}
|
||||
})
|
||||
|
||||
// and load the index.html of the app.
|
||||
mainWindow.loadFile('index.html')
|
||||
|
||||
// Open the DevTools.
|
||||
// mainWindow.webContents.openDevTools()
|
||||
|
||||
// Emitted when the window is closed.
|
||||
mainWindow.on('closed', function () {
|
||||
// Dereference the window object, usually you would store windows
|
||||
// in an array if your app supports multi windows, this is the time
|
||||
// when you should delete the corresponding element.
|
||||
mainWindow = null
|
||||
})
|
||||
}
|
||||
|
||||
// This method will be called when Electron has finished
|
||||
// initialization and is ready to create browser windows.
|
||||
// Some APIs can only be used after this event occurs.
|
||||
app.on('ready', createWindow)
|
||||
|
||||
// Quit when all windows are closed.
|
||||
app.on('window-all-closed', function () {
|
||||
// On OS X it is common for applications and their menu bar
|
||||
// to stay active until the user quits explicitly with Cmd + Q
|
||||
if (process.platform !== 'darwin') {
|
||||
app.quit()
|
||||
}
|
||||
})
|
||||
|
||||
app.on('activate', function () {
|
||||
// On OS X it's common to re-create a window in the app when the
|
||||
// dock icon is clicked and there are no other windows open.
|
||||
if (mainWindow === null) {
|
||||
createWindow()
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
ipcMain.on('open-file-dialog', event => {
|
||||
dialog.showOpenDialog(
|
||||
{
|
||||
properties: ['openFile', 'openDirectory']
|
||||
},
|
||||
files => {
|
||||
if (files) {
|
||||
event.sender.send('selected-directory', files)
|
||||
}
|
||||
}
|
||||
)
|
||||
})
|
||||
|
||||
// In this file you can include the rest of your app's specific main process
|
||||
// code. You can also put them in separate files and require them here.
|
||||
@@ -0,0 +1,22 @@
|
||||
const { ipcRenderer, shell } = require('electron')
|
||||
|
||||
const selectDirBtn = document.getElementById('select-directory')
|
||||
const links = document.querySelectorAll('a[href]')
|
||||
|
||||
selectDirBtn.addEventListener('click', event => {
|
||||
ipcRenderer.send('open-file-dialog')
|
||||
})
|
||||
|
||||
ipcRenderer.on('selected-directory', (event, path) => {
|
||||
document.getElementById('selected-file').innerHTML = `You selected: ${path}`
|
||||
})
|
||||
|
||||
Array.prototype.forEach.call(links, (link) => {
|
||||
const url = link.getAttribute('href')
|
||||
if (url.indexOf('http') === 0) {
|
||||
link.addEventListener('click', (e) => {
|
||||
e.preventDefault()
|
||||
shell.openExternal(url)
|
||||
})
|
||||
}
|
||||
})
|
||||
91
docs/fiddles/native-ui/dialogs/save-dialog/index.html
Normal file
91
docs/fiddles/native-ui/dialogs/save-dialog/index.html
Normal file
@@ -0,0 +1,91 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>Save Dialog</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div>
|
||||
<h1>Use system dialogs</h1>
|
||||
|
||||
<h3>
|
||||
The <code>dialog</code> module in Electron allows you to use native
|
||||
system dialogs for opening files or directories, saving a file or
|
||||
displaying informational messages.
|
||||
</h3>
|
||||
|
||||
<p>
|
||||
This is a main process module because this process is more efficient
|
||||
with native utilities and it allows the call to happen without
|
||||
interrupting the visible elements in your page's renderer process.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Open the
|
||||
<a href="http://electron.atom.io/docs/api/dialog/">
|
||||
full API documentation (opens in new window)
|
||||
</a>
|
||||
in your browser.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div>
|
||||
<h2>Save Dialog</h2>
|
||||
<div>
|
||||
<div>
|
||||
<button button id="save-dialog">View Demo</button>
|
||||
<span id="file-saved"></span>
|
||||
</div>
|
||||
<p>
|
||||
In this demo, the <code>ipc</code> module is used to send a message
|
||||
from the renderer process instructing the main process to launch the
|
||||
save dialog. It returns the path selected by the user which can be
|
||||
relayed back to the renderer process.
|
||||
</p>
|
||||
<h5>Renderer Process</h5>
|
||||
<pre>
|
||||
<code>
|
||||
const {ipcRenderer} = require('electron')
|
||||
|
||||
const saveBtn = document.getElementById('save-dialog')
|
||||
|
||||
saveBtn.addEventListener('click', (event) => {
|
||||
ipcRenderer.send('save-dialog')
|
||||
})
|
||||
|
||||
ipcRenderer.on('saved-file', (event, path) => {
|
||||
if (!path) path = 'No path'
|
||||
document.getElementById('file-saved').innerHTML = `Path selected: ${path}`
|
||||
})
|
||||
</code>
|
||||
</pre>
|
||||
<h5>Main Process</h5>
|
||||
<pre>
|
||||
<code>
|
||||
const {ipcMain, dialog} = require('electron')
|
||||
|
||||
ipcMain.on('save-dialog', (event) => {
|
||||
const options = {
|
||||
title: 'Save an Image',
|
||||
filters: [
|
||||
{ name: 'Images', extensions: ['jpg', 'png', 'gif'] }
|
||||
]
|
||||
}
|
||||
dialog.showSaveDialog(options, (filename) => {
|
||||
event.sender.send('saved-file', filename)
|
||||
})
|
||||
})
|
||||
</code>
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
// You can also require other files to run in this process
|
||||
require("./renderer.js");
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
66
docs/fiddles/native-ui/dialogs/save-dialog/main.js
Normal file
66
docs/fiddles/native-ui/dialogs/save-dialog/main.js
Normal file
@@ -0,0 +1,66 @@
|
||||
// Modules to control application life and create native browser window
|
||||
const { app, BrowserWindow, ipcMain, dialog } = require('electron')
|
||||
|
||||
// Keep a global reference of the window object, if you don't, the window will
|
||||
// be closed automatically when the JavaScript object is garbage collected.
|
||||
let mainWindow
|
||||
|
||||
function createWindow () {
|
||||
// Create the browser window.
|
||||
mainWindow = new BrowserWindow({
|
||||
width: 800,
|
||||
height: 600,
|
||||
webPreferences: {
|
||||
nodeIntegration: true
|
||||
}
|
||||
})
|
||||
|
||||
// and load the index.html of the app.
|
||||
mainWindow.loadFile('index.html')
|
||||
|
||||
// Open the DevTools.
|
||||
// mainWindow.webContents.openDevTools()
|
||||
|
||||
// Emitted when the window is closed.
|
||||
mainWindow.on('closed', function () {
|
||||
// Dereference the window object, usually you would store windows
|
||||
// in an array if your app supports multi windows, this is the time
|
||||
// when you should delete the corresponding element.
|
||||
mainWindow = null
|
||||
})
|
||||
}
|
||||
|
||||
// This method will be called when Electron has finished
|
||||
// initialization and is ready to create browser windows.
|
||||
// Some APIs can only be used after this event occurs.
|
||||
app.on('ready', createWindow)
|
||||
|
||||
// Quit when all windows are closed.
|
||||
app.on('window-all-closed', function () {
|
||||
// On OS X it is common for applications and their menu bar
|
||||
// to stay active until the user quits explicitly with Cmd + Q
|
||||
if (process.platform !== 'darwin') {
|
||||
app.quit()
|
||||
}
|
||||
})
|
||||
|
||||
app.on('activate', function () {
|
||||
// On OS X it's common to re-create a window in the app when the
|
||||
// dock icon is clicked and there are no other windows open.
|
||||
if (mainWindow === null) {
|
||||
createWindow()
|
||||
}
|
||||
})
|
||||
|
||||
ipcMain.on('save-dialog', event => {
|
||||
const options = {
|
||||
title: 'Save an Image',
|
||||
filters: [{ name: 'Images', extensions: ['jpg', 'png', 'gif'] }]
|
||||
}
|
||||
dialog.showSaveDialog(options, filename => {
|
||||
event.sender.send('saved-file', filename)
|
||||
})
|
||||
})
|
||||
|
||||
// In this file you can include the rest of your app's specific main process
|
||||
// code. You can also put them in separate files and require them here.
|
||||
23
docs/fiddles/native-ui/dialogs/save-dialog/renderer.js
Normal file
23
docs/fiddles/native-ui/dialogs/save-dialog/renderer.js
Normal file
@@ -0,0 +1,23 @@
|
||||
const { ipcRenderer, shell } = require('electron')
|
||||
|
||||
const saveBtn = document.getElementById('save-dialog')
|
||||
const links = document.querySelectorAll('a[href]')
|
||||
|
||||
saveBtn.addEventListener('click', event => {
|
||||
ipcRenderer.send('save-dialog')
|
||||
})
|
||||
|
||||
ipcRenderer.on('saved-file', (event, path) => {
|
||||
if (!path) path = 'No path'
|
||||
document.getElementById('file-saved').innerHTML = `Path selected: ${path}`
|
||||
})
|
||||
|
||||
Array.prototype.forEach.call(links, (link) => {
|
||||
const url = link.getAttribute('href')
|
||||
if (url.indexOf('http') === 0) {
|
||||
link.addEventListener('click', (e) => {
|
||||
e.preventDefault()
|
||||
shell.openExternal(url)
|
||||
})
|
||||
}
|
||||
})
|
||||
@@ -1,64 +1,64 @@
|
||||
// Modules to control application life and create native browser window
|
||||
const { app, BrowserWindow, ipcMain, nativeImage } = require('electron')
|
||||
// Keep a global reference of the window object, if you don't, the window will
|
||||
// be closed automatically when the JavaScript object is garbage collected.
|
||||
let mainWindow
|
||||
|
||||
function createWindow () {
|
||||
// Create the browser window.
|
||||
mainWindow = new BrowserWindow({
|
||||
width: 800,
|
||||
height: 600,
|
||||
webPreferences: {
|
||||
nodeIntegration: true
|
||||
}
|
||||
})
|
||||
|
||||
// and load the index.html of the app.
|
||||
mainWindow.loadFile('index.html')
|
||||
|
||||
// Open the DevTools.
|
||||
// mainWindow.webContents.openDevTools()
|
||||
|
||||
// Emitted when the window is closed.
|
||||
mainWindow.on('closed', function () {
|
||||
// Dereference the window object, usually you would store windows
|
||||
// in an array if your app supports multi windows, this is the time
|
||||
// when you should delete the corresponding element.
|
||||
mainWindow = null
|
||||
})
|
||||
}
|
||||
|
||||
// This method will be called when Electron has finished
|
||||
// initialization and is ready to create browser windows.
|
||||
// Some APIs can only be used after this event occurs.
|
||||
app.on('ready', createWindow)
|
||||
|
||||
// Quit when all windows are closed.
|
||||
app.on('window-all-closed', function () {
|
||||
// On OS X it is common for applications and their menu bar
|
||||
// to stay active until the user quits explicitly with Cmd + Q
|
||||
if (process.platform !== 'darwin') {
|
||||
app.quit()
|
||||
}
|
||||
})
|
||||
|
||||
app.on('activate', function () {
|
||||
// On OS X it's common to re-create a window in the app when the
|
||||
// dock icon is clicked and there are no other windows open.
|
||||
if (mainWindow === null) {
|
||||
createWindow()
|
||||
}
|
||||
})
|
||||
|
||||
ipcMain.on('ondragstart', (event, filepath) => {
|
||||
const icon = nativeImage.createFromDataURL('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACQAAAAkCAYAAADhAJiYAAAAAXNSR0IArs4c6QAAAAlwSFlzAAALEwAACxMBAJqcGAAAAVlpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IlhNUCBDb3JlIDUuNC4wIj4KICAgPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4KICAgICAgPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIKICAgICAgICAgICAgeG1sbnM6dGlmZj0iaHR0cDovL25zLmFkb2JlLmNvbS90aWZmLzEuMC8iPgogICAgICAgICA8dGlmZjpPcmllbnRhdGlvbj4xPC90aWZmOk9yaWVudGF0aW9uPgogICAgICA8L3JkZjpEZXNjcmlwdGlvbj4KICAgPC9yZGY6UkRGPgo8L3g6eG1wbWV0YT4KTMInWQAACsZJREFUWAmtWFlsXFcZ/u82++Jt7IyT2Em6ZFHTpAtWIzspEgjEUhA8VNAiIYEQUvuABBIUwUMkQIVKPCIoEiABLShISEBbhFJwIGRpIKRpbNeJ7bh2HHvssR3PPnPnLnzfmRlju6EQqUc+c++c8y/fv54z1uQOh+/7Glh0TD59TE/TND7lnfa4/64OKsM071QoeZpA/y9WWvk/B4XCC06TUC+Xyw8HTXNQ1+Ww6PpOrMebewXxvBueJ6/XHOdMJBL5J9Y97m2R0SS/wweE6JxkGx5dilWr1S/7dXsEa2o4+LyFmcFcaL5zbX3Y9gh5hpeWYpSB9XV5/H678V89BGYDXnHJlCsWn4gHrGc1K9CXxferOdvPOOKUfF8cH7nUyCtklQZXih/VNNlmirk3GdBSoIcRswW7/vVkLPYi5W2Uze8bh7J+4wLfh4dViFx5/nmrUi7/MhGNvrCkBfpeWqnW/7BUdadqntQ8zwr6vhUV34xpYnDynWvcmwQNaclDXsqgLMqkocPDw7fNx7d5qIX+/PmJxKGD6VdDkeh7ztyqOFfrokGCEWiiZ1mp0uITnuKAosaT7+pNxMYTyefutcQfbA+b1XLpH5fnF97/yD335Fu6mqTqsclDINBVmI4fDxw80KPAvJSt1MZtMcLiGxYUu83p4UkgnJZlqcl3LAj3WnTkIS9lUBYNPJjueVWgg7qocyOgliFqjZsg8gq5tRdiieQTf1gq15Y8CUbRZtyWOzZwc8lEqS3PTCtgqd13ieO68BQ2uNl64tXAewktrFuX2mPdkWAxn3sxnmx7sqUTJGqso8MGS9tbXFz8DMH8bblUX3T9QARVi8RV8qljfcJy0zRlaf6mzHEuzEtmekqCoZB4rqp0OmudHtUnlEWZlE0d1EWd1N3EozourcO65pw4eTIZQTW9VazJtbqvw9XwKVFQMsKDBuNhtp4uvGGFI+IDgKnpMjYyIis3ZsQMBIR7pONsIaMsyqRs6ohY1rPUSd3EQFDqo+kdZ3Fh4aupbdu+99uFQr2A1CBs4uEAjZjIFUMHi4dVxMXzCdCXQj4vBrwVCofl0ulTcv/DAxJJJBUPc8mpoyI2JDw7bFyT+ifTcSubyXytJ51+roWBxwG9Q73WWjZ7eSUU3//nXM0NI+x0PBGrTSgsLS9JFuFxHFrvSqIrJV279gi6tjiVspTza3JjZhY+0CQZj0mlWJSeHTslCro6eFqymCcVVN77kkGjs1p4sy2VOoSlOrFwT+XR+PjkgGaZ+ycKVbRTYUdVrmaImCvzk1dlFCEJdHRJ284+ie/ol0h7p7jFvExcvCCXzp2Rqem3pAMAiqWS6JGYhFI9Mjo6KjevXVUyKEuFHrKpY6JQ8TXT3D8+OTkAHBw6o6LCFo9ag3o4JtlCyTHEt5AxKvS6YUi5kJeZG3Py0NAxlLcJ9xti+K7Mjo/JfGZRuvv6Ze+9+yWEhDZAvzg3JyhX2d6/S7q6e+TimdOS7ElLKBZDwqvmj6rztayr1fVI1IoXi4PAcYZY1tPEEO1wEVlXgRFBDcmIXTqJsS+XyhKLJ5A/OpIVXXptWUYv/UvaenfIocEhMQ2EzHHErlXFCgQl3paU1eVl6QAY8sQTCSmVihKJx1V/ogvgIYF/pACdcMBhqONoHhF88/2d+bojyA6cRvje2IdFjoSjUSnBS8hgyS9lZOzKFdmPxO3o6gQIGzwuDn1dVSCtCKPy1pZXlATXqUsVYMLRmKo87vP4Y1ioqwCdCegmMYx3W/VPn8RrSDwwIMMbcEjkYo29JZVOy+ybI7K4eksODx1VSqvligpReSVLgySM/FI5h2q062jNyL3s7FtoAyGJIlx1225UmwJF6aJRJ3XzHXO9bWvsJa3jQFlBJkz6iuXdu32HzM7MyP0PPNgAU6ko4Qzp6b+flr8MD9OYJg9CwtzL5+T65ITs2bsP3mGxN/ZbBcOn0sk20gAkLQ+huXpFi8vkoY9AoyDjxTR1mbo6Ltt275HpN0dlNxQE40mVM8Ajjxx9VAGhAvQR1akZFCq799ADysMuQqOxh2FNmamEaz51ItGLfFD9+oUJoZkLowHoFA2mljUacqOMflKuVmHpfmnfvlMuvXZeStmMBIMhcWEdjgFJtrUjXI0KchAuAg0ilxLJNoRVBxhIBm0TjjKAuqjTqTs3CQZ6QUUMGFW7eiWMUg6w+yo8YMW7DqtqlZLkUDV2ISfd29KyDwk9MjYmMyOXxQIIKuShqo4VGFNBEgeDQYqVam5N5tEePFQgURIUBCsd1EWd1XrtDUUMLARD9bKaK5ytQ2Gb75g8WMiEP6VkfnZGevv6UF1vSBW5E0PFDAweFRvlfun8WVmamhDNrkmweQ0pwaPt6M4m8mgKTTFXqcrV0ZH1FKBg6qAu6qTuJiCV1Cp2Q0NDr9Uq5Ym+oMEDlSewsoRwrVBEaij7AJ4s7zrOpumxEdm15y6558GHJVe1Zezy6zJx6aJkpq5JFB4z6zVZmBiX1VWUP0IY4CFMYcpQdZ3xqIs6oftCE5DHKwd0q/tzOV8svdDb3nk8VnG9qmgQC0ZURz8Ur91alXgSByZ6ES9kZZTr/PR16UOCh+7dq0CWyyXJ4xqCQ0nKt9YQSlPue2gAeYZzD7yNLk0wmqAreb2WYSxAJ8Dget64wxtEBlDaqVOn/K5dB67t6+t5MhoMJuc8w8UPKiQ9CQR9JK5czhZAQxPt7TKF3OiAIisUViAD2Lg5d0P2HDgoKeRaW0enyqVwBJcO5fFG5dqa7h406qaeX8384uTZL5w9+UqxhYHFp0YLIYA9ddfu3T+4UJF6Rg+YAc9D0+RoIGP1ULhpWspr10evyK7+ftWTrk9PS/++A9KZSm26cih2mMOErem6n/ZsZwA2TM/MPHXs2LEftnSTbh0Q36mIIbx44cLvOnu3f+xUwbWLmoHTCUlF6g2jBQo/GnFrnGNqSHdvr+rIKGMW1KahwEBdzHft98aNwMr8zd8/NDDwccihc0hLi3GubRjY0Bm6H19fPvnZI4c/fHd7PJ2peXYZ+WQ26JufZELjQ6lbAQtnWre0d3apY8TFIdtAo+Qri6mupsB49lBMC+QXF0YefObZT8j0eKWlswVjEyCCOXHihPGb575VCvVuf3lvetsH9rXF0rla3cnhpoIGjgsUPhR3I4TMKYJQV1Z6WO02aEjHa5mNe3OPW3OPRHVrbXFh9Ocvv/KR1372owx1Pf3005uc35Ddgtd8rsf06IdS5777zZ+mUqmPzjm6TPpmvayZOq4LyATeCzkanmiy4qEuC/yXiO8CSMRzvLs1x9phepLNZl868sy3Pyen/5hd1/EfRvWmuvSWNeaRS/RkPDI4+NjE1NSXEoXlpaNB1zqo20abi59/vu/UfM2pie7WUDVq8l3wTwnskeZ+zTbIQ17KoCzKpGzq2KqX32/roRbh8ePHdUzl0s9/5Rv9n/7go19MxCKfCkZiu3V06wrO5gocxL7Dgd/IEobEMH6rejg+auXidL5Y/vWv/vTX53/y/e/MkGajTH7fOt4RUJOY1df4RdtY6ICFRzqTySOhUOA+3Ai3o31H1ZbnlXBruFmt2iMrudy5xx9//BzWV7nXDBGN2xpjbt/5oGUEdhtO3iD47xZOvm8a5CHvpsV38wsUaMwBWsz3rbK5xr0mzdv2t9Jv/f5vhsF4J+Q63IUAAAAASUVORK5CYII=')
|
||||
|
||||
event.sender.startDrag({
|
||||
file: filepath,
|
||||
icon
|
||||
})
|
||||
})
|
||||
|
||||
// In this file you can include the rest of your app's specific main process
|
||||
// code. You can also put them in separate files and require them here.
|
||||
// Modules to control application life and create native browser window
|
||||
const { app, BrowserWindow, ipcMain, nativeImage } = require('electron')
|
||||
// Keep a global reference of the window object, if you don't, the window will
|
||||
// be closed automatically when the JavaScript object is garbage collected.
|
||||
let mainWindow
|
||||
|
||||
function createWindow () {
|
||||
// Create the browser window.
|
||||
mainWindow = new BrowserWindow({
|
||||
width: 800,
|
||||
height: 600,
|
||||
webPreferences: {
|
||||
nodeIntegration: true
|
||||
}
|
||||
})
|
||||
|
||||
// and load the index.html of the app.
|
||||
mainWindow.loadFile('index.html')
|
||||
|
||||
// Open the DevTools.
|
||||
// mainWindow.webContents.openDevTools()
|
||||
|
||||
// Emitted when the window is closed.
|
||||
mainWindow.on('closed', function () {
|
||||
// Dereference the window object, usually you would store windows
|
||||
// in an array if your app supports multi windows, this is the time
|
||||
// when you should delete the corresponding element.
|
||||
mainWindow = null
|
||||
})
|
||||
}
|
||||
|
||||
// This method will be called when Electron has finished
|
||||
// initialization and is ready to create browser windows.
|
||||
// Some APIs can only be used after this event occurs.
|
||||
app.on('ready', createWindow)
|
||||
|
||||
// Quit when all windows are closed.
|
||||
app.on('window-all-closed', function () {
|
||||
// On OS X it is common for applications and their menu bar
|
||||
// to stay active until the user quits explicitly with Cmd + Q
|
||||
if (process.platform !== 'darwin') {
|
||||
app.quit()
|
||||
}
|
||||
})
|
||||
|
||||
app.on('activate', function () {
|
||||
// On OS X it's common to re-create a window in the app when the
|
||||
// dock icon is clicked and there are no other windows open.
|
||||
if (mainWindow === null) {
|
||||
createWindow()
|
||||
}
|
||||
})
|
||||
|
||||
ipcMain.on('ondragstart', (event, filepath) => {
|
||||
const icon = nativeImage.createFromDataURL('data:image/png;base64,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')
|
||||
|
||||
event.sender.startDrag({
|
||||
file: filepath,
|
||||
icon
|
||||
})
|
||||
})
|
||||
|
||||
// In this file you can include the rest of your app's specific main process
|
||||
// code. You can also put them in separate files and require them here.
|
||||
|
||||
@@ -1,21 +1,21 @@
|
||||
const { ipcRenderer } = require('electron')
|
||||
const shell = require('electron').shell
|
||||
|
||||
const links = document.querySelectorAll('a[href]')
|
||||
|
||||
Array.prototype.forEach.call(links, (link) => {
|
||||
const url = link.getAttribute('href')
|
||||
if (url.indexOf('http') === 0) {
|
||||
link.addEventListener('click', (e) => {
|
||||
e.preventDefault()
|
||||
shell.openExternal(url)
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
const dragFileLink = document.getElementById('drag-file-link')
|
||||
|
||||
dragFileLink.addEventListener('dragstart', event => {
|
||||
event.preventDefault()
|
||||
ipcRenderer.send('ondragstart', __filename)
|
||||
})
|
||||
const { ipcRenderer } = require('electron')
|
||||
const shell = require('electron').shell
|
||||
|
||||
const links = document.querySelectorAll('a[href]')
|
||||
|
||||
Array.prototype.forEach.call(links, (link) => {
|
||||
const url = link.getAttribute('href')
|
||||
if (url.indexOf('http') === 0) {
|
||||
link.addEventListener('click', (e) => {
|
||||
e.preventDefault()
|
||||
shell.openExternal(url)
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
const dragFileLink = document.getElementById('drag-file-link')
|
||||
|
||||
dragFileLink.addEventListener('dragstart', event => {
|
||||
event.preventDefault()
|
||||
ipcRenderer.send('ondragstart', __filename)
|
||||
})
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>Open external links</title>
|
||||
</head>
|
||||
<body>
|
||||
<div class="demo">
|
||||
<div class="demo-wrapper">
|
||||
<div class="demo-box">
|
||||
<div class="demo-controls">
|
||||
<button class="demo-button" id="open-ex-links">View Demo</button>
|
||||
</div>
|
||||
<p>
|
||||
If you do not want your app to open website links
|
||||
<em>within</em> the app, you can use the <code>shell</code> module
|
||||
to open them externally. When clicked, the links will open outside
|
||||
of your app and in the user's default web browser.
|
||||
</p>
|
||||
<p>
|
||||
When the demo button is clicked, the electron website will open in
|
||||
your browser.
|
||||
</p>
|
||||
<p></p>
|
||||
<h5>Renderer Process</h5>
|
||||
<pre><code>
|
||||
const { shell } = require('electron')
|
||||
const exLinksBtn = document.getElementById('open-ex-links')
|
||||
exLinksBtn.addEventListener('click', (event) => {
|
||||
shell.openExternal('http://electron.atom.io')
|
||||
})
|
||||
</code></pre>
|
||||
|
||||
<div class="demo-protip">
|
||||
<h2>ProTip</h2>
|
||||
<strong>Open all outbound links externally.</strong>
|
||||
<p>
|
||||
You may want to open all <code>http</code> and
|
||||
<code>https</code> links outside of your app. To do this, query
|
||||
the document and loop through each link and add a listener. This
|
||||
app uses the code below which is located in
|
||||
<code>assets/ex-links.js</code>.
|
||||
</p>
|
||||
<h5>Renderer Process</h5>
|
||||
<pre><code>
|
||||
const { shell } = require('electron')
|
||||
const links = document.querySelectorAll('a[href]')
|
||||
Array.prototype.forEach.call(links, (link) => {
|
||||
const url = link.getAttribute('href')
|
||||
if (url.indexOf('http') === 0) {
|
||||
link.addEventListener('click', (e) => {
|
||||
e.preventDefault()
|
||||
shell.openExternal(url)
|
||||
})
|
||||
}})
|
||||
</code></pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
// You can also require other files to run in this process
|
||||
require("./renderer.js");
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,25 @@
|
||||
const { app, BrowserWindow } = require('electron')
|
||||
|
||||
let mainWindow = null
|
||||
|
||||
function createWindow () {
|
||||
const windowOptions = {
|
||||
width: 600,
|
||||
height: 400,
|
||||
title: 'Open External Links',
|
||||
webPreferences: {
|
||||
nodeIntegration: true
|
||||
}
|
||||
}
|
||||
|
||||
mainWindow = new BrowserWindow(windowOptions)
|
||||
mainWindow.loadFile('index.html')
|
||||
|
||||
mainWindow.on('closed', () => {
|
||||
mainWindow = null
|
||||
})
|
||||
}
|
||||
|
||||
app.on('ready', () => {
|
||||
createWindow()
|
||||
})
|
||||
@@ -0,0 +1,21 @@
|
||||
const { shell } = require('electron')
|
||||
|
||||
const exLinksBtn = document.getElementById('open-ex-links')
|
||||
|
||||
exLinksBtn.addEventListener('click', (event) => {
|
||||
shell.openExternal('http://electron.atom.io')
|
||||
})
|
||||
|
||||
const OpenAllOutboundLinks = () => {
|
||||
const links = document.querySelectorAll('a[href]')
|
||||
|
||||
Array.prototype.forEach.call(links, (link) => {
|
||||
const url = link.getAttribute('href')
|
||||
if (url.indexOf('http') === 0) {
|
||||
link.addEventListener('click', (e) => {
|
||||
e.preventDefault()
|
||||
shell.openExternal(url)
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
104
docs/fiddles/native-ui/external-links-file-manager/index.html
Normal file
104
docs/fiddles/native-ui/external-links-file-manager/index.html
Normal file
@@ -0,0 +1,104 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>Open external links and the file manager</title>
|
||||
</head>
|
||||
<body>
|
||||
<div>
|
||||
<h1>
|
||||
Open external links and the file manager
|
||||
</h1>
|
||||
<h3>
|
||||
The <code>shell</code> module in Electron allows you to access certain
|
||||
native elements like the file manager and default web browser.
|
||||
</h3>
|
||||
|
||||
<p>This module works in both the main and renderer process.</p>
|
||||
<p>
|
||||
Open the
|
||||
<a href="http://electron.atom.io/docs/api/shell">
|
||||
full API documentation (opens in new window)
|
||||
</a>
|
||||
in your browser.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div>
|
||||
<h2>Open Path in File Manager</h2>
|
||||
<div>
|
||||
<div>
|
||||
<button id="open-file-manager">
|
||||
View Demo
|
||||
</button>
|
||||
</div>
|
||||
<p>
|
||||
This demonstrates using the <code>shell</code> module to open the
|
||||
system file manager at a particular location.
|
||||
</p>
|
||||
<p>
|
||||
Clicking the demo button will open your file manager at the root.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div>
|
||||
<h2>Open External Links</h2>
|
||||
<div>
|
||||
<div>
|
||||
<button id="open-ex-links">View Demo</button>
|
||||
</div>
|
||||
<p>
|
||||
If you do not want your app to open website links
|
||||
<em>within</em> the app, you can use the <code>shell</code> module
|
||||
to open them externally. When clicked, the links will open outside
|
||||
of your app and in the user's default web browser.
|
||||
</p>
|
||||
<p>
|
||||
When the demo button is clicked, the electron website will open in
|
||||
your browser.
|
||||
</p>
|
||||
<p></p>
|
||||
|
||||
<div>
|
||||
<h2>ProTip</h2>
|
||||
<strong>Open all outbound links externally.</strong>
|
||||
<p>
|
||||
You may want to open all <code>http</code> and
|
||||
<code>https</code> links outside of your app. To do this, query
|
||||
the document and loop through each link and add a listener. This
|
||||
app uses the code below which is located in
|
||||
<code>assets/ex-links.js</code>.
|
||||
</p>
|
||||
<h5>Renderer Process</h5>
|
||||
<pre>
|
||||
<code>
|
||||
const shell = require('electron').shell
|
||||
|
||||
const links = document.querySelectorAll('a[href]')
|
||||
|
||||
Array.prototype.forEach.call(links, (link) => {
|
||||
const url = link.getAttribute('href')
|
||||
if (url.indexOf('http') === 0) {
|
||||
link.addEventListener('click', (e) => {
|
||||
e.preventDefault()
|
||||
shell.openExternal(url)
|
||||
})
|
||||
}
|
||||
})
|
||||
</code>
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
// You can also require other files to run in this process
|
||||
require("./renderer.js");
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
56
docs/fiddles/native-ui/external-links-file-manager/main.js
Normal file
56
docs/fiddles/native-ui/external-links-file-manager/main.js
Normal file
@@ -0,0 +1,56 @@
|
||||
// Modules to control application life and create native browser window
|
||||
const { app, BrowserWindow } = require('electron')
|
||||
|
||||
// Keep a global reference of the window object, if you don't, the window will
|
||||
// be closed automatically when the JavaScript object is garbage collected.
|
||||
let mainWindow
|
||||
|
||||
function createWindow () {
|
||||
// Create the browser window.
|
||||
mainWindow = new BrowserWindow({
|
||||
width: 800,
|
||||
height: 600,
|
||||
webPreferences: {
|
||||
nodeIntegration: true
|
||||
}
|
||||
})
|
||||
|
||||
// and load the index.html of the app.
|
||||
mainWindow.loadFile('index.html')
|
||||
|
||||
// Open the DevTools.
|
||||
// mainWindow.webContents.openDevTools()
|
||||
|
||||
// Emitted when the window is closed.
|
||||
mainWindow.on('closed', function () {
|
||||
// Dereference the window object, usually you would store windows
|
||||
// in an array if your app supports multi windows, this is the time
|
||||
// when you should delete the corresponding element.
|
||||
mainWindow = null
|
||||
})
|
||||
}
|
||||
|
||||
// This method will be called when Electron has finished
|
||||
// initialization and is ready to create browser windows.
|
||||
// Some APIs can only be used after this event occurs.
|
||||
app.on('ready', createWindow)
|
||||
|
||||
// Quit when all windows are closed.
|
||||
app.on('window-all-closed', function () {
|
||||
// On OS X it is common for applications and their menu bar
|
||||
// to stay active until the user quits explicitly with Cmd + Q
|
||||
if (process.platform !== 'darwin') {
|
||||
app.quit()
|
||||
}
|
||||
})
|
||||
|
||||
app.on('activate', function () {
|
||||
// On OS X it's common to re-create a window in the app when the
|
||||
// dock icon is clicked and there are no other windows open.
|
||||
if (mainWindow === null) {
|
||||
createWindow()
|
||||
}
|
||||
})
|
||||
|
||||
// In this file you can include the rest of your app's specific main process
|
||||
// code. You can also put them in separate files and require them here.
|
||||
@@ -0,0 +1,13 @@
|
||||
const { shell } = require('electron')
|
||||
const os = require('os')
|
||||
|
||||
const exLinksBtn = document.getElementById('open-ex-links')
|
||||
const fileManagerBtn = document.getElementById('open-file-manager')
|
||||
|
||||
fileManagerBtn.addEventListener('click', (event) => {
|
||||
shell.showItemInFolder(os.homedir())
|
||||
})
|
||||
|
||||
exLinksBtn.addEventListener('click', (event) => {
|
||||
shell.openExternal('http://electron.atom.io')
|
||||
})
|
||||
67
docs/fiddles/native-ui/notifications/index.html
Normal file
67
docs/fiddles/native-ui/notifications/index.html
Normal file
@@ -0,0 +1,67 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>Desktop notifications</title>
|
||||
</head>
|
||||
<body>
|
||||
<div>
|
||||
<h1>Desktop notifications</h1>
|
||||
<h3>
|
||||
The <code>notification</code> module in Electron allows you to add basic
|
||||
desktop notifications.
|
||||
</h3>
|
||||
|
||||
<p>
|
||||
Electron conveniently allows developers to send notifications with the
|
||||
<a href="https://notifications.spec.whatwg.org/">HTML5 Notification API</a>,
|
||||
using the currently running operating system’s native notification
|
||||
APIs to display it.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<b>Note:</b> Since this is an HTML5 API it is only available in the
|
||||
renderer process.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Open the
|
||||
<a href="https://electron.atom.io/docs/all/#notifications-windows-linux-macos">
|
||||
full API documentation<span>(opens in new window)</span>
|
||||
</a>
|
||||
in your browser.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div>
|
||||
<h2>Basic notification</h2>
|
||||
<div>
|
||||
<div>
|
||||
<button id="basic-noti">View demo</button>
|
||||
</div>
|
||||
<p>This demo demonstrates a basic notification. Text only.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div>
|
||||
<h2>Notification with image</h2>
|
||||
<div>
|
||||
<div>
|
||||
<button id="advanced-noti">View demo</button>
|
||||
</div>
|
||||
<p>
|
||||
This demo demonstrates a basic notification. Both text and a image
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
// You can also require other files to run in this process
|
||||
require("./renderer.js");
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
56
docs/fiddles/native-ui/notifications/main.js
Normal file
56
docs/fiddles/native-ui/notifications/main.js
Normal file
@@ -0,0 +1,56 @@
|
||||
// Modules to control application life and create native browser window
|
||||
const { app, BrowserWindow } = require('electron')
|
||||
|
||||
// Keep a global reference of the window object, if you don't, the window will
|
||||
// be closed automatically when the JavaScript object is garbage collected.
|
||||
let mainWindow
|
||||
|
||||
function createWindow () {
|
||||
// Create the browser window.
|
||||
mainWindow = new BrowserWindow({
|
||||
width: 800,
|
||||
height: 600,
|
||||
webPreferences: {
|
||||
nodeIntegration: true
|
||||
}
|
||||
})
|
||||
|
||||
// and load the index.html of the app.
|
||||
mainWindow.loadFile('index.html')
|
||||
|
||||
// Open the DevTools.
|
||||
// mainWindow.webContents.openDevTools()
|
||||
|
||||
// Emitted when the window is closed.
|
||||
mainWindow.on('closed', function () {
|
||||
// Dereference the window object, usually you would store windows
|
||||
// in an array if your app supports multi windows, this is the time
|
||||
// when you should delete the corresponding element.
|
||||
mainWindow = null
|
||||
})
|
||||
}
|
||||
|
||||
// This method will be called when Electron has finished
|
||||
// initialization and is ready to create browser windows.
|
||||
// Some APIs can only be used after this event occurs.
|
||||
app.on('ready', createWindow)
|
||||
|
||||
// Quit when all windows are closed.
|
||||
app.on('window-all-closed', function () {
|
||||
// On OS X it is common for applications and their menu bar
|
||||
// to stay active until the user quits explicitly with Cmd + Q
|
||||
if (process.platform !== 'darwin') {
|
||||
app.quit()
|
||||
}
|
||||
})
|
||||
|
||||
app.on('activate', function () {
|
||||
// On OS X it's common to re-create a window in the app when the
|
||||
// dock icon is clicked and there are no other windows open.
|
||||
if (mainWindow === null) {
|
||||
createWindow()
|
||||
}
|
||||
})
|
||||
|
||||
// In this file you can include the rest of your app's specific main process
|
||||
// code. You can also put them in separate files and require them here.
|
||||
29
docs/fiddles/native-ui/notifications/renderer.js
Normal file
29
docs/fiddles/native-ui/notifications/renderer.js
Normal file
@@ -0,0 +1,29 @@
|
||||
const basicNotification = {
|
||||
title: 'Basic Notification',
|
||||
body: 'Short message part'
|
||||
}
|
||||
|
||||
const notification = {
|
||||
title: 'Notification with image',
|
||||
body: 'Short message plus a custom image',
|
||||
icon: 'https://via.placeholder.com/150'
|
||||
}
|
||||
|
||||
const basicNotificationButton = document.getElementById('basic-noti')
|
||||
const notificationButton = document.getElementById('advanced-noti')
|
||||
|
||||
notificationButton.addEventListener('click', () => {
|
||||
const myNotification = new window.Notification(notification.title, notification)
|
||||
|
||||
myNotification.onclick = () => {
|
||||
console.log('Notification clicked')
|
||||
}
|
||||
})
|
||||
|
||||
basicNotificationButton.addEventListener('click', () => {
|
||||
const myNotification = new window.Notification(basicNotification.title, basicNotification)
|
||||
|
||||
myNotification.onclick = () => {
|
||||
console.log('Notification clicked')
|
||||
}
|
||||
})
|
||||
126
docs/fiddles/native-ui/tray/index.html
Normal file
126
docs/fiddles/native-ui/tray/index.html
Normal file
@@ -0,0 +1,126 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>Tray</title>
|
||||
</head>
|
||||
<body>
|
||||
<div>
|
||||
<h1>Tray</h1>
|
||||
<h3>
|
||||
The <code>tray</code> module allows you to create an icon in the
|
||||
operating system's notification area.
|
||||
</h3>
|
||||
<p>This icon can also have a context menu attached.</p>
|
||||
|
||||
<p>
|
||||
Open the
|
||||
<a href="http://electron.atom.io/docs/api/tray">
|
||||
full API documentation (opens in new window)
|
||||
</a>
|
||||
in your browser.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div>
|
||||
<div>
|
||||
<div>
|
||||
<button id="put-in-tray">View Demo</button>
|
||||
<span id="tray-countdown"></span>
|
||||
</div>
|
||||
<p>
|
||||
The demo button sends a message to the main process using the
|
||||
<code>ipc</code> module. In the main process the app is told to
|
||||
place an icon, with a context menu, in the tray.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
In this example the tray icon can be removed by clicking 'Remove' in
|
||||
the context menu or selecting the demo button again.
|
||||
</p>
|
||||
<h5>Main Process</h5>
|
||||
<pre>
|
||||
<code>
|
||||
const path = require('path')
|
||||
const {ipcMain, app, Menu, Tray} = require('electron')
|
||||
|
||||
let appIcon = null
|
||||
|
||||
ipcMain.on('put-in-tray', (event) => {
|
||||
const iconName = process.platform === 'win32' ? 'windows-icon.png' : 'iconTemplate.png'
|
||||
const iconPath = path.join(__dirname, iconName)
|
||||
appIcon = new Tray(iconPath)
|
||||
|
||||
const contextMenu = Menu.buildFromTemplate([{
|
||||
label: 'Remove',
|
||||
click: () => {
|
||||
event.sender.send('tray-removed')
|
||||
}
|
||||
}])
|
||||
|
||||
appIcon.setToolTip('Electron Demo in the tray.')
|
||||
appIcon.setContextMenu(contextMenu)
|
||||
})
|
||||
|
||||
ipcMain.on('remove-tray', () => {
|
||||
appIcon.destroy()
|
||||
})
|
||||
|
||||
app.on('window-all-closed', () => {
|
||||
if (appIcon) appIcon.destroy()
|
||||
})
|
||||
</code>
|
||||
</pre>
|
||||
<h5>Renderer Process</h5>
|
||||
<pre>
|
||||
<code>
|
||||
const ipc = require('electron').ipcRenderer
|
||||
|
||||
const trayBtn = document.getElementById('put-in-tray')
|
||||
let trayOn = false
|
||||
|
||||
trayBtn.addEventListener('click', function (event) {
|
||||
if (trayOn) {
|
||||
trayOn = false
|
||||
document.getElementById('tray-countdown').innerHTML = ''
|
||||
ipc.send('remove-tray')
|
||||
} else {
|
||||
trayOn = true
|
||||
const message = 'Click demo again to remove.'
|
||||
document.getElementById('tray-countdown').innerHTML = message
|
||||
ipc.send('put-in-tray')
|
||||
}
|
||||
})
|
||||
// Tray removed from context menu on icon
|
||||
ipc.on('tray-removed', function () {
|
||||
ipc.send('remove-tray')
|
||||
trayOn = false
|
||||
document.getElementById('tray-countdown').innerHTML = ''
|
||||
})
|
||||
</code>
|
||||
</pre>
|
||||
|
||||
<div>
|
||||
<h2>ProTip</h2>
|
||||
<strong>Tray support in Linux.</strong>
|
||||
<p>
|
||||
On Linux distributions that only have app indicator support, users
|
||||
will need to install <code>libappindicator1</code> to make the
|
||||
tray icon work. See the
|
||||
<a href="http://electron.atom.io/docs/api/tray">
|
||||
full API documentation (opens in new window)
|
||||
</a>
|
||||
for more details about using Tray on Linux.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
// You can also require other files to run in this process
|
||||
require("./renderer.js");
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
77
docs/fiddles/native-ui/tray/main.js
Normal file
77
docs/fiddles/native-ui/tray/main.js
Normal file
File diff suppressed because one or more lines are too long
35
docs/fiddles/native-ui/tray/renderer.js
Normal file
35
docs/fiddles/native-ui/tray/renderer.js
Normal file
@@ -0,0 +1,35 @@
|
||||
const { ipcRenderer, shell } = require('electron')
|
||||
|
||||
const trayBtn = document.getElementById('put-in-tray')
|
||||
const links = document.querySelectorAll('a[href]')
|
||||
|
||||
let trayOn = false
|
||||
|
||||
trayBtn.addEventListener('click', function (event) {
|
||||
if (trayOn) {
|
||||
trayOn = false
|
||||
document.getElementById('tray-countdown').innerHTML = ''
|
||||
ipcRenderer.send('remove-tray')
|
||||
} else {
|
||||
trayOn = true
|
||||
const message = 'Click demo again to remove.'
|
||||
document.getElementById('tray-countdown').innerHTML = message
|
||||
ipcRenderer.send('put-in-tray')
|
||||
}
|
||||
})
|
||||
// Tray removed from context menu on icon
|
||||
ipcRenderer.on('tray-removed', function () {
|
||||
ipcRenderer.send('remove-tray')
|
||||
trayOn = false
|
||||
document.getElementById('tray-countdown').innerHTML = ''
|
||||
})
|
||||
|
||||
Array.prototype.forEach.call(links, (link) => {
|
||||
const url = link.getAttribute('href')
|
||||
if (url.indexOf('http') === 0) {
|
||||
link.addEventListener('click', (e) => {
|
||||
e.preventDefault()
|
||||
shell.openExternal(url)
|
||||
})
|
||||
}
|
||||
})
|
||||
@@ -0,0 +1,92 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Hello World!</title>
|
||||
</head>
|
||||
<body>
|
||||
<section>
|
||||
<header>
|
||||
<h1>
|
||||
Protocol Handler
|
||||
</h1>
|
||||
<h3>The <code>app</code> module provides methods for handling protocols.</h3>
|
||||
<p>These methods allow you to set and unset the protocols your app should be the default app for. Similar to when a browser asks to be your default for viewing web pages.</p>
|
||||
|
||||
<p>Open the <a href="http://electron.atom.io/docs/api/app">full app API documentation<span class="u-visible-to-screen-reader">(opens in new window)</span></a> in your browser.</p>
|
||||
</header>
|
||||
|
||||
<div >
|
||||
<button id="open-in-browser" class="js-container-target demo-toggle-button">Launch current page in browser
|
||||
<div class="demo-meta u-avoid-clicks">Supports: Win, macOS <span class="demo-meta-divider">|</span> Process: Main</div>
|
||||
</button>
|
||||
<section id='open-app-link'>
|
||||
<a href="electron-api-demos://open">Now... launch the app from a web link</a>
|
||||
</section>
|
||||
<div >
|
||||
<p>You can set your app as the default app to open for a specific protocol. For instance, in this demo we set this app as the default for <code>electron-api-demos://</code>. The demo button above will launch a page in your default browser with a link. Click that link and it will re-launch this app.</p>
|
||||
<h5>Packaging</h5>
|
||||
<p>This feature will only work on macOS when your app is packaged. It will not work when you're launching it in development from the command-line. When you package your app you'll need to make sure the macOS <code>plist</code> for the app is updated to include the new protocol handler. If you're using <code>electron-packager</code> then you can add the flag <code>--extend-info</code> with a path to the <code>plist</code> you've created. The one for this app is below.</p>
|
||||
<h5>Renderer Process</h5>
|
||||
<pre><code>
|
||||
const {shell} = require('electron')
|
||||
const path = require('path')
|
||||
const protocolHandlerBtn = document.getElementById('protocol-handler')
|
||||
protocolHandlerBtn.addEventListener('click', () => {
|
||||
const pageDirectory = __dirname.replace('app.asar', 'app.asar.unpacked')
|
||||
const pagePath = path.join('file://', pageDirectory, '../../sections/system/protocol-link.html')
|
||||
shell.openExternal(pagePath)
|
||||
})
|
||||
</code></pre>
|
||||
<h5>Main Process</h5>
|
||||
<pre><code>
|
||||
const {app, dialog} = require('electron')
|
||||
const path = require('path')
|
||||
|
||||
if (process.defaultApp) {
|
||||
if (process.argv.length >= 2) {
|
||||
app.setAsDefaultProtocolClient('electron-api-demos', process.execPath, [path.resolve(process.argv[1])])
|
||||
}
|
||||
} else {
|
||||
app.setAsDefaultProtocolClient('electron-api-demos')
|
||||
}
|
||||
|
||||
app.on('open-url', (event, url) => {
|
||||
dialog.showErrorBox('Welcome Back', `You arrived from: ${url}`)
|
||||
})
|
||||
|
||||
</code></pre>
|
||||
<h5>macOS plist</h5>
|
||||
<pre><code>
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleURLTypes</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>CFBundleURLSchemes</key>
|
||||
<array>
|
||||
<string>electron-api-demos</string>
|
||||
</array>
|
||||
<key>CFBundleURLName</key>
|
||||
<string>Electron API Demos Protocol</string>
|
||||
</dict>
|
||||
</array>
|
||||
<key>ElectronTeamID</key>
|
||||
<string>VEKTX9H2N7</string>
|
||||
</dict>
|
||||
</plist>
|
||||
</code>
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
<script type="text/javascript">
|
||||
require('./renderer.js')
|
||||
</script>
|
||||
</section>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,69 @@
|
||||
// Modules to control application life and create native browser window
|
||||
const { app, BrowserWindow, dialog } = require('electron')
|
||||
const path = require('path')
|
||||
|
||||
// Keep a global reference of the window object, if you don't, the window will
|
||||
// be closed automatically when the JavaScript object is garbage collected.
|
||||
let mainWindow
|
||||
|
||||
function createWindow () {
|
||||
// Create the browser window.
|
||||
mainWindow = new BrowserWindow({
|
||||
width: 800,
|
||||
height: 600,
|
||||
webPreferences: {
|
||||
nodeIntegration: true
|
||||
}
|
||||
})
|
||||
|
||||
// and load the index.html of the app.
|
||||
mainWindow.loadFile('index.html')
|
||||
|
||||
// Open the DevTools.
|
||||
mainWindow.webContents.openDevTools()
|
||||
|
||||
// Emitted when the window is closed.
|
||||
mainWindow.on('closed', function () {
|
||||
// Dereference the window object, usually you would store windows
|
||||
// in an array if your app supports multi windows, this is the time
|
||||
// when you should delete the corresponding element.
|
||||
mainWindow = null
|
||||
})
|
||||
}
|
||||
|
||||
// This method will be called when Electron has finished
|
||||
// initialization and is ready to create browser windows.
|
||||
// Some APIs can only be used after this event occurs.
|
||||
app.on('ready', createWindow)
|
||||
|
||||
// Quit when all windows are closed.
|
||||
app.on('window-all-closed', function () {
|
||||
// On OS X it is common for applications and their menu bar
|
||||
// to stay active until the user quits explicitly with Cmd + Q
|
||||
if (process.platform !== 'darwin') {
|
||||
app.quit()
|
||||
}
|
||||
})
|
||||
|
||||
app.on('activate', function () {
|
||||
// On OS X it's common to re-create a window in the app when the
|
||||
// dock icon is clicked and there are no other windows open.
|
||||
if (mainWindow === null) {
|
||||
createWindow()
|
||||
}
|
||||
})
|
||||
|
||||
// In this file you can include the rest of your app's specific main process
|
||||
// code. You can also put them in separate files and require them here.
|
||||
|
||||
if (process.defaultApp) {
|
||||
if (process.argv.length >= 2) {
|
||||
app.setAsDefaultProtocolClient('electron-api-demos', process.execPath, [path.resolve(process.argv[1])])
|
||||
}
|
||||
} else {
|
||||
app.setAsDefaultProtocolClient('electron-api-demos')
|
||||
}
|
||||
|
||||
app.on('open-url', (event, url) => {
|
||||
dialog.showErrorBox('Welcome Back', `You arrived from: ${url}`)
|
||||
})
|
||||
@@ -0,0 +1,14 @@
|
||||
const { shell } = require('electron')
|
||||
const path = require('path')
|
||||
|
||||
const openInBrowserButton = document.getElementById('open-in-browser')
|
||||
const openAppLink = document.getElementById('open-app-link')
|
||||
// Hides openAppLink when loaded inside Electron
|
||||
openAppLink.style.display = 'none'
|
||||
|
||||
openInBrowserButton.addEventListener('click', () => {
|
||||
console.log('clicked')
|
||||
const pageDirectory = __dirname.replace('app.asar', 'app.asar.unpacked')
|
||||
const pagePath = path.join('file://', pageDirectory, 'index.html')
|
||||
shell.openExternal(pagePath)
|
||||
})
|
||||
@@ -0,0 +1,26 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
</head>
|
||||
<body>
|
||||
<div>
|
||||
<div>
|
||||
<h1>App Information</h1>
|
||||
<div>
|
||||
<div>
|
||||
<button id="app-info">View Demo</button>
|
||||
<span id="got-app-info"></span>
|
||||
</div>
|
||||
<p>The main process <code>app</code> module can be used to get the path at which your app is located on the user's computer.</p>
|
||||
<p>In this example, to get that information from the renderer process, we use the <code>ipc</code> module to send a message to the main process requesting the app's path.</p>
|
||||
<p>See the <a id="electron-docs" href="https://electronjs.org/docs/api/app">app module documentation<span class="u-visible-to-screen-reader">(opens in new window)</span></a> for more.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
// You can also require other files to run in this process
|
||||
require('./renderer.js')
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,5 @@
|
||||
const {app, ipcMain} = require('electron')
|
||||
|
||||
ipcMain.on('get-app-path', (event) => {
|
||||
event.sender.send('got-app-path', app.getAppPath())
|
||||
})
|
||||
@@ -0,0 +1,18 @@
|
||||
const {ipcRenderer} = require('electron')
|
||||
|
||||
const appInfoBtn = document.getElementById('app-info')
|
||||
const electron_doc_link = document.querySelectorAll('a[href]')
|
||||
|
||||
appInfoBtn.addEventListener('click', () => {
|
||||
ipcRenderer.send('get-app-path')
|
||||
})
|
||||
|
||||
ipcRenderer.on('got-app-path', (event, path) => {
|
||||
const message = `This app is located at: ${path}`
|
||||
document.getElementById('got-app-info').innerHTML = message
|
||||
})
|
||||
|
||||
electron_doc_link.addEventListener('click', (e) => {
|
||||
e.preventDefault()
|
||||
shell.openExternal(url)
|
||||
})
|
||||
@@ -0,0 +1,26 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
</head>
|
||||
<body>
|
||||
<div>
|
||||
<div>
|
||||
<h1>Create a frameless window</h1>
|
||||
<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
|
||||
a browser window frameless by setting
|
||||
<code>frame</code> to <code>false</code> when creating the window.</p>
|
||||
<div>
|
||||
<button id="frameless-window">View Demo</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
<script>
|
||||
require('./renderer.js')
|
||||
</script>
|
||||
</html>
|
||||
@@ -0,0 +1,25 @@
|
||||
const { app, BrowserWindow } = require('electron')
|
||||
|
||||
let mainWindow = null
|
||||
|
||||
function createWindow () {
|
||||
const windowOptions = {
|
||||
width: 600,
|
||||
height: 400,
|
||||
title: 'Create a frameless window',
|
||||
webPreferences: {
|
||||
nodeIntegration: true
|
||||
}
|
||||
}
|
||||
|
||||
mainWindow = new BrowserWindow(windowOptions)
|
||||
mainWindow.loadFile('index.html')
|
||||
|
||||
mainWindow.on('closed', () => {
|
||||
mainWindow = null
|
||||
})
|
||||
}
|
||||
|
||||
app.on('ready', () => {
|
||||
createWindow()
|
||||
})
|
||||
@@ -0,0 +1,12 @@
|
||||
const { BrowserWindow } = require('electron').remote
|
||||
|
||||
const newWindowBtn = document.getElementById('frameless-window')
|
||||
|
||||
newWindowBtn.addEventListener('click', (event) => {
|
||||
let win = new BrowserWindow({ frame: false })
|
||||
|
||||
win.on('close', () => { win = null })
|
||||
|
||||
win.loadURL('data:text/html,<h2>Hello World!</h2><a id="close" href="javascript:window.close()">Close this Window</a>')
|
||||
win.show()
|
||||
})
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user