chore: extend linting of code blocks in the docs (#40245)

* chore: extend linting of code blocks in the docs

* chore: combine lint:markdownlint and lint:markdown scripts
This commit is contained in:
David Sanders 2023-11-20 23:50:08 -08:00 committed by GitHub
parent d6bb9b40b0
commit 3d2a754531
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
71 changed files with 510 additions and 286 deletions

View file

@ -12,7 +12,7 @@ including instances of `BrowserWindow`, `BrowserView`, and `WebView`. You
can open them programmatically by calling the `openDevTools()` API on the
`webContents` of the instance:
```javascript
```js
const { BrowserWindow } = require('electron')
const win = new BrowserWindow()

View file

@ -41,27 +41,27 @@ $ asar list /path/to/example.asar
Read a file in the ASAR archive:
```javascript
```js
const fs = require('node:fs')
fs.readFileSync('/path/to/example.asar/file.txt')
```
List all files under the root of the archive:
```javascript
```js
const fs = require('node:fs')
fs.readdirSync('/path/to/example.asar')
```
Use a module from the archive:
```javascript @ts-nocheck
```js @ts-nocheck
require('./path/to/example.asar/dir/module.js')
```
You can also display a web page in an ASAR archive with `BrowserWindow`:
```javascript
```js
const { BrowserWindow } = require('electron')
const win = new BrowserWindow()
@ -90,7 +90,7 @@ For some cases like verifying the ASAR archive's checksum, we need to read the
content of an ASAR archive as a file. For this purpose you can use the built-in
`original-fs` module which provides original `fs` APIs without `asar` support:
```javascript
```js
const originalFs = require('original-fs')
originalFs.readFileSync('/path/to/example.asar')
```
@ -98,7 +98,7 @@ originalFs.readFileSync('/path/to/example.asar')
You can also set `process.noAsar` to `true` to disable the support for `asar` in
the `fs` module:
```javascript
```js
const fs = require('node:fs')
process.noAsar = true
fs.readFileSync('/path/to/example.asar')

View file

@ -16,7 +16,7 @@ Context isolation has been enabled by default since Electron 12, and it is a rec
Exposing APIs from your preload script to a loaded website in the renderer process is a common use-case. With context isolation disabled, your preload script would share a common global `window` object with the renderer. You could then attach arbitrary properties to a preload script:
```javascript title='preload.js' @ts-nocheck
```js title='preload.js' @ts-nocheck
// preload with contextIsolation disabled
window.myAPI = {
doAThing: () => {}
@ -25,7 +25,7 @@ window.myAPI = {
The `doAThing()` function could then be used directly in the renderer process:
```javascript title='renderer.js' @ts-nocheck
```js title='renderer.js' @ts-nocheck
// use the exposed API in the renderer
window.myAPI.doAThing()
```
@ -34,7 +34,7 @@ window.myAPI.doAThing()
There is a dedicated module in Electron to help you do this in a painless way. The [`contextBridge`](../api/context-bridge.md) module can be used to **safely** expose APIs from your preload script's isolated context to the context the website is running in. The API will also be accessible from the website on `window.myAPI` just like it was before.
```javascript title='preload.js'
```js title='preload.js'
// preload with contextIsolation enabled
const { contextBridge } = require('electron')
@ -43,7 +43,7 @@ contextBridge.exposeInMainWorld('myAPI', {
})
```
```javascript title='renderer.js' @ts-nocheck
```js title='renderer.js' @ts-nocheck
// use the exposed API in the renderer
window.myAPI.doAThing()
```
@ -54,7 +54,7 @@ Please read the `contextBridge` documentation linked above to fully understand i
Just enabling `contextIsolation` and using `contextBridge` does not automatically mean that everything you do is safe. For instance, this code is **unsafe**.
```javascript title='preload.js'
```js title='preload.js'
// ❌ Bad code
contextBridge.exposeInMainWorld('myAPI', {
send: ipcRenderer.send
@ -63,7 +63,7 @@ contextBridge.exposeInMainWorld('myAPI', {
It directly exposes a powerful API without any kind of argument filtering. This would allow any website to send arbitrary IPC messages, which you do not want to be possible. The correct way to expose IPC-based APIs would instead be to provide one method per IPC message.
```javascript title='preload.js'
```js title='preload.js'
// ✅ Good code
contextBridge.exposeInMainWorld('myAPI', {
loadPreferences: () => ipcRenderer.invoke('load-prefs')
@ -76,7 +76,7 @@ If you're building your Electron app with TypeScript, you'll want to add types t
For example, given this `preload.ts` script:
```typescript title='preload.ts'
```ts title='preload.ts'
contextBridge.exposeInMainWorld('electronAPI', {
loadPreferences: () => ipcRenderer.invoke('load-prefs')
})
@ -84,7 +84,7 @@ contextBridge.exposeInMainWorld('electronAPI', {
You can create a `interface.d.ts` declaration file and globally augment the `Window` interface:
```typescript title='interface.d.ts' @ts-noisolate
```ts title='interface.d.ts' @ts-noisolate
export interface IElectronAPI {
loadPreferences: () => Promise<void>,
}
@ -98,7 +98,7 @@ declare global {
Doing so will ensure that the TypeScript compiler will know about the `electronAPI` property on your global `window` object when writing scripts in your renderer process:
```typescript title='renderer.ts'
```ts title='renderer.ts'
window.electronAPI.loadPreferences()
```

View file

@ -50,7 +50,7 @@ of this theming, due to the use of the macOS 10.14 SDK.
This example demonstrates an Electron application that derives its theme colors from the
`nativeTheme`. Additionally, it provides theme toggle and reset controls using IPC channels.
```javascript fiddle='docs/fiddles/features/dark-mode'
```fiddle docs/fiddles/features/dark-mode
```

View file

@ -26,7 +26,7 @@ This example demonstrates an Electron application that automatically selects
the first available bluetooth device when the `Test Bluetooth` button is
clicked.
```javascript fiddle='docs/fiddles/features/web-bluetooth'
```fiddle docs/fiddles/features/web-bluetooth
```
@ -61,7 +61,7 @@ By default Electron employs the same [blocklist](https://github.com/WICG/webhid/
used by Chromium. If you wish to override this behavior, you can do so by
setting the `disable-hid-blocklist` flag:
```javascript
```js
app.commandLine.appendSwitch('disable-hid-blocklist')
```
@ -72,7 +72,7 @@ HID devices through [`ses.setDevicePermissionHandler(handler)`](../api/session.m
and through [`select-hid-device` event on the Session](../api/session.md#event-select-hid-device)
when the `Test WebHID` button is clicked.
```javascript fiddle='docs/fiddles/features/web-hid'
```fiddle docs/fiddles/features/web-hid
```
@ -112,7 +112,7 @@ as well as demonstrating selecting the first available Arduino Uno serial device
[`select-serial-port` event on the Session](../api/session.md#event-select-serial-port)
when the `Test Web Serial` button is clicked.
```javascript fiddle='docs/fiddles/features/web-serial'
```fiddle docs/fiddles/features/web-serial
```
@ -152,6 +152,6 @@ USB devices (if they are attached) through [`ses.setDevicePermissionHandler(hand
and through [`select-usb-device` event on the Session](../api/session.md#event-select-usb-device)
when the `Test WebUSB` button is clicked.
```javascript fiddle='docs/fiddles/features/web-usb'
```fiddle docs/fiddles/features/web-usb
```

View file

@ -33,7 +33,7 @@ Using the [React Developer Tools][react-devtools] as an example:
1. Pass the location of the extension to the [`ses.loadExtension`][load-extension]
API. For React Developer Tools `v4.9.0`, it looks something like:
```javascript
```js
const { app, session } = require('electron')
const path = require('node:path')
const os = require('node:os')

View file

@ -16,16 +16,7 @@ Once Fiddle is installed, you can press on the "Open in Fiddle" button that you
will find below code samples like the following one:
```fiddle docs/fiddles/quick-start
window.addEventListener('DOMContentLoaded', () => {
const replaceText = (selector, text) => {
const element = document.getElementById(selector)
if (element) element.innerText = text
}
for (const type of ['chrome', 'node', 'electron']) {
replaceText(`${type}-version`, process.versions[type])
}
})
```
If there is still something that you do not know how to do, please take a look at the [API][app]

View file

@ -34,7 +34,7 @@ To test In-App Purchase in development with Electron you'll have to change the `
Here is an example that shows how to use In-App Purchases in Electron. You'll have to replace the product ids by the identifiers of the products created with iTunes Connect (the identifier of `com.example.app.product1` is `product1`). Note that you have to listen to the `transactions-updated` event as soon as possible in your app.
```javascript
```js
// Main process
const { inAppPurchase } = require('electron')
const PRODUCT_IDS = ['id1', 'id2']

View file

@ -66,7 +66,7 @@ You can use environment variables to override the base URL, the path at which to
look for Electron binaries, and the binary filename. The URL used by `@electron/get`
is composed as follows:
```javascript @ts-nocheck
```js @ts-nocheck
url = ELECTRON_MIRROR + ELECTRON_CUSTOM_DIR + '/' + ELECTRON_CUSTOM_FILENAME
```

View file

@ -50,7 +50,7 @@ sections.
In the main process, set an IPC listener on the `set-title` channel with the `ipcMain.on` API:
```javascript {6-10,22} title='main.js (Main Process)'
```js {6-10,22} title='main.js (Main Process)'
const { app, BrowserWindow, ipcMain } = require('electron')
const path = require('node:path')
@ -96,7 +96,7 @@ you need to choose which APIs to expose from your preload script using the `cont
In your preload script, add the following code, which will expose a global `window.electronAPI`
variable to your renderer process.
```javascript title='preload.js (Preload Script)'
```js title='preload.js (Preload Script)'
const { contextBridge, ipcRenderer } = require('electron')
contextBridge.exposeInMainWorld('electronAPI', {
@ -138,7 +138,7 @@ To make these elements interactive, we'll be adding a few lines of code in the i
`renderer.js` file that leverages the `window.electronAPI` functionality exposed from the preload
script:
```javascript title='renderer.js (Renderer Process)' @ts-expect-error=[4,5]
```js title='renderer.js (Renderer Process)' @ts-expect-error=[4,5]
const setButton = document.getElementById('btn')
const titleInput = document.getElementById('title')
setButton.addEventListener('click', () => {
@ -181,7 +181,7 @@ provided to the renderer process. Please refer to
[#24427](https://github.com/electron/electron/issues/24427) for details.
:::
```javascript {6-13,25} title='main.js (Main Process)'
```js {6-13,25} title='main.js (Main Process)'
const { app, BrowserWindow, dialog, ipcMain } = require('electron')
const path = require('node:path')
@ -225,7 +225,7 @@ In the preload script, we expose a one-line `openFile` function that calls and r
`ipcRenderer.invoke('dialog:openFile')`. We'll be using this API in the next step to call the
native dialog from our renderer's user interface.
```javascript title='preload.js (Preload Script)'
```js title='preload.js (Preload Script)'
const { contextBridge, ipcRenderer } = require('electron')
contextBridge.exposeInMainWorld('electronAPI', {
@ -263,7 +263,7 @@ The UI consists of a single `#btn` button element that will be used to trigger o
a `#filePath` element that will be used to display the path of the selected file. Making these
pieces work will take a few lines of code in the renderer process script:
```javascript title='renderer.js (Renderer Process)' @ts-expect-error=[5]
```js title='renderer.js (Renderer Process)' @ts-expect-error=[5]
const btn = document.getElementById('btn')
const filePathElement = document.getElementById('filePath')
@ -299,7 +299,7 @@ The `ipcRenderer.send` API that we used for single-way communication can also be
perform two-way communication. This was the recommended way for asynchronous two-way communication
via IPC prior to Electron 7.
```javascript title='preload.js (Preload Script)'
```js title='preload.js (Preload Script)'
// You can also put expose this code to the renderer
// process with the `contextBridge` API
const { ipcRenderer } = require('electron')
@ -310,7 +310,7 @@ ipcRenderer.on('asynchronous-reply', (_event, arg) => {
ipcRenderer.send('asynchronous-message', 'ping')
```
```javascript title='main.js (Main Process)'
```js title='main.js (Main Process)'
ipcMain.on('asynchronous-message', (event, arg) => {
console.log(arg) // prints "ping" in the Node console
// works like `send`, but returning a message back
@ -332,7 +332,7 @@ channels, you would need to add additional app code to track each call and respo
The `ipcRenderer.sendSync` API sends a message to the main process and waits _synchronously_ for a
response.
```javascript title='main.js (Main Process)'
```js title='main.js (Main Process)'
const { ipcMain } = require('electron')
ipcMain.on('synchronous-message', (event, arg) => {
console.log(arg) // prints "ping" in the Node console
@ -340,7 +340,7 @@ ipcMain.on('synchronous-message', (event, arg) => {
})
```
```javascript title='preload.js (Preload Script)'
```js title='preload.js (Preload Script)'
// You can also put expose this code to the renderer
// process with the `contextBridge` API
const { ipcRenderer } = require('electron')
@ -376,7 +376,7 @@ For this demo, we'll need to first build a custom menu in the main process using
module that uses the `webContents.send` API to send an IPC message from the main process to the
target renderer.
```javascript {11-26} title='main.js (Main Process)'
```js {11-26} title='main.js (Main Process)'
const { app, BrowserWindow, Menu, ipcMain } = require('electron')
const path = require('node:path')
@ -412,7 +412,7 @@ function createWindow () {
For the purposes of the tutorial, it's important to note that the `click` handler
sends a message (either `1` or `-1`) to the renderer process through the `update-counter` channel.
```javascript @ts-type={mainWindow:Electron.BrowserWindow}
```js @ts-type={mainWindow:Electron.BrowserWindow}
click: () => mainWindow.webContents.send('update-counter', -1)
```
@ -425,7 +425,7 @@ Make sure you're loading the `index.html` and `preload.js` entry points for the
Like in the previous renderer-to-main example, we use the `contextBridge` and `ipcRenderer`
modules in the preload script to expose IPC functionality to the renderer process:
```javascript title='preload.js (Preload Script)'
```js title='preload.js (Preload Script)'
const { contextBridge, ipcRenderer } = require('electron')
contextBridge.exposeInMainWorld('electronAPI', {
@ -447,7 +447,7 @@ Use a custom handler that invoke the `callback` only with the desired arguments.
In the case of this minimal example, you can call `ipcRenderer.on` directly in the preload script
rather than exposing it over the context bridge.
```javascript title='preload.js (Preload Script)'
```js title='preload.js (Preload Script)'
const { ipcRenderer } = require('electron')
window.addEventListener('DOMContentLoaded', () => {
@ -488,7 +488,7 @@ To tie it all together, we'll create an interface in the loaded HTML file that c
Finally, to make the values update in the HTML document, we'll add a few lines of DOM manipulation
so that the value of the `#counter` element is updated whenever we fire an `update-counter` event.
```javascript title='renderer.js (Renderer Process)' @ts-window-type={electronAPI:{onUpdateCounter:(callback:(value:number)=>void)=>void}}
```js title='renderer.js (Renderer Process)' @ts-window-type={electronAPI:{onUpdateCounter:(callback:(value:number)=>void)=>void}}
const counter = document.getElementById('counter')
window.electronAPI.onUpdateCounter((value) => {
@ -511,7 +511,7 @@ We can demonstrate this with slight modifications to the code from the previous
renderer process, expose another API to send a reply back to the main process through the
`counter-value` channel.
```javascript title='preload.js (Preload Script)'
```js title='preload.js (Preload Script)'
const { contextBridge, ipcRenderer } = require('electron')
contextBridge.exposeInMainWorld('electronAPI', {
@ -520,7 +520,7 @@ contextBridge.exposeInMainWorld('electronAPI', {
})
```
```javascript title='renderer.js (Renderer Process)' @ts-window-type={electronAPI:{onUpdateCounter:(callback:(value:number)=>void)=>void,counterValue:(value:number)=>void}}
```js title='renderer.js (Renderer Process)' @ts-window-type={electronAPI:{onUpdateCounter:(callback:(value:number)=>void)=>void,counterValue:(value:number)=>void}}
const counter = document.getElementById('counter')
window.electronAPI.onUpdateCounter((value) => {
@ -533,7 +533,7 @@ window.electronAPI.onUpdateCounter((value) => {
In the main process, listen for `counter-value` events and handle them appropriately.
```javascript title='main.js (Main Process)'
```js title='main.js (Main Process)'
// ...
ipcMain.on('counter-value', (_event, value) => {
console.log(value) // will print value to Node console

View file

@ -14,11 +14,19 @@ To configure a local keyboard shortcut, you need to specify an [`accelerator`][]
property when creating a [MenuItem][] within the [Menu][] module.
Starting with a working application from the
[Quick Start Guide](quick-start.md), update the `main.js` file with the
following lines:
[Quick Start Guide](quick-start.md), update the `main.js` to be:
```javascript fiddle='docs/fiddles/features/keyboard-shortcuts/local'
const { Menu, MenuItem } = require('electron')
```fiddle docs/fiddles/features/keyboard-shortcuts/local
const { app, BrowserWindow, Menu, MenuItem } = require('electron/main')
function createWindow () {
const win = new BrowserWindow({
width: 800,
height: 600
})
win.loadFile('index.html')
}
const menu = new Menu()
menu.append(new MenuItem({
@ -31,6 +39,20 @@ menu.append(new MenuItem({
}))
Menu.setApplicationMenu(menu)
app.whenReady().then(createWindow)
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit()
}
})
app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0) {
createWindow()
}
})
```
> NOTE: In the code above, you can see that the accelerator differs based on the
@ -53,17 +75,37 @@ module to detect keyboard events even when the application does not have
keyboard focus.
Starting with a working application from the
[Quick Start Guide](quick-start.md), update the `main.js` file with the
following lines:
[Quick Start Guide](quick-start.md), update the `main.js` to be:
```javascript fiddle='docs/fiddles/features/keyboard-shortcuts/global' @ts-type={createWindow:()=>void}
const { app, globalShortcut } = require('electron')
```fiddle docs/fiddles/features/keyboard-shortcuts/global
const { app, BrowserWindow, globalShortcut } = require('electron/main')
function createWindow () {
const win = new BrowserWindow({
width: 800,
height: 600
})
win.loadFile('index.html')
}
app.whenReady().then(() => {
globalShortcut.register('Alt+CommandOrControl+I', () => {
console.log('Electron loves global shortcuts!')
})
}).then(createWindow)
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit()
}
})
app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0) {
createWindow()
}
})
```
> NOTE: In the code above, the `CommandOrControl` combination uses `Command`
@ -81,8 +123,8 @@ If you want to handle keyboard shortcuts within a [BrowserWindow][], you can
listen for the `keyup` and `keydown` [DOM events][dom-events] inside the
renderer process using the [addEventListener() API][addEventListener-api].
```javascript fiddle='docs/fiddles/features/keyboard-shortcuts/web-apis|focus=renderer.js'
const handleKeyPress = (event) => {
```fiddle docs/fiddles/features/keyboard-shortcuts/web-apis|focus=renderer.js
function handleKeyPress (event) {
// You can put code here to handle the keypress.
document.getElementById('last-keypress').innerText = event.key
console.log(`You pressed ${event.key}`)
@ -105,8 +147,8 @@ Starting with a working application from the
[Quick Start Guide](quick-start.md), update the `main.js` file with the
following lines:
```javascript fiddle='docs/fiddles/features/keyboard-shortcuts/interception-from-main'
const { app, BrowserWindow } = require('electron')
```fiddle docs/fiddles/features/keyboard-shortcuts/interception-from-main
const { app, BrowserWindow } = require('electron/main')
app.whenReady().then(() => {
const win = new BrowserWindow({ width: 800, height: 600 })

View file

@ -25,14 +25,14 @@ we will use will be "`electron-fiddle://`".
First, we will import the required modules from `electron`. These modules help
control our application lifecycle and create a native browser window.
```javascript
```js
const { app, BrowserWindow, shell } = require('electron')
const path = require('node:path')
```
Next, we will proceed to register our application to handle all "`electron-fiddle://`" protocols.
```javascript
```js
if (process.defaultApp) {
if (process.argv.length >= 2) {
app.setAsDefaultProtocolClient('electron-fiddle', process.execPath, [path.resolve(process.argv[1])])
@ -44,7 +44,7 @@ if (process.defaultApp) {
We will now define the function in charge of creating our browser window and load our application's `index.html` file.
```javascript
```js
let mainWindow
const createWindow = () => {
@ -67,7 +67,7 @@ This code will be different in Windows and Linux compared to MacOS. This is due
#### Windows and Linux code:
```javascript @ts-type={mainWindow:Electron.BrowserWindow} @ts-type={createWindow:()=>void}
```js @ts-type={mainWindow:Electron.BrowserWindow} @ts-type={createWindow:()=>void}
const gotTheLock = app.requestSingleInstanceLock()
if (!gotTheLock) {
@ -92,7 +92,7 @@ if (!gotTheLock) {
#### MacOS code:
```javascript @ts-type={createWindow:()=>void}
```js @ts-type={createWindow:()=>void}
// 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.
@ -108,7 +108,7 @@ app.on('open-url', (event, url) => {
Finally, we will add some additional code to handle when someone closes our application.
```javascript
```js
// Quit when all windows are closed, except on macOS. There, it's common
// for applications and their menu bar to stay active until the user quits
// explicitly with Cmd + Q.
@ -167,7 +167,7 @@ If you're using Electron Packager's API, adding support for protocol handlers is
Electron Forge is handled, except
`protocols` is part of the Packager options passed to the `packager` function.
```javascript @ts-nocheck
```js @ts-nocheck
const packager = require('@electron/packager')
packager({

View file

@ -23,10 +23,10 @@ To set your custom dock menu, you need to use the
[`app.dock.setMenu`](../api/dock.md#docksetmenumenu-macos) API,
which is only available on macOS.
```javascript fiddle='docs/fiddles/features/macos-dock-menu'
const { app, BrowserWindow, Menu } = require('electron')
```fiddle docs/fiddles/features/macos-dock-menu
const { app, BrowserWindow, Menu } = require('electron/main')
const createWindow = () => {
function createWindow () {
const win = new BrowserWindow({
width: 800,
height: 600

View file

@ -9,7 +9,7 @@ It is possible to use Node.js features in Electron's Web Workers, to do
so the `nodeIntegrationInWorker` option should be set to `true` in
`webPreferences`.
```javascript
```js
const win = new BrowserWindow({
webPreferences: {
nodeIntegrationInWorker: true
@ -42,7 +42,7 @@ safe.
The only way to load a native module safely for now, is to make sure the app
loads no native modules after the Web Workers get started.
```javascript @ts-expect-error=[1]
```js @ts-expect-error=[1]
process.dlopen = () => {
throw new Error('Load native module is not safe')
}

View file

@ -44,7 +44,7 @@ Add a draggable element to `index.html`, and reference your renderer script:
In `renderer.js` set up the renderer process to handle drag events by calling the method you added via the [`contextBridge`][] above.
```javascript @ts-expect-error=[3]
```js @ts-expect-error=[3]
document.getElementById('drag').ondragstart = (event) => {
event.preventDefault()
window.electron.startDrag('drag-and-drop.md')
@ -56,15 +56,55 @@ document.getElementById('drag').ondragstart = (event) => {
In the Main process (`main.js` file), expand the received event with a path to the file that is
being dragged and an icon:
```javascript fiddle='docs/fiddles/features/drag-and-drop'
const { ipcMain } = require('electron')
```fiddle docs/fiddles/features/drag-and-drop
const { app, BrowserWindow, ipcMain } = require('electron/main')
const path = require('node:path')
const fs = require('node:fs')
const https = require('node:https')
function createWindow () {
const win = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
preload: path.join(__dirname, 'preload.js')
}
})
win.loadFile('index.html')
}
const iconName = path.join(__dirname, 'iconForDragAndDrop.png')
const icon = fs.createWriteStream(iconName)
// Create a new file to copy - you can also copy existing files.
fs.writeFileSync(path.join(__dirname, 'drag-and-drop-1.md'), '# First file to test drag and drop')
fs.writeFileSync(path.join(__dirname, 'drag-and-drop-2.md'), '# Second file to test drag and drop')
https.get('https://img.icons8.com/ios/452/drag-and-drop.png', (response) => {
response.pipe(icon)
})
app.whenReady().then(createWindow)
ipcMain.on('ondragstart', (event, filePath) => {
event.sender.startDrag({
file: filePath,
icon: '/path/to/icon.png'
file: path.join(__dirname, filePath),
icon: iconName
})
})
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit()
}
})
app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0) {
createWindow()
}
})
```
After launching the Electron application, try dragging and dropping

View file

@ -30,16 +30,38 @@ new Notification({
Here's a full example that you can open with Electron Fiddle:
```javascript fiddle='docs/fiddles/features/notifications/main'
const { Notification } = require('electron')
```fiddle docs/fiddles/features/notifications/main
const { app, BrowserWindow, Notification } = require('electron/main')
function createWindow () {
const win = new BrowserWindow({
width: 800,
height: 600
})
win.loadFile('index.html')
}
const NOTIFICATION_TITLE = 'Basic Notification'
const NOTIFICATION_BODY = 'Notification from the Main process'
new Notification({
title: NOTIFICATION_TITLE,
body: NOTIFICATION_BODY
}).show()
function showNotification () {
new Notification({ title: NOTIFICATION_TITLE, body: NOTIFICATION_BODY }).show()
}
app.whenReady().then(createWindow).then(showNotification)
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit()
}
})
app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0) {
createWindow()
}
})
```
### Show notifications in the renderer process
@ -59,14 +81,13 @@ new Notification(NOTIFICATION_TITLE, { body: NOTIFICATION_BODY }).onclick =
Here's a full example that you can open with Electron Fiddle:
```javascript fiddle='docs/fiddles/features/notifications/renderer'
```fiddle docs/fiddles/features/notifications/renderer|focus=renderer.js
const NOTIFICATION_TITLE = 'Title'
const NOTIFICATION_BODY =
'Notification from the Renderer process. Click to log to console.'
const CLICK_MESSAGE = 'Notification clicked'
const NOTIFICATION_BODY = 'Notification from the Renderer process. Click to log to console.'
const CLICK_MESSAGE = 'Notification clicked!'
new Notification(NOTIFICATION_TITLE, { body: NOTIFICATION_BODY }).onclick =
() => console.log(CLICK_MESSAGE)
new window.Notification(NOTIFICATION_TITLE, { body: NOTIFICATION_BODY })
.onclick = () => { document.getElementById('output').innerText = CLICK_MESSAGE }
```
## Platform considerations

View file

@ -39,22 +39,44 @@ To enable this mode, GPU acceleration has to be disabled by calling the
## Example
```javascript fiddle='docs/fiddles/features/offscreen-rendering'
const { app, BrowserWindow } = require('electron')
```fiddle docs/fiddles/features/offscreen-rendering
const { app, BrowserWindow } = require('electron/main')
const fs = require('node:fs')
const path = require('node:path')
app.disableHardwareAcceleration()
let win
app.whenReady().then(() => {
win = new BrowserWindow({ webPreferences: { offscreen: true } })
function createWindow () {
const win = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
offscreen: true
}
})
win.loadURL('https://github.com')
win.webContents.on('paint', (event, dirty, image) => {
fs.writeFileSync('ex.png', image.toPNG())
})
win.webContents.setFrameRate(60)
console.log(`The screenshot has been successfully saved to ${path.join(process.cwd(), 'ex.png')}`)
}
app.whenReady().then(() => {
createWindow()
app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0) {
createWindow()
}
})
})
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit()
}
})
```

View file

@ -50,12 +50,12 @@ See the [API documentation for more options and modes][setprogressbar].
In this example, we add a progress bar to the main window that increments over time
using Node.js timers.
```javascript fiddle='docs/fiddles/features/progress-bar'
const { app, BrowserWindow } = require('electron')
```fiddle docs/fiddles/features/progress-bar
const { app, BrowserWindow } = require('electron/main')
let progressInterval
const createWindow = () => {
function createWindow () {
const win = new BrowserWindow({
width: 800,
height: 600
@ -73,8 +73,11 @@ const createWindow = () => {
win.setProgressBar(c)
// increment or reset progress bar
if (c < 2) c += INCREMENT
else c = 0
if (c < 2) {
c += INCREMENT
} else {
c = (-INCREMENT * 5) // reset to a bit less than 0 to show reset state
}
}, INTERVAL_DELAY)
}

View file

@ -24,12 +24,12 @@ the application via JumpList or dock menu, respectively.
### Managing recent documents
```javascript fiddle='docs/fiddles/features/recent-documents'
const { app, BrowserWindow } = require('electron')
```fiddle docs/fiddles/features/recent-documents
const { app, BrowserWindow } = require('electron/main')
const fs = require('node:fs')
const path = require('node:path')
const createWindow = () => {
function createWindow () {
const win = new BrowserWindow({
width: 800,
height: 600
@ -116,7 +116,7 @@ following code snippet to your menu template:
Make sure the application menu is added after the [`'ready'`](../api/app.md#event-ready)
event and not before, or the menu item will be disabled:
```javascript
```js
const { app, Menu } = require('electron')
const template = [

View file

@ -27,22 +27,30 @@ To set the represented file of window, you can use the
## Example
```javascript fiddle='docs/fiddles/features/represented-file'
const { app, BrowserWindow } = require('electron')
```fiddle docs/fiddles/features/represented-file
const { app, BrowserWindow } = require('electron/main')
const os = require('node:os')
const createWindow = () => {
function createWindow () {
const win = new BrowserWindow({
width: 800,
height: 600
})
}
app.whenReady().then(() => {
const win = new BrowserWindow()
win.setRepresentedFilename(os.homedir())
win.setDocumentEdited(true)
win.loadFile('index.html')
}
app.whenReady().then(() => {
createWindow()
app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0) {
createWindow()
}
})
})
app.on('window-all-closed', () => {
@ -50,12 +58,6 @@ app.on('window-all-closed', () => {
app.quit()
}
})
app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0) {
createWindow()
}
})
```
After launching the Electron application, click on the title with `Command` or

View file

@ -375,7 +375,7 @@ which can be set using Electron's
[`webRequest.onHeadersReceived`](../api/web-request.md#webrequestonheadersreceivedfilter-listener)
handler:
```javascript title='main.js (Main Process)'
```js title='main.js (Main Process)'
const { session } = require('electron')
session.defaultSession.webRequest.onHeadersReceived((details, callback) => {

View file

@ -81,14 +81,14 @@ You can use the [app.isPackaged](../api/app.md#appispackaged-readonly) API to ch
:::
```javascript title='main.js'
```js title='main.js'
const { app, autoUpdater, dialog } = require('electron')
```
Next, construct the URL of the update server feed and tell
[autoUpdater](../api/auto-updater.md) about it:
```javascript title='main.js'
```js title='main.js'
const server = 'https://your-deployment-url.com'
const url = `${server}/update/${process.platform}/${app.getVersion()}`
@ -97,7 +97,7 @@ autoUpdater.setFeedURL({ url })
As the final step, check for updates. The example below will check every minute:
```javascript title='main.js'
```js title='main.js'
setInterval(() => {
autoUpdater.checkForUpdates()
}, 60000)
@ -113,7 +113,7 @@ Now that you've configured the basic update mechanism for your application, you
need to ensure that the user will get notified when there's an update. This
can be achieved using the [autoUpdater API events](../api/auto-updater.md#events):
```javascript title="main.js" @ts-expect-error=[11]
```js title="main.js" @ts-expect-error=[11]
autoUpdater.on('update-downloaded', (event, releaseNotes, releaseName) => {
const dialogOpts = {
type: 'info',
@ -134,7 +134,7 @@ Also make sure that errors are
[being handled](../api/auto-updater.md#event-error). Here's an example
for logging them to `stderr`:
```javascript title="main.js"
```js title="main.js"
autoUpdater.on('error', (message) => {
console.error('There was a problem updating the application')
console.error(message)

View file

@ -14,7 +14,7 @@ that are not a part of the web page.
To create a frameless window, you need to set `frame` to `false` in the `BrowserWindow`
constructor.
```javascript title='main.js'
```js title='main.js'
const { BrowserWindow } = require('electron')
const win = new BrowserWindow({ frame: false })
```
@ -28,7 +28,7 @@ option in the `BrowserWindow` constructor.
Applying the `hidden` title bar style results in a hidden title bar and a full-size
content window.
```javascript title='main.js'
```js title='main.js'
const { BrowserWindow } = require('electron')
const win = new BrowserWindow({ titleBarStyle: 'hidden' })
```
@ -44,7 +44,7 @@ The `customButtonsOnHover` title bar style will hide the traffic lights until yo
over them. This is useful if you want to create custom traffic lights in your HTML but still
use the native UI to control the window.
```javascript
```js
const { BrowserWindow } = require('electron')
const win = new BrowserWindow({ titleBarStyle: 'customButtonsOnHover' })
```
@ -57,7 +57,7 @@ options available.
Applying `hiddenInset` title bar style will shift the vertical inset of the traffic lights
by a fixed amount.
```javascript title='main.js'
```js title='main.js'
const { BrowserWindow } = require('electron')
const win = new BrowserWindow({ titleBarStyle: 'hiddenInset' })
```
@ -66,7 +66,7 @@ If you need more granular control over the positioning of the traffic lights, yo
a set of coordinates to the `trafficLightPosition` option in the `BrowserWindow`
constructor.
```javascript title='main.js'
```js title='main.js'
const { BrowserWindow } = require('electron')
const win = new BrowserWindow({
titleBarStyle: 'hidden',
@ -80,7 +80,7 @@ You can also show and hide the traffic lights programmatically from the main pro
The `win.setWindowButtonVisibility` forces traffic lights to be show or hidden depending
on the value of its boolean parameter.
```javascript title='main.js'
```js title='main.js'
const { BrowserWindow } = require('electron')
const win = new BrowserWindow()
// hides the traffic lights
@ -106,7 +106,7 @@ The `titleBarOverlay` option accepts two different value formats.
Specifying `true` on either platform will result in an overlay region with default
system colors:
```javascript title='main.js'
```js title='main.js'
// on macOS or Windows
const { BrowserWindow } = require('electron')
const win = new BrowserWindow({
@ -119,7 +119,7 @@ On either platform `titleBarOverlay` can also be an object. On both macOS and Wi
If a color option is not specified, the color will default to its system color for the window control buttons. Similarly, if the height option is not specified it will default to the default height:
```javascript title='main.js'
```js title='main.js'
// on Windows
const { BrowserWindow } = require('electron')
const win = new BrowserWindow({
@ -140,7 +140,7 @@ const win = new BrowserWindow({
By setting the `transparent` option to `true`, you can make a fully transparent window.
```javascript title='main.js'
```js title='main.js'
const { BrowserWindow } = require('electron')
const win = new BrowserWindow({ transparent: true })
```
@ -169,7 +169,7 @@ To create a click-through window, i.e. making the window ignore all mouse
events, you can call the [win.setIgnoreMouseEvents(ignore)][ignore-mouse-events]
API:
```javascript title='main.js'
```js title='main.js'
const { BrowserWindow } = require('electron')
const win = new BrowserWindow()
win.setIgnoreMouseEvents(true)
@ -182,7 +182,7 @@ meaning that mouse movement events will not be emitted. On Windows and macOS, an
optional parameter can be used to forward mouse move messages to the web page,
allowing events such as `mouseleave` to be emitted:
```javascript title='main.js'
```js title='main.js'
const { BrowserWindow, ipcMain } = require('electron')
const path = require('node:path')
@ -198,7 +198,7 @@ ipcMain.on('set-ignore-mouse-events', (event, ignore, options) => {
})
```
```javascript title='preload.js'
```js title='preload.js'
window.addEventListener('DOMContentLoaded', () => {
const el = document.getElementById('clickThroughElement')
el.addEventListener('mouseenter', () => {

View file

@ -60,7 +60,7 @@ Starting with a working application from the
[Quick Start Guide](quick-start.md), update the `main.js` file with the
following lines:
```javascript
```js
const { app } = require('electron')
app.setUserTasks([
@ -80,7 +80,7 @@ app.setUserTasks([
To clear your tasks list, you need to call `app.setUserTasks` with an empty
array in the `main.js` file.
```javascript
```js
const { app } = require('electron')
app.setUserTasks([])
@ -124,7 +124,7 @@ Starting with a working application from the
[Quick Start Guide](quick-start.md), update the `main.js` file with the
following lines:
```javascript
```js
const { BrowserWindow, nativeImage } = require('electron')
const path = require('node:path')
@ -149,7 +149,7 @@ win.setThumbarButtons([
To clear thumbnail toolbar buttons, you need to call
`BrowserWindow.setThumbarButtons` with an empty array in the `main.js` file.
```javascript
```js
const { BrowserWindow } = require('electron')
const win = new BrowserWindow()
@ -188,7 +188,7 @@ Starting with a working application from the
[Quick Start Guide](quick-start.md), update the `main.js` file with the
following lines:
```javascript
```js
const { BrowserWindow, nativeImage } = require('electron')
const win = new BrowserWindow()
@ -217,7 +217,7 @@ Starting with a working application from the
[Quick Start Guide](quick-start.md), update the `main.js` file with the
following lines:
```javascript
```js
const { BrowserWindow } = require('electron')
const win = new BrowserWindow()