diff --git a/docs/.oxfmtrc.json b/docs/.oxfmtrc.json new file mode 100644 index 0000000000..ce11d2f631 --- /dev/null +++ b/docs/.oxfmtrc.json @@ -0,0 +1,8 @@ +{ + "$schema": "../node_modules/oxfmt/configuration_schema.json", + "semi": false, + "singleQuote": true, + "printWidth": 120, + "trailingComma": "none", + "ignorePatterns": ["fiddles"] +} diff --git a/docs/api/app.md b/docs/api/app.md index 98d57f09f3..31e39e70f2 100644 --- a/docs/api/app.md +++ b/docs/api/app.md @@ -1021,7 +1021,8 @@ app.setJumpList([ { type: 'file', path: 'C:\\Projects\\project2.proj' } ] }, - { // has a name so `type` is assumed to be "custom" + { + // has a name so `type` is assumed to be "custom" name: 'Tools', items: [ { @@ -1045,7 +1046,8 @@ app.setJumpList([ ] }, { type: 'frequent' }, - { // has no name and no type so `type` is assumed to be "tasks" + { + // has no name and no type so `type` is assumed to be "tasks" items: [ { type: 'task', @@ -1268,9 +1270,7 @@ const { app } = require('electron') app.whenReady().then(() => { app.configureHostResolver({ secureDnsMode: 'secure', - secureDnsServers: [ - 'https://cloudflare-dns.com/dns-query' - ] + secureDnsServers: ['https://cloudflare-dns.com/dns-query'] }) }) ``` @@ -1481,26 +1481,26 @@ For `infoType` equal to `basic`: ```json5 { - auxAttributes: - { - amdSwitchable: true, - canSupportThreadedTextureMailbox: false, - directComposition: false, - directRendering: true, - glResetNotificationStrategy: 0, - inProcessGpu: true, - initializationTime: 0, - jpegDecodeAcceleratorSupported: false, - optimus: false, - passthroughCmdDecoder: false, - sandboxed: false, - softwareRendering: false, - supportsOverlays: false, - videoDecodeAcceleratorFlags: 0 - }, - gpuDevice: - [{ active: true, deviceId: 26657, vendorId: 4098 }, - { active: false, deviceId: 3366, vendorId: 32902 }], + auxAttributes: { + amdSwitchable: true, + canSupportThreadedTextureMailbox: false, + directComposition: false, + directRendering: true, + glResetNotificationStrategy: 0, + inProcessGpu: true, + initializationTime: 0, + jpegDecodeAcceleratorSupported: false, + optimus: false, + passthroughCmdDecoder: false, + sandboxed: false, + softwareRendering: false, + supportsOverlays: false, + videoDecodeAcceleratorFlags: 0 + }, + gpuDevice: [ + { active: true, deviceId: 26657, vendorId: 4098 }, + { active: false, deviceId: 3366, vendorId: 32902 } + ], machineModelName: 'MacBookPro', machineModelVersion: '11.5' } @@ -1703,11 +1703,7 @@ const { app } = require('electron') app.whenReady().then(() => { // Enable a subset of features: - app.setAccessibilitySupportFeatures([ - 'screenReader', - 'pdfPrinting', - 'webContents' - ]) + app.setAccessibilitySupportFeatures(['screenReader', 'pdfPrinting', 'webContents']) // Other logic @@ -1813,12 +1809,14 @@ const { app, dialog } = require('electron') app.moveToApplicationsFolder({ conflictHandler: (conflictType) => { if (conflictType === 'exists') { - return dialog.showMessageBoxSync({ - type: 'question', - buttons: ['Halt Move', 'Continue Move'], - defaultId: 0, - message: 'An app of this name already exists' - }) === 1 + return ( + dialog.showMessageBoxSync({ + type: 'question', + buttons: ['Halt Move', 'Continue Move'], + defaultId: 0, + message: 'An app of this name already exists' + }) === 1 + ) } } }) @@ -1880,7 +1878,7 @@ The handler is called when a password is needed to unlock a client certificate f ```js const { app } = require('electron') -async function passwordPromptUI (text) { +async function passwordPromptUI(text) { return new Promise((resolve, reject) => { // display UI to prompt user for password // ... diff --git a/docs/api/browser-window.md b/docs/api/browser-window.md index 43a8580a58..4068aa79ea 100644 --- a/docs/api/browser-window.md +++ b/docs/api/browser-window.md @@ -1317,10 +1317,12 @@ const { BrowserWindow } = require('electron') const win = new BrowserWindow() win.loadURL('http://localhost:8000/post', { - postData: [{ - type: 'rawData', - bytes: Buffer.from('hello=world') - }], + postData: [ + { + type: 'rawData', + bytes: Buffer.from('hello=world') + } + ], extraHeaders: 'Content-Type: application/x-www-form-urlencoded' }) ``` diff --git a/docs/api/clipboard-item.md b/docs/api/clipboard-item.md index b49792f515..55b1f7717e 100644 --- a/docs/api/clipboard-item.md +++ b/docs/api/clipboard-item.md @@ -103,15 +103,12 @@ const { pathToFileURL } = require('node:url') // manager. clipboard.write([ new ClipboardItem({ - 'text/uri-list': [ - pathToFileURL('/path/to/first.txt').href, - pathToFileURL('/path/to/second.txt').href - ].join('\r\n') + 'text/uri-list': [pathToFileURL('/path/to/first.txt').href, pathToFileURL('/path/to/second.txt').href].join('\r\n') }) ]) // Read the files currently on the clipboard. -async function readFiles () { +async function readFiles() { const [item] = await clipboard.read() if (item.types.includes('text/uri-list')) { const blob = await item.getType('text/uri-list') @@ -152,7 +149,7 @@ Rejects when `type` is not present in ```js const { clipboard } = require('electron') -async function dumpClipboard () { +async function dumpClipboard() { const items = await clipboard.read() for (const item of items) { for (const type of item.types) { @@ -174,7 +171,7 @@ Rejects when a bookmark is not available in the clipboard. ```js const { clipboard } = require('electron') -async function dumpClipboard () { +async function dumpClipboard() { const bookmarkType = 'electron application/bookmark' const items = await clipboard.read() for (const item of items) { diff --git a/docs/api/clipboard.md b/docs/api/clipboard.md index df8909c034..456dd02dd5 100644 --- a/docs/api/clipboard.md +++ b/docs/api/clipboard.md @@ -52,7 +52,7 @@ that follow the W3C [web custom format proposal](https://github.com/w3c/editing/ ```js const { clipboard, ClipboardItem } = require('electron') -async function writeClipboard () { +async function writeClipboard() { await clipboard.write([ new ClipboardItem({ 'web application/x.my-app-clip': new Blob(['arbitrary payload']) @@ -81,7 +81,7 @@ clipboard. The two clipboards are independent: writing via ```js const { clipboard } = require('electron') -async function run () { +async function run() { await clipboard.selection.writeText('Example string') console.log(await clipboard.selection.readText()) } @@ -103,7 +103,7 @@ API. ```js const { clipboard } = require('electron') -async function readText () { +async function readText() { await clipboard.writeText('hello i am a bit of text!') const text = await clipboard.readText() console.log(text) @@ -125,7 +125,7 @@ API. ```js const { clipboard } = require('electron') -async function writeClipboardText () { +async function writeClipboardText() { await clipboard.writeText('hello i am a bit of text!') } @@ -141,7 +141,7 @@ contents. ```js const { clipboard } = require('electron') -async function dumpClipboard () { +async function dumpClipboard() { const items = await clipboard.read() for (const item of items) { for (const type of item.types) { @@ -169,7 +169,7 @@ const { clipboard, ClipboardItem, nativeImage } = require('electron') const png = nativeImage.createFromPath('/path/to/icon.png').toPNG() -async function writeClipboard () { +async function writeClipboard() { await clipboard.write([ new ClipboardItem({ 'text/plain': 'hello', @@ -198,7 +198,7 @@ custom format (`electron application/osclipboard;format="public/utf8-plain-text" ```js const { clipboard } = require('electron') -async function check () { +async function check() { const hasFormat = await clipboard.has('text/html') console.log(hasFormat) // 'true' or 'false' diff --git a/docs/api/content-tracing.md b/docs/api/content-tracing.md index 67cea6c724..fad5c1227e 100644 --- a/docs/api/content-tracing.md +++ b/docs/api/content-tracing.md @@ -14,16 +14,14 @@ This module does not include a web interface. To view recorded traces, use ```js const { app, contentTracing } = require('electron') -app.whenReady().then(() => { - (async () => { - await contentTracing.startRecording({ - included_categories: ['*'] - }) - console.log('Tracing started') - await new Promise(resolve => setTimeout(resolve, 5000)) - const path = await contentTracing.stopRecording() - console.log('Tracing data recorded to ' + path) - })() +app.whenReady().then(async () => { + await contentTracing.startRecording({ + included_categories: ['*'] + }) + console.log('Tracing started') + await new Promise((resolve) => setTimeout(resolve, 5000)) + const path = await contentTracing.stopRecording() + console.log('Tracing data recorded to ' + path) }) ``` diff --git a/docs/api/context-bridge.md b/docs/api/context-bridge.md index 6eb7dd2a2b..d5bddc8526 100644 --- a/docs/api/context-bridge.md +++ b/docs/api/context-bridge.md @@ -19,12 +19,9 @@ An example of exposing an API to a renderer from an isolated preload script is g // Preload (Isolated World) const { contextBridge, ipcRenderer } = require('electron') -contextBridge.exposeInMainWorld( - 'electron', - { - doThing: () => ipcRenderer.send('do-a-thing') - } -) +contextBridge.exposeInMainWorld('electron', { + doThing: () => ipcRenderer.send('do-a-thing') +}) ``` ```js @ts-nocheck @@ -90,27 +87,24 @@ An example of a complex API is shown below: ```js const { contextBridge, ipcRenderer } = require('electron') -contextBridge.exposeInMainWorld( - 'electron', - { - doThing: () => ipcRenderer.send('do-a-thing'), - myPromises: [Promise.resolve(), Promise.reject(new Error('whoops'))], - anAsyncFunction: async () => 123, - data: { - myFlags: ['a', 'b', 'c'], - bootTime: 1234 - }, - nestedAPI: { - evenDeeper: { - youCanDoThisAsMuchAsYouWant: { - fn: () => ({ - returnData: 123 - }) - } +contextBridge.exposeInMainWorld('electron', { + doThing: () => ipcRenderer.send('do-a-thing'), + myPromises: [Promise.resolve(), Promise.reject(new Error('whoops'))], + anAsyncFunction: async () => 123, + data: { + myFlags: ['a', 'b', 'c'], + bootTime: 1234 + }, + nestedAPI: { + evenDeeper: { + youCanDoThisAsMuchAsYouWant: { + fn: () => ({ + returnData: 123 + }) } } } -) +}) ``` An example of `exposeInIsolatedWorld` is shown below: @@ -118,13 +112,9 @@ An example of `exposeInIsolatedWorld` is shown below: ```js const { contextBridge, ipcRenderer } = require('electron') -contextBridge.exposeInIsolatedWorld( - 1004, - 'electron', - { - doThing: () => ipcRenderer.send('do-a-thing') - } -) +contextBridge.exposeInIsolatedWorld(1004, 'electron', { + doThing: () => ipcRenderer.send('do-a-thing') +}) ``` ```js @ts-nocheck @@ -178,7 +168,9 @@ contextBridge.exposeInMainWorld('electron', { ```js @ts-nocheck // Renderer (Main World) -window.electron.onMyEventName(data => { /* ... */ }) +window.electron.onMyEventName((data) => { + /* ... */ +}) ``` ### Exposing Node Global Symbols @@ -194,7 +186,7 @@ const { contextBridge } = require('electron') const crypto = require('node:crypto') contextBridge.exposeInMainWorld('nodeCrypto', { - sha256sum (data) { + sha256sum(data) { const hash = crypto.createHash('sha256') hash.update(data) return hash.digest('hex') diff --git a/docs/api/cookies.md b/docs/api/cookies.md index b85d6635d1..a445de638f 100644 --- a/docs/api/cookies.md +++ b/docs/api/cookies.md @@ -14,30 +14,36 @@ For example: const { session } = require('electron') // Query all cookies. -session.defaultSession.cookies.get({}) +session.defaultSession.cookies + .get({}) .then((cookies) => { console.log(cookies) - }).catch((error) => { + }) + .catch((error) => { console.log(error) }) // Query all cookies associated with a specific url. -session.defaultSession.cookies.get({ url: 'https://www.github.com' }) +session.defaultSession.cookies + .get({ url: 'https://www.github.com' }) .then((cookies) => { console.log(cookies) - }).catch((error) => { + }) + .catch((error) => { console.log(error) }) // Set a cookie with the given cookie data; // may overwrite equivalent cookies if they exist. const cookie = { url: 'https://www.github.com', name: 'dummy_name', value: 'dummy' } -session.defaultSession.cookies.set(cookie) - .then(() => { +session.defaultSession.cookies.set(cookie).then( + () => { // success - }, (error) => { + }, + (error) => { console.error(error) - }) + } +) ``` ### Instance Events diff --git a/docs/api/desktop-capturer.md b/docs/api/desktop-capturer.md index 2f952331cd..54dbeb1674 100644 --- a/docs/api/desktop-capturer.md +++ b/docs/api/desktop-capturer.md @@ -15,16 +15,19 @@ const { app, BrowserWindow, desktopCapturer, session } = require('electron') app.whenReady().then(() => { const mainWindow = new BrowserWindow() - session.defaultSession.setDisplayMediaRequestHandler((request, callback) => { - desktopCapturer.getSources({ types: ['screen'] }).then((sources) => { - // Grant access to the first screen found. - callback({ video: sources[0], audio: 'loopback' }) - }) - // If true, use the system picker if available. - // Note: this is currently experimental. If the system picker - // is available, it will be used and the media request handler - // will not be invoked. - }, { useSystemPicker: true }) + session.defaultSession.setDisplayMediaRequestHandler( + (request, callback) => { + desktopCapturer.getSources({ types: ['screen'] }).then((sources) => { + // Grant access to the first screen found. + callback({ video: sources[0], audio: 'loopback' }) + }) + // If true, use the system picker if available. + // Note: this is currently experimental. If the system picker + // is available, it will be used and the media request handler + // will not be invoked. + }, + { useSystemPicker: true } + ) mainWindow.loadFile('index.html') }) @@ -37,17 +40,20 @@ const stopButton = document.getElementById('stopButton') const video = document.querySelector('video') startButton.addEventListener('click', () => { - navigator.mediaDevices.getDisplayMedia({ - audio: true, - video: { - width: 320, - height: 240, - frameRate: 30 - } - }).then(stream => { - video.srcObject = stream - video.onloadedmetadata = (e) => video.play() - }).catch(e => console.log(e)) + navigator.mediaDevices + .getDisplayMedia({ + audio: true, + video: { + width: 320, + height: 240, + frameRate: 30 + } + }) + .then((stream) => { + video.srcObject = stream + video.onloadedmetadata = (e) => video.play() + }) + .catch((e) => console.log(e)) }) stopButton.addEventListener('click', () => { diff --git a/docs/api/dialog.md b/docs/api/dialog.md index 28cd6cae49..7a67346411 100644 --- a/docs/api/dialog.md +++ b/docs/api/dialog.md @@ -171,14 +171,17 @@ The `extensions` array should contain extensions without wildcards or dots (e.g. > shown. ```js @ts-type={mainWindow:Electron.BaseWindow} -dialog.showOpenDialog(mainWindow, { - properties: ['openFile', 'openDirectory'] -}).then(result => { - console.log(result.canceled) - console.log(result.filePaths) -}).catch(err => { - console.log(err) -}) +dialog + .showOpenDialog(mainWindow, { + properties: ['openFile', 'openDirectory'] + }) + .then((result) => { + console.log(result.canceled) + console.log(result.filePaths) + }) + .catch((err) => { + console.log(err) + }) ``` > [!NOTE] diff --git a/docs/api/net.md b/docs/api/net.md index d4827f849d..5bfc736668 100644 --- a/docs/api/net.md +++ b/docs/api/net.md @@ -78,7 +78,7 @@ Node.js's HTTP stack. Example: ```js -async function example () { +async function example() { const response = await net.fetch('https://my.app') if (response.ok) { const body = await response.json() diff --git a/docs/api/protocol.md b/docs/api/protocol.md index e1a5ae48e9..9c0d78593d 100644 --- a/docs/api/protocol.md +++ b/docs/api/protocol.md @@ -88,9 +88,7 @@ Policy: ```js const { protocol } = require('electron') -protocol.registerSchemesAsPrivileged([ - { scheme: 'foo', privileges: { bypassCSP: true } } -]) +protocol.registerSchemesAsPrivileged([{ scheme: 'foo', privileges: { bypassCSP: true } }]) ``` A standard scheme adheres to what RFC 3986 calls [generic URI syntax](https://tools.ietf.org/html/rfc3986#section-3). @@ -352,7 +350,7 @@ const { protocol } = require('electron') const { PassThrough } = require('node:stream') -function createStream (text) { +function createStream(text) { const rv = new PassThrough() // PassThrough is also a Readable stream rv.push(text) rv.push(null) diff --git a/docs/api/session.md b/docs/api/session.md index 9a98e0a584..d352c806d0 100644 --- a/docs/api/session.md +++ b/docs/api/session.md @@ -185,7 +185,7 @@ Returns: ```js const { app, dialog, BrowserWindow, session } = require('electron') -async function createWindow () { +async function createWindow() { const mainWindow = new BrowserWindow() await mainWindow.loadURL('https://buzzfeed.com') @@ -208,14 +208,16 @@ async function createWindow () { } }) - mainWindow.webContents.executeJavaScript(` + mainWindow.webContents.executeJavaScript( + ` window.showDirectoryPicker({ id: 'electron-demo', mode: 'readwrite', startIn: 'downloads', }).catch(e => { console.log(e) - })`, true + })`, + true ) } @@ -341,9 +343,12 @@ app.whenReady().then(() => { // Search through the list of devices that have previously been granted permission return grantedDevices.some((grantedDevice) => { - return grantedDevice.vendorId === details.device.vendorId && - grantedDevice.productId === details.device.productId && - grantedDevice.serialNumber && grantedDevice.serialNumber === details.device.serialNumber + return ( + grantedDevice.vendorId === details.device.vendorId && + grantedDevice.productId === details.device.productId && + grantedDevice.serialNumber && + grantedDevice.serialNumber === details.device.serialNumber + ) }) } return false @@ -452,9 +457,12 @@ app.whenReady().then(() => { // Search through the list of devices that have previously been granted permission return grantedDevices.some((grantedDevice) => { - return grantedDevice.vendorId === details.device.vendorId && - grantedDevice.productId === details.device.productId && - grantedDevice.serialNumber && grantedDevice.serialNumber === details.device.serialNumber + return ( + grantedDevice.vendorId === details.device.vendorId && + grantedDevice.productId === details.device.productId && + grantedDevice.serialNumber && + grantedDevice.serialNumber === details.device.serialNumber + ) }) } return false @@ -594,9 +602,12 @@ app.whenReady().then(() => { // Search through the list of devices that have previously been granted permission return grantedDevices.some((grantedDevice) => { - return grantedDevice.vendorId === details.device.vendorId && - grantedDevice.productId === details.device.productId && - grantedDevice.serialNumber && grantedDevice.serialNumber === details.device.serialNumber + return ( + grantedDevice.vendorId === details.device.vendorId && + grantedDevice.productId === details.device.productId && + grantedDevice.serialNumber && + grantedDevice.serialNumber === details.device.serialNumber + ) }) } return false @@ -921,7 +932,7 @@ Node.js's HTTP stack. Example: ```js -async function example () { +async function example() { const response = await net.fetch('https://my.app') if (response.ok) { const body = await response.json() @@ -1236,16 +1247,19 @@ is set to `true`, the handler will not be invoked. ```js const { session, desktopCapturer } = require('electron') -session.defaultSession.setDisplayMediaRequestHandler((request, callback) => { - desktopCapturer.getSources({ types: ['screen'] }).then((sources) => { - // Grant access to the first screen found. - callback({ video: sources[0] }) - }) - // Use the system picker if available. - // Note: this is currently experimental. If the system picker - // is available, it will be used and the media request handler - // will not be invoked. -}, { useSystemPicker: true }) +session.defaultSession.setDisplayMediaRequestHandler( + (request, callback) => { + desktopCapturer.getSources({ types: ['screen'] }).then((sources) => { + // Grant access to the first screen found. + callback({ video: sources[0] }) + }) + // Use the system picker if available. + // Note: this is currently experimental. If the system picker + // is available, it will be used and the media request handler + // will not be invoked. + }, + { useSystemPicker: true } +) ``` Passing a [WebFrameMain](web-frame-main.md) object as a video or audio stream @@ -1320,9 +1334,12 @@ app.whenReady().then(() => { // Search through the list of devices that have previously been granted permission return grantedDevices.some((grantedDevice) => { - return grantedDevice.vendorId === details.device.vendorId && - grantedDevice.productId === details.device.productId && - grantedDevice.serialNumber && grantedDevice.serialNumber === details.device.serialNumber + return ( + grantedDevice.vendorId === details.device.vendorId && + grantedDevice.productId === details.device.productId && + grantedDevice.serialNumber && + grantedDevice.serialNumber === details.device.serialNumber + ) }) } else if (details.deviceType === 'serial') { if (details.device.vendorId === 123 && details.device.productId === 345) { @@ -1431,7 +1448,7 @@ const { app, BrowserWindow, session } = require('electron') const path = require('node:path') -function createWindow () { +function createWindow() { let bluetoothPinCallback = null const mainWindow = new BrowserWindow({ @@ -1911,10 +1928,12 @@ const path = require('node:path') app.whenReady().then(() => { const protocol = session.fromPartition('some-partition').protocol - if (!protocol.registerFileProtocol('atom', (request, callback) => { - const url = request.url.substr(7) - callback({ path: path.normalize(path.join(__dirname, url)) }) - })) { + if ( + !protocol.registerFileProtocol('atom', (request, callback) => { + const url = request.url.substr(7) + callback({ path: path.normalize(path.join(__dirname, url)) }) + }) + ) { console.error('Failed to register protocol') } }) diff --git a/docs/api/structures/notification-action.md b/docs/api/structures/notification-action.md index 24229682da..65060c4952 100644 --- a/docs/api/structures/notification-action.md +++ b/docs/api/structures/notification-action.md @@ -32,11 +32,13 @@ app.whenReady().then(() => { const items = ['One', 'Two', 'Three'] const n = new Notification({ title: 'Choose an option', - actions: [{ - type: 'selection', - text: 'Apply', - items - }] + actions: [ + { + type: 'selection', + text: 'Apply', + items + } + ] }) n.on('action', (e) => { diff --git a/docs/api/system-preferences.md b/docs/api/system-preferences.md index ce5f4bf8b5..605c7f4c94 100644 --- a/docs/api/system-preferences.md +++ b/docs/api/system-preferences.md @@ -320,11 +320,14 @@ Returns `Promise` - resolves if the user has successfully authenticated wi ```js const { systemPreferences } = require('electron') -systemPreferences.promptTouchID('To get consent for a Security-Gated Thing').then(success => { - console.log('You have successfully authenticated with Touch ID!') -}).catch(err => { - console.log(err) -}) +systemPreferences + .promptTouchID('To get consent for a Security-Gated Thing') + .then((success) => { + console.log('You have successfully authenticated with Touch ID!') + }) + .catch((err) => { + console.log(err) + }) ``` This API itself will not protect your user data; rather, it is a mechanism to allow you to do so. Native apps will need to set [Access Control Constants](https://developer.apple.com/documentation/security/secaccesscontrolcreateflags?language=objc) like [`kSecAccessControlUserPresence`](https://developer.apple.com/documentation/security/secaccesscontrolcreateflags/ksecaccesscontroluserpresence?language=objc) on their keychain entry so that reading it would auto-prompt for Touch ID biometric consent. This could be done with [`node-keytar`](https://github.com/atom/node-keytar), such that one would store an encryption key with `node-keytar` and only fetch it if `promptTouchID()` resolves. diff --git a/docs/api/touch-bar.md b/docs/api/touch-bar.md index 6ff301dbe5..2a94207a62 100644 --- a/docs/api/touch-bar.md +++ b/docs/api/touch-bar.md @@ -115,7 +115,7 @@ const spin = new TouchBarButton({ const spinReels = () => { updateReels() - if ((Date.now() - startTime) >= spinLength) { + if (Date.now() - startTime >= spinLength) { finishSpin() } else { // Slow down a bit on each spin diff --git a/docs/api/web-contents.md b/docs/api/web-contents.md index acd840bcca..c5cf9cd4dd 100644 --- a/docs/api/web-contents.md +++ b/docs/api/web-contents.md @@ -94,7 +94,7 @@ When communicating with the [Chrome DevTools Protocol](https://chromedevtools.gi it can be useful to lookup a WebContents instance based on its assigned TargetID. ```js -async function lookupTargetId (browserWindow) { +async function lookupTargetId(browserWindow) { const wc = browserWindow.webContents await wc.debugger.attach('1.3') const { targetInfo } = await wc.debugger.sendCommand('Target.getTargetInfo') @@ -472,7 +472,7 @@ win.webContents.on('will-prevent-unload', (event) => { defaultId: 0, cancelId: 1 }) - const leave = (choice === 0) + const leave = choice === 0 if (leave) { event.preventDefault() } @@ -972,7 +972,7 @@ win.webContents.on('paint', async (e, dirty, image) => { if (e.texture) { // By managing lifecycle yourself, you can handle the event in async handler or pass the `e.texture.textureInfo` // to other processes (not `e.texture`, the `e.texture.release` function is not passable through IPC). - await new Promise(resolve => setTimeout(resolve, 50)) + await new Promise((resolve) => setTimeout(resolve, 50)) // You can send the native texture handle to native code for importing into your rendering pipeline. // Read more at https://github.com/electron/electron/blob/main/shell/browser/osr/README.md @@ -1448,7 +1448,8 @@ Code execution will be suspended until web page stop loading. ```js const win = new BrowserWindow() -win.webContents.executeJavaScript('fetch("https://jsonplaceholder.typicode.com/users/1").then(resp => resp.json())', true) +win.webContents + .executeJavaScript('fetch("https://jsonplaceholder.typicode.com/users/1").then(resp => resp.json())', true) .then((result) => { console.log(result) // Will be the JSON object from the fetch call }) @@ -1902,10 +1903,12 @@ const win = new BrowserWindow() const options = { silent: true, deviceName: 'My-Printer', - pageRanges: [{ - from: 0, - to: 1 - }] + pageRanges: [ + { + from: 0, + to: 1 + } + ] } win.webContents.print(options, (success, errorType) => { if (!success) console.log(errorType) @@ -1938,14 +1941,17 @@ app.whenReady().then(() => { win.webContents.on('did-finish-load', () => { // Use default printing options const pdfPath = path.join(os.homedir(), 'Desktop', 'temp.pdf') - win.webContents.printToPDF({}).then(data => { - fs.writeFile(pdfPath, data, (error) => { - if (error) throw error - console.log(`Wrote PDF successfully to ${pdfPath}`) + win.webContents + .printToPDF({}) + .then((data) => { + fs.writeFile(pdfPath, data, (error) => { + if (error) throw error + console.log(`Wrote PDF successfully to ${pdfPath}`) + }) + }) + .catch((error) => { + console.log(`Failed to write PDF to ${pdfPath}: `, error) }) - }).catch(error => { - console.log(`Failed to write PDF to ${pdfPath}: `, error) - }) }) }) ``` @@ -2258,11 +2264,14 @@ const win = new BrowserWindow() win.loadURL('https://github.com') win.webContents.on('did-finish-load', async () => { - win.webContents.savePage('/tmp/test.html', 'HTMLComplete').then(() => { - console.log('Page was saved successfully.') - }).catch(err => { - console.log(err) - }) + win.webContents + .savePage('/tmp/test.html', 'HTMLComplete') + .then(() => { + console.log('Page was saved successfully.') + }) + .catch((err) => { + console.log(err) + }) }) ``` diff --git a/docs/api/web-frame-main.md b/docs/api/web-frame-main.md index 37bd697dc0..9ee582c893 100644 --- a/docs/api/web-frame-main.md +++ b/docs/api/web-frame-main.md @@ -32,7 +32,7 @@ of [`WebContents`](web-contents.md). ```js const { BrowserWindow } = require('electron') -async function main () { +async function main() { const win = new BrowserWindow({ width: 800, height: 600 }) await win.loadURL('https://reddit.com') @@ -226,14 +226,17 @@ app.whenReady().then(() => { win.webContents.on('did-finish-load', () => { const pdfPath = path.join(os.homedir(), 'Desktop', 'iframe.pdf') const iframe = win.webContents.mainFrame.frames[0] - iframe.printToPDF({}).then(data => { - fs.writeFile(pdfPath, data, (error) => { - if (error) throw error - console.log(`Wrote PDF successfully to ${pdfPath}`) + iframe + .printToPDF({}) + .then((data) => { + fs.writeFile(pdfPath, data, (error) => { + if (error) throw error + console.log(`Wrote PDF successfully to ${pdfPath}`) + }) + }) + .catch((error) => { + console.log(`Failed to write PDF to ${pdfPath}: `, error) }) - }).catch(error => { - console.log(`Failed to write PDF to ${pdfPath}: `, error) - }) }) }) ``` diff --git a/docs/api/web-frame.md b/docs/api/web-frame.md index a5cc3b3e6c..710d4153b4 100644 --- a/docs/api/web-frame.md +++ b/docs/api/web-frame.md @@ -111,9 +111,9 @@ const { webFrame } = require('electron') const spellChecker = require('spellchecker') webFrame.setSpellCheckProvider('en-US', { - spellCheck (words, callback) { + spellCheck(words, callback) { setTimeout(() => { - const misspelled = words.filter(x => spellchecker.isMisspelled(x)) + const misspelled = words.filter((x) => spellchecker.isMisspelled(x)) callback(misspelled) }, 0) } @@ -249,10 +249,18 @@ This will generate: size: 2549, liveSize: 2542 }, - cssStyleSheets: { /* same with "images" */ }, - xslStyleSheets: { /* same with "images" */ }, - fonts: { /* same with "images" */ }, - other: { /* same with "images" */ } + cssStyleSheets: { + /* same with "images" */ + }, + xslStyleSheets: { + /* same with "images" */ + }, + fonts: { + /* same with "images" */ + }, + other: { + /* same with "images" */ + } } ``` diff --git a/docs/api/web-utils.md b/docs/api/web-utils.md index f1d04fcc98..39d85f6e65 100644 --- a/docs/api/web-utils.md +++ b/docs/api/web-utils.md @@ -40,7 +40,7 @@ electronApi.doSomethingWithFile(file) const { contextBridge, webUtils } = require('electron') contextBridge.exposeInMainWorld('electronApi', { - doSomethingWithFile (file) { + doSomethingWithFile(file) { const path = webUtils.getPathForFile(file) // Do something with the path, e.g., send it over IPC to the main process. // It's best not to expose the full file path to the web content if possible. diff --git a/docs/breaking-changes.md b/docs/breaking-changes.md index 322a300f2d..ab2f9a7efd 100644 --- a/docs/breaking-changes.md +++ b/docs/breaking-changes.md @@ -412,7 +412,7 @@ now reached through a new `clipboard.selection` sub-namespace. ```js const { clipboard, ClipboardItem } = require('electron') -function getClipboardToUse (clipboardType) { +function getClipboardToUse(clipboardType) { if (clipboardType === 'selection') { return clipboard.selection } else { @@ -420,10 +420,10 @@ function getClipboardToUse (clipboardType) { } } -async function readClipboard (format, clipboardType) { +async function readClipboard(format, clipboardType) { const clipboardToUse = getClipboardToUse(clipboardType) const clipboardItems = await clipboardToUse.read() - const foundItem = clipboardItems.find(clipboardItem => { + const foundItem = clipboardItems.find((clipboardItem) => { return clipboardItem.types.includes(format) }) if (foundItem) { @@ -433,7 +433,7 @@ async function readClipboard (format, clipboardType) { } } -async function writeClipboard (format, text, clipboardType) { +async function writeClipboard(format, text, clipboardType) { const clipboardToUse = getClipboardToUse(clipboardType) return clipboardToUse.write([ new ClipboardItem({ @@ -442,10 +442,10 @@ async function writeClipboard (format, text, clipboardType) { ]) } -async function readBuffer (format, clipboardType) { +async function readBuffer(format, clipboardType) { const clipboardToUse = getClipboardToUse(clipboardType) const clipboardItems = await clipboardToUse.read() - const foundItem = clipboardItems.find(clipboardItem => { + const foundItem = clipboardItems.find((clipboardItem) => { return clipboardItem.types.includes(format) }) if (foundItem) { @@ -455,7 +455,7 @@ async function readBuffer (format, clipboardType) { } } -async function writeBuffer (format, buffer, clipboardType) { +async function writeBuffer(format, buffer, clipboardType) { const clipboardToUse = getClipboardToUse(clipboardType) return clipboardToUse.write([ new ClipboardItem({ @@ -464,7 +464,7 @@ async function writeBuffer (format, buffer, clipboardType) { ]) } -async function availableFormats (clipboardType) { +async function availableFormats(clipboardType) { const clipboardToUse = getClipboardToUse(clipboardType) const clipboardItems = await clipboardToUse.read() const clipboardFormats = [] @@ -478,7 +478,7 @@ async function availableFormats (clipboardType) { return clipboardFormats } -async function has (format, clipboardType, isRawFormat) { +async function has(format, clipboardType, isRawFormat) { const clipboardToUse = getClipboardToUse(clipboardType) let mimeType = format if (isRawFormat) { @@ -488,10 +488,10 @@ async function has (format, clipboardType, isRawFormat) { } const BOOKMARK_MIME_TYPE = 'electron application/bookmark' -async function readBookmark (clipboardType) { +async function readBookmark(clipboardType) { const clipboardToUse = getClipboardToUse(clipboardType) const clipboardItems = await clipboardToUse.read() - const foundItem = clipboardItems.find(clipboardItem => { + const foundItem = clipboardItems.find((clipboardItem) => { return clipboardItem.types.includes(BOOKMARK_MIME_TYPE) }) if (foundItem) { @@ -501,7 +501,7 @@ async function readBookmark (clipboardType) { } } -async function writeBookmark (title, url, clipboardType) { +async function writeBookmark(title, url, clipboardType) { const clipboardToUse = getClipboardToUse(clipboardType) return clipboardToUse.write([ new ClipboardItem({ @@ -511,41 +511,39 @@ async function writeBookmark (title, url, clipboardType) { } const FIND_TEXT_MIME_TYPE = 'electron application/findtext' -async function readFindText () { +async function readFindText() { return readClipboard(FIND_TEXT_MIME_TYPE) } -async function writeFindText (text) { +async function writeFindText(text) { return writeClipboard(FIND_TEXT_MIME_TYPE, text) } const HTML_MIME_TYPE = 'text/html' -async function readHTML (clipboardType) { +async function readHTML(clipboardType) { return readClipboard(HTML_MIME_TYPE, clipboardType) } -async function writeHTML (markup, clipboardType) { +async function writeHTML(markup, clipboardType) { return writeClipboard(HTML_MIME_TYPE, markup, clipboardType) } const PNG_MIME_TYPE = 'image/png' const JPEG_MIME_TYPE = 'image/jpeg' -async function readImage (clipboardType) { +async function readImage(clipboardType) { const clipboardToUse = getClipboardToUse(clipboardType) const clipboardItems = await clipboardToUse.read() // Look for PNG first - let foundItem = clipboardItems.find(clipboardItem => { + let foundItem = clipboardItems.find((clipboardItem) => { return clipboardItem.types.includes(PNG_MIME_TYPE) }) if (!foundItem) { - foundItem = clipboardItems.find(clipboardItem => { + foundItem = clipboardItems.find((clipboardItem) => { return clipboardItem.types.includes(JPEG_MIME_TYPE) }) } if (foundItem) { - const mimeType = foundItem.types.includes(PNG_MIME_TYPE) - ? PNG_MIME_TYPE - : JPEG_MIME_TYPE + const mimeType = foundItem.types.includes(PNG_MIME_TYPE) ? PNG_MIME_TYPE : JPEG_MIME_TYPE // getType() resolves to a Blob; convert it to a Buffer for nativeImage. const blob = await foundItem.getType(mimeType) const buffer = Buffer.from(await blob.arrayBuffer()) @@ -553,7 +551,7 @@ async function readImage (clipboardType) { } } -async function writeImage (image, clipboardType) { +async function writeImage(image, clipboardType) { const clipboardToUse = getClipboardToUse(clipboardType) return clipboardToUse.write([ new ClipboardItem({ @@ -563,11 +561,11 @@ async function writeImage (image, clipboardType) { } const RTF_MIME_TYPE = 'text/rtf' -async function readRTF (clipboardType) { +async function readRTF(clipboardType) { return readClipboard(RTF_MIME_TYPE, clipboardType) } -async function writeRTF (text, clipboardType) { +async function writeRTF(text, clipboardType) { return writeClipboard(RTF_MIME_TYPE, text, clipboardType) } ``` @@ -809,10 +807,7 @@ Electron 45 and no longer has any effect): ```js // main.js (right beneath your require/import statements) -app.commandLine.appendSwitch( - 'disable-features', - 'MacCatapLoopbackAudioForScreenShare' -) +app.commandLine.appendSwitch('disable-features', 'MacCatapLoopbackAudioForScreenShare') ``` ### Behavior Changed: shared texture OSR `paint` event data structure @@ -1131,7 +1126,9 @@ protocol.registerFileProtocol('other', () => { }) const mainWindow = new BrowserWindow() -mainWindow.loadURL('data:text/html,', { baseURLForDataURL: 'other://C:\\myapp' }) +mainWindow.loadURL('data:text/html,', { + baseURLForDataURL: 'other://C:\\myapp' +}) mainWindow.loadURL('other://C:\\myapp\\index.html') // Replace with @@ -1209,7 +1206,7 @@ electron.showFilePath(file) const { contextBridge, webUtils } = require('electron') contextBridge.exposeInMainWorld('electron', { - showFilePath (file) { + showFilePath(file) { // It's best not to expose the full file path to the web content if // possible. const path = webUtils.getPathForFile(file) @@ -1348,10 +1345,14 @@ Use the new `render-process-gone` event instead. ```js // Removed -app.on('renderer-process-crashed', (event, webContents, killed) => { /* ... */ }) +app.on('renderer-process-crashed', (event, webContents, killed) => { + /* ... */ +}) // Replace with -app.on('render-process-gone', (event, webContents, details) => { /* ... */ }) +app.on('render-process-gone', (event, webContents, details) => { + /* ... */ +}) ``` ### Removed: `crashed` event on `WebContents` and `` @@ -1361,12 +1362,20 @@ Use the new `render-process-gone` event instead. ```js // Removed -win.webContents.on('crashed', (event, killed) => { /* ... */ }) -webview.addEventListener('crashed', (event) => { /* ... */ }) +win.webContents.on('crashed', (event, killed) => { + /* ... */ +}) +webview.addEventListener('crashed', (event) => { + /* ... */ +}) // Replace with -win.webContents.on('render-process-gone', (event, details) => { /* ... */ }) -webview.addEventListener('render-process-gone', (event) => { /* ... */ }) +win.webContents.on('render-process-gone', (event, details) => { + /* ... */ +}) +webview.addEventListener('render-process-gone', (event) => { + /* ... */ +}) ``` ### Removed: `gpu-process-crashed` event on `app` @@ -1376,10 +1385,14 @@ Use the new `child-process-gone` event instead. ```js // Removed -app.on('gpu-process-crashed', (event, killed) => { /* ... */ }) +app.on('gpu-process-crashed', (event, killed) => { + /* ... */ +}) // Replace with -app.on('child-process-gone', (event, details) => { /* ... */ }) +app.on('child-process-gone', (event, details) => { + /* ... */ +}) ``` ## Breaking API Changes (28.0) @@ -1452,10 +1465,14 @@ Use the new `render-process-gone` event instead. ```js // Deprecated -app.on('renderer-process-crashed', (event, webContents, killed) => { /* ... */ }) +app.on('renderer-process-crashed', (event, webContents, killed) => { + /* ... */ +}) // Replace with -app.on('render-process-gone', (event, webContents, details) => { /* ... */ }) +app.on('render-process-gone', (event, webContents, details) => { + /* ... */ +}) ``` ### Deprecated: `params.inputFormType` property on `context-menu` on `WebContents` @@ -1471,12 +1488,20 @@ Use the new `render-process-gone` event instead. ```js // Deprecated -win.webContents.on('crashed', (event, killed) => { /* ... */ }) -webview.addEventListener('crashed', (event) => { /* ... */ }) +win.webContents.on('crashed', (event, killed) => { + /* ... */ +}) +webview.addEventListener('crashed', (event) => { + /* ... */ +}) // Replace with -win.webContents.on('render-process-gone', (event, details) => { /* ... */ }) -webview.addEventListener('render-process-gone', (event) => { /* ... */ }) +win.webContents.on('render-process-gone', (event, details) => { + /* ... */ +}) +webview.addEventListener('render-process-gone', (event) => { + /* ... */ +}) ``` ### Deprecated: `gpu-process-crashed` event on `app` @@ -1486,10 +1511,14 @@ Use the new `child-process-gone` event instead. ```js // Deprecated -app.on('gpu-process-crashed', (event, killed) => { /* ... */ }) +app.on('gpu-process-crashed', (event, killed) => { + /* ... */ +}) // Replace with -app.on('child-process-gone', (event, details) => { /* ... */ }) +app.on('child-process-gone', (event, details) => { + /* ... */ +}) ``` ## Breaking API Changes (27.0) @@ -1518,11 +1547,17 @@ Use the new `updated` event on the `nativeTheme` module instead. ```js // Removed -systemPreferences.on('inverted-color-scheme-changed', () => { /* ... */ }) -systemPreferences.on('high-contrast-color-scheme-changed', () => { /* ... */ }) +systemPreferences.on('inverted-color-scheme-changed', () => { + /* ... */ +}) +systemPreferences.on('high-contrast-color-scheme-changed', () => { + /* ... */ +}) // Replace with -nativeTheme.on('updated', () => { /* ... */ }) +nativeTheme.on('updated', () => { + /* ... */ +}) ``` ### Removed: Some `window.setVibrancy` options on macOS @@ -1743,13 +1778,13 @@ const imagePath = path.join('path', 'to', 'capybara.png') // Scaling up a smaller image. const upSize = { width: 256, height: 256 } -nativeImage.createThumbnailFromPath(imagePath, upSize).then(result => { +nativeImage.createThumbnailFromPath(imagePath, upSize).then((result) => { console.log(result.getSize()) // { width: 256, height: 256 } }) // Scaling down a larger image. const downSize = { width: 64, height: 64 } -nativeImage.createThumbnailFromPath(imagePath, downSize).then(result => { +nativeImage.createThumbnailFromPath(imagePath, downSize).then((result) => { console.log(result.getSize()) // { width: 64, height: 64 } }) ``` @@ -1760,7 +1795,7 @@ Previous Behavior (on Windows): // a 128x128 image const imagePath = path.join('path', 'to', 'capybara.png') const size = { width: 256, height: 256 } -nativeImage.createThumbnailFromPath(imagePath, size).then(result => { +nativeImage.createThumbnailFromPath(imagePath, size).then((result) => { console.log(result.getSize()) // { width: 128, height: 128 } }) ``` @@ -1815,13 +1850,13 @@ const w = new BrowserWindow({ show: false }) // Removed in Electron 23 w.webContents.incrementCapturerCount() -w.capturePage().then(image => { +w.capturePage().then((image) => { console.log(image.toDataURL()) w.webContents.decrementCapturerCount() }) // Replace with -w.capturePage().then(image => { +w.capturePage().then((image) => { console.log(image.toDataURL()) }) ``` @@ -1836,13 +1871,13 @@ const w = new BrowserWindow({ show: false }) // Removed in Electron 23 w.webContents.incrementCapturerCount() -w.capturePage().then(image => { +w.capturePage().then((image) => { console.log(image.toDataURL()) w.webContents.decrementCapturerCount() }) // Replace with -w.capturePage().then(image => { +w.capturePage().then((image) => { console.log(image.toDataURL()) }) ``` @@ -1859,13 +1894,13 @@ const w = new BrowserWindow({ show: false }) // Removed in Electron 23 w.webContents.incrementCapturerCount() -w.capturePage().then(image => { +w.capturePage().then((image) => { console.log(image.toDataURL()) w.webContents.decrementCapturerCount() }) // Replace with -w.capturePage().then(image => { +w.capturePage().then((image) => { console.log(image.toDataURL()) }) ``` @@ -1880,13 +1915,13 @@ const w = new BrowserWindow({ show: false }) // Removed in Electron 23 w.webContents.incrementCapturerCount() -w.capturePage().then(image => { +w.capturePage().then((image) => { console.log(image.toDataURL()) w.webContents.decrementCapturerCount() }) // Replace with -w.capturePage().then(image => { +w.capturePage().then((image) => { console.log(image.toDataURL()) }) ``` @@ -2002,30 +2037,33 @@ address changes upstream that made our previous implementation untenable and rif // Main process const { webContents } = require('electron') -webContents.printToPDF({ - landscape: true, - displayHeaderFooter: true, - printBackground: true, - scale: 2, - pageSize: 'Ledger', - margins: { - top: 2, - bottom: 2, - left: 2, - right: 2 - }, - pageRanges: '1-5, 8, 11-13', - headerTemplate: '

Title

', - footerTemplate: '
', - preferCSSPageSize: true -}).then(data => { - fs.writeFile(pdfPath, data, (error) => { - if (error) throw error - console.log(`Wrote PDF successfully to ${pdfPath}`) +webContents + .printToPDF({ + landscape: true, + displayHeaderFooter: true, + printBackground: true, + scale: 2, + pageSize: 'Ledger', + margins: { + top: 2, + bottom: 2, + left: 2, + right: 2 + }, + pageRanges: '1-5, 8, 11-13', + headerTemplate: '

Title

', + footerTemplate: '
', + preferCSSPageSize: true + }) + .then((data) => { + fs.writeFile(pdfPath, data, (error) => { + if (error) throw error + console.log(`Wrote PDF successfully to ${pdfPath}`) + }) + }) + .catch((error) => { + console.log(`Failed to write PDF to ${pdfPath}: `, error) }) -}).catch(error => { - console.log(`Failed to write PDF to ${pdfPath}: `, error) -}) ``` ## Breaking API Changes (20.0) @@ -2097,10 +2135,7 @@ If you need this functionality, it can be replaced as follows: // Main process const { ipcMain, desktopCapturer } = require('electron') -ipcMain.handle( - 'DESKTOP_CAPTURER_GET_SOURCES', - (event, opts) => desktopCapturer.getSources(opts) -) +ipcMain.handle('DESKTOP_CAPTURER_GET_SOURCES', (event, opts) => desktopCapturer.getSources(opts)) ``` ```js @@ -2582,7 +2617,9 @@ The APIs are now synchronous and the optional callback is no longer needed. ```js // Deprecated -protocol.unregisterProtocol(scheme, () => { /* ... */ }) +protocol.unregisterProtocol(scheme, () => { + /* ... */ +}) // Replace with protocol.unregisterProtocol(scheme) ``` @@ -2611,7 +2648,9 @@ The APIs are now synchronous and the optional callback is no longer needed. ```js // Deprecated -protocol.registerFileProtocol(scheme, handler, () => { /* ... */ }) +protocol.registerFileProtocol(scheme, handler, () => { + /* ... */ +}) // Replace with protocol.registerFileProtocol(scheme, handler) ``` @@ -2626,7 +2665,9 @@ and `protocol.isProtocolIntercepted` instead. ```js // Deprecated -protocol.isProtocolHandled(scheme).then(() => { /* ... */ }) +protocol.isProtocolHandled(scheme).then(() => { + /* ... */ +}) // Replace with const isRegistered = protocol.isProtocolRegistered(scheme) const isIntercepted = protocol.isProtocolIntercepted(scheme) @@ -2843,11 +2884,17 @@ Use the new `updated` event on the `nativeTheme` module instead. ```js // Deprecated -systemPreferences.on('inverted-color-scheme-changed', () => { /* ... */ }) -systemPreferences.on('high-contrast-color-scheme-changed', () => { /* ... */ }) +systemPreferences.on('inverted-color-scheme-changed', () => { + /* ... */ +}) +systemPreferences.on('high-contrast-color-scheme-changed', () => { + /* ... */ +}) // Replace with -nativeTheme.on('updated', () => { /* ... */ }) +nativeTheme.on('updated', () => { + /* ... */ +}) ``` ### Deprecated: methods in `systemPreferences` @@ -2930,13 +2977,11 @@ webFrame.setIsolatedWorldContentSecurityPolicy(worldId, csp) webFrame.setIsolatedWorldHumanReadableName(worldId, name) webFrame.setIsolatedWorldSecurityOrigin(worldId, securityOrigin) // Replace with -webFrame.setIsolatedWorldInfo( - worldId, - { - securityOrigin: 'some_origin', - name: 'human_readable_name', - csp: 'content_security_policy' - }) +webFrame.setIsolatedWorldInfo(worldId, { + securityOrigin: 'some_origin', + name: 'human_readable_name', + csp: 'content_security_policy' +}) ``` ### Removed: `marked` property on `getBlinkMemoryInfo` @@ -3150,13 +3195,11 @@ webFrame.setIsolatedWorldContentSecurityPolicy(worldId, csp) webFrame.setIsolatedWorldHumanReadableName(worldId, name) webFrame.setIsolatedWorldSecurityOrigin(worldId, securityOrigin) // Replace with -webFrame.setIsolatedWorldInfo( - worldId, - { - securityOrigin: 'some_origin', - name: 'human_readable_name', - csp: 'content_security_policy' - }) +webFrame.setIsolatedWorldInfo(worldId, { + securityOrigin: 'some_origin', + name: 'human_readable_name', + csp: 'content_security_policy' +}) ``` ### API Changed: `webFrame.setSpellCheckProvider` now takes an asynchronous callback @@ -3173,7 +3216,7 @@ webFrame.setSpellCheckProvider('en-US', true, { // Replace with webFrame.setSpellCheckProvider('en-US', { spellCheck: (words, callback) => { - callback(words.filter(text => spellchecker.isMisspelled(text))) + callback(words.filter((text) => spellchecker.isMisspelled(text))) } }) ``` @@ -3425,8 +3468,12 @@ webview.setAttribute('guestinstance', instanceId) // There is no replacement for this API // Keyboard listeners no longer work on webview tag -webview.onkeydown = () => { /* handler */ } -webview.onkeyup = () => { /* handler */ } +webview.onkeydown = () => { + /* handler */ +} +webview.onkeyup = () => { + /* handler */ +} ``` ### Node Headers URL diff --git a/docs/development/creating-api.md b/docs/development/creating-api.md index 558318997d..176f208567 100644 --- a/docs/development/creating-api.md +++ b/docs/development/creating-api.md @@ -129,9 +129,9 @@ void Initialize(v8::Local exports, In the [`typings/internal-ambient.d.ts`](../../typings/internal-ambient.d.ts) file, we need to append a new property onto the `Process` interface like so: -```ts title='typings/internal-ambient.d.ts' @ts-nocheck +```ts title='typings/internal-ambient.d.ts' @ts-nocheck @noformat interface Process { - _linkedBinding(name: 'electron_browser_{api_name}'): Electron.ApiName; + _linkedBinding(name: 'electron_browser_{api_name}'): Electron.ApiName; } ``` @@ -165,7 +165,7 @@ An example of the contents of this file can be found [here](../../lib/browser/ap Add your module to the module list found at `"lib/browser/api/module-list.ts"` like so: -```ts title='lib/browser/api/module-list.ts' @ts-nocheck +```ts title='lib/browser/api/module-list.ts' @ts-nocheck @noformat export const browserModuleList: ElectronInternal.ModuleEntry[] = [ { name: 'apiName', loader: () => require('./api-name') } ]; diff --git a/docs/development/multi-monitor-testing.md b/docs/development/multi-monitor-testing.md index 900c8170d3..3bdcc62625 100644 --- a/docs/development/multi-monitor-testing.md +++ b/docs/development/multi-monitor-testing.md @@ -94,7 +94,7 @@ const display1 = virtualDisplay.create({ x: 0, y: 0, width: 1920, height: 1080 } const display2 = virtualDisplay.create({ x: 500, y: 0, width: 1920, height: 1080 }) // macOS automatically repositions display2 to x: 1920 to prevent overlap -const actualBounds = screen.getAllDisplays().map(d => d.bounds) +const actualBounds = screen.getAllDisplays().map((d) => d.bounds) // Result: [{ x: 0, y: 0, width: 1920, height: 1080 }, { x: 1920, y: 0, width: 1920, height: 1080 }] ``` diff --git a/docs/development/style-guide.md b/docs/development/style-guide.md index aea35d6cae..722c81e06b 100644 --- a/docs/development/style-guide.md +++ b/docs/development/style-guide.md @@ -55,7 +55,9 @@ There are a few style guidelines that aren't covered by the linter rules: purposes. * No nesting lists more than 2 levels (due to the markdown renderer). * All `js` and `javascript` code blocks are linted with - [oxlint](https://oxc.rs/docs/guide/usage/linter) as part of `npm run lint:docs`. + [oxlint](https://oxc.rs/docs/guide/usage/linter) and formatted with + [oxfmt](https://oxc.rs/docs/guide/usage/formatter) as part of `npm run lint:docs`; + `npm run lint:fmt-in-markdown -- --fix` reformats them. * For unordered lists, use asterisks instead of dashes. ## Picking words diff --git a/docs/tutorial/application-menu.md b/docs/tutorial/application-menu.md index c77e7983ce..344e81b0f5 100644 --- a/docs/tutorial/application-menu.md +++ b/docs/tutorial/application-menu.md @@ -22,7 +22,7 @@ When building an application menu in Electron, each top-level array menu item ** Electron will set a default menu for your app if this API is never called. Below is an example of that default menu being created manually using shorthand [`MenuItem` roles](./menus.md#roles). -```js title='Manually creating the default menu' @ts-expect-error=[107] +```js title='Manually creating the default menu' @ts-expect-error=[94] const { shell } = require('electron/common') const { app, Menu } = require('electron/main') @@ -30,27 +30,27 @@ const isMac = process.platform === 'darwin' const template = [ // { role: 'appMenu' } ...(isMac - ? [{ - label: app.name, - submenu: [ - { role: 'about' }, - { type: 'separator' }, - { role: 'services' }, - { type: 'separator' }, - { role: 'hide' }, - { role: 'hideOthers' }, - { role: 'unhide' }, - { type: 'separator' }, - { role: 'quit' } - ] - }] + ? [ + { + label: app.name, + submenu: [ + { role: 'about' }, + { type: 'separator' }, + { role: 'services' }, + { type: 'separator' }, + { role: 'hide' }, + { role: 'hideOthers' }, + { role: 'unhide' }, + { type: 'separator' }, + { role: 'quit' } + ] + } + ] : []), // { role: 'fileMenu' } { label: 'File', - submenu: [ - isMac ? { role: 'close' } : { role: 'quit' } - ] + submenu: [isMac ? { role: 'close' } : { role: 'quit' }] }, // { role: 'editMenu' } { @@ -70,17 +70,10 @@ const template = [ { type: 'separator' }, { label: 'Speech', - submenu: [ - { role: 'startSpeaking' }, - { role: 'stopSpeaking' } - ] + submenu: [{ role: 'startSpeaking' }, { role: 'stopSpeaking' }] } ] - : [ - { role: 'delete' }, - { type: 'separator' }, - { role: 'selectAll' } - ]) + : [{ role: 'delete' }, { type: 'separator' }, { role: 'selectAll' }]) ] }, // { role: 'viewMenu' } @@ -105,15 +98,8 @@ const template = [ { role: 'minimize' }, { role: 'zoom' }, ...(isMac - ? [ - { type: 'separator' }, - { role: 'front' }, - { type: 'separator' }, - { role: 'window' } - ] - : [ - { role: 'close' } - ]) + ? [{ type: 'separator' }, { role: 'front' }, { type: 'separator' }, { role: 'window' }] + : [{ role: 'close' }]) ] }, { @@ -148,14 +134,12 @@ Menu.setApplicationMenu(menu) Defining each submenu explicitly can get very verbose. If you want to re-use default submenus in your app, you can use various submenu-related roles provided by Electron. -```js title='Using default roles for each submenu' @ts-expect-error=[26] +```js title='Using default roles for each submenu' @ts-expect-error=[24] const { shell } = require('electron/common') const { app, Menu } = require('electron/main') const template = [ - ...(process.platform === 'darwin' - ? [{ role: 'appMenu' }] - : []), + ...(process.platform === 'darwin' ? [{ role: 'appMenu' }] : []), { role: 'fileMenu' }, { role: 'editMenu' }, { role: 'viewMenu' }, @@ -194,10 +178,7 @@ const win = new BrowserWindow() const menu = Menu.buildFromTemplate([ { label: 'my custom menu', - submenu: [ - { role: 'copy' }, - { role: 'paste' } - ] + submenu: [{ role: 'copy' }, { role: 'paste' }] } ]) win.setMenu(menu) diff --git a/docs/tutorial/automated-testing.md b/docs/tutorial/automated-testing.md index 740f79c393..c38453923b 100644 --- a/docs/tutorial/automated-testing.md +++ b/docs/tutorial/automated-testing.md @@ -42,16 +42,18 @@ After running the configuration wizard, your `wdio.conf.js` should include rough export const config = { // ... services: ['electron'], - capabilities: [{ - browserName: 'electron', - 'wdio:electronServiceOptions': { - // WebdriverIO can automatically find your bundled application - // if you use Electron Forge or electron-builder, otherwise you - // can define it here, e.g.: - // appBinaryPath: './path/to/bundled/application.exe', - appArgs: ['foo', 'bar=baz'] + capabilities: [ + { + browserName: 'electron', + 'wdio:electronServiceOptions': { + // WebdriverIO can automatically find your bundled application + // if you use Electron Forge or electron-builder, otherwise you + // can define it here, e.g.: + // appBinaryPath: './path/to/bundled/application.exe', + appArgs: ['foo', 'bar=baz'] + } } - }] + ] // ... } ``` @@ -300,7 +302,9 @@ const electronPath = require('electron') const childProcess = require('node:child_process') // spawn the process -const env = { /* ... */ } +const env = { + /* ... */ +} const stdio = ['inherit', 'inherit', 'inherit', 'ipc'] const appProcess = childProcess.spawn(electronPath, ['./app'], { stdio, env }) @@ -334,7 +338,7 @@ a `TestDriver` class: ```js title='testDriver.js' @ts-nocheck class TestDriver { - constructor ({ path, args, env }) { + constructor({ path, args, env }) { this.rpcCalls = [] // start child process @@ -362,14 +366,14 @@ class TestDriver { // simple RPC call // to use: driver.rpc('method', 1, 2, 3).then(...) - async rpc (cmd, ...args) { + async rpc(cmd, ...args) { // send rpc request const msgId = this.rpcCalls.length this.process.send({ msgId, cmd, args }) return new Promise((resolve, reject) => this.rpcCalls.push({ resolve, reject })) } - stop () { + stop() { this.process.kill() } } @@ -381,7 +385,7 @@ In your app code, you can then write a simple handler to receive RPC calls: ```js title='main.js' const METHODS = { - isReady () { + isReady() { // do any setup needed return true } @@ -428,10 +432,10 @@ const app = new TestDriver({ NODE_ENV: 'test' } }) -test.before(async t => { +test.before(async (t) => { await app.isReady }) -test.after.always('cleanup', async t => { +test.after.always('cleanup', async (t) => { await app.stop() }) ``` diff --git a/docs/tutorial/context-isolation.md b/docs/tutorial/context-isolation.md index 389db0cc9f..3f264b04f6 100644 --- a/docs/tutorial/context-isolation.md +++ b/docs/tutorial/context-isolation.md @@ -86,7 +86,7 @@ You can create a `interface.d.ts` declaration file and globally augment the `Win ```ts title='interface.d.ts' @ts-noisolate export interface IElectronAPI { - loadPreferences: () => Promise, + loadPreferences: () => Promise } declare global { diff --git a/docs/tutorial/context-menu.md b/docs/tutorial/context-menu.md index 99563d8ef9..bcdf291d6e 100644 --- a/docs/tutorial/context-menu.md +++ b/docs/tutorial/context-menu.md @@ -61,7 +61,7 @@ win.webContents.on('context-menu', (_event, params) => { // Whether the context is editable. if (params.isEditable) { menu.popup({ - // highlight-next-line + // highlight-next-line frame: params.frame }) } diff --git a/docs/tutorial/esm.md b/docs/tutorial/esm.md index 1bc6e3e2f6..f4dac5848e 100644 --- a/docs/tutorial/esm.md +++ b/docs/tutorial/esm.md @@ -85,7 +85,7 @@ The `@babel/plugin-transform-modules-commonjs` plugin will transform ESM imports down to `require` calls. The exact syntax will depend on the [`importInterop` setting](https://babeljs.io/docs/babel-plugin-transform-modules-commonjs#importinterop). -```js @nolint @ts-nocheck title='@babel/plugin-transform-modules-commonjs' +```js @nolint @noformat @ts-nocheck title='@babel/plugin-transform-modules-commonjs' import foo from "foo"; import { bar } from "bar"; foo; diff --git a/docs/tutorial/in-app-purchases.md b/docs/tutorial/in-app-purchases.md index 0696bf260a..f43dc7c95b 100644 --- a/docs/tutorial/in-app-purchases.md +++ b/docs/tutorial/in-app-purchases.md @@ -76,7 +76,6 @@ inAppPurchase.on('transactions-updated', (event, transactions) => { } case 'failed': - console.log(`Failed to purchase ${payment.productIdentifier}.`) // Finish the transaction. @@ -84,12 +83,10 @@ inAppPurchase.on('transactions-updated', (event, transactions) => { break case 'restored': - console.log(`The purchase of ${payment.productIdentifier} has been restored.`) break case 'deferred': - console.log(`The purchase of ${payment.productIdentifier} has been deferred.`) break @@ -105,7 +102,7 @@ if (!inAppPurchase.canMakePayments()) { } // Retrieve and display the product descriptions. -inAppPurchase.getProducts(PRODUCT_IDS).then(products => { +inAppPurchase.getProducts(PRODUCT_IDS).then((products) => { // Check the parameters. if (!Array.isArray(products) || products.length <= 0) { console.log('Unable to retrieve the product information.') @@ -122,7 +119,7 @@ inAppPurchase.getProducts(PRODUCT_IDS).then(products => { const selectedQuantity = 1 // Purchase the selected product. - inAppPurchase.purchaseProduct(selectedProduct.productIdentifier, selectedQuantity).then(isProductValid => { + inAppPurchase.purchaseProduct(selectedProduct.productIdentifier, selectedQuantity).then((isProductValid) => { if (!isProductValid) { console.log('The product is not valid.') return diff --git a/docs/tutorial/ipc.md b/docs/tutorial/ipc.md index 1c2e285ba0..e484bcbf18 100644 --- a/docs/tutorial/ipc.md +++ b/docs/tutorial/ipc.md @@ -57,13 +57,13 @@ const path = require('node:path') // ... -function handleSetTitle (event, title) { +function handleSetTitle(event, title) { const webContents = event.sender const win = BrowserWindow.fromWebContents(webContents) win.setTitle(title) } -function createWindow () { +function createWindow() { const mainWindow = new BrowserWindow({ webPreferences: { preload: path.join(__dirname, 'preload.js') @@ -189,14 +189,14 @@ const path = require('node:path') // ... -async function handleFileOpen () { +async function handleFileOpen() { const { canceled, filePaths } = await dialog.showOpenDialog({}) if (!canceled) { return filePaths[0] } } -function createWindow () { +function createWindow() { const mainWindow = new BrowserWindow({ webPreferences: { preload: path.join(__dirname, 'preload.js') @@ -384,7 +384,7 @@ const { app, BrowserWindow, Menu, ipcMain } = require('electron') const path = require('node:path') -function createWindow () { +function createWindow() { const mainWindow = new BrowserWindow({ webPreferences: { preload: path.join(__dirname, 'preload.js') diff --git a/docs/tutorial/keyboard-shortcuts.md b/docs/tutorial/keyboard-shortcuts.md index eeb613410c..eb2a0c953a 100644 --- a/docs/tutorial/keyboard-shortcuts.md +++ b/docs/tutorial/keyboard-shortcuts.md @@ -108,11 +108,13 @@ if (process.platform === 'darwin') { } // highlight-start -const submenu = Menu.buildFromTemplate([{ - label: 'Open a Dialog', - click: () => dialog.showMessageBox({ message: 'Hello World!' }), - accelerator: 'CommandOrControl+Alt+R' -}]) +const submenu = Menu.buildFromTemplate([ + { + label: 'Open a Dialog', + click: () => dialog.showMessageBox({ message: 'Hello World!' }), + accelerator: 'CommandOrControl+Alt+R' + } +]) menu.append(new MenuItem({ label: 'Custom Menu', submenu })) // highlight-end diff --git a/docs/tutorial/launch-app-from-url-in-another-app.md b/docs/tutorial/launch-app-from-url-in-another-app.md index ee9af51250..d12dbf3f4e 100644 --- a/docs/tutorial/launch-app-from-url-in-another-app.md +++ b/docs/tutorial/launch-app-from-url-in-another-app.md @@ -193,9 +193,9 @@ packager({ schemes: ['electron-fiddle'] } ] - -}).then(paths => console.log(`SUCCESS: Created ${paths.join(', ')}`)) - .catch(err => console.error(`ERROR: ${err.message}`)) +}) + .then((paths) => console.log(`SUCCESS: Created ${paths.join(', ')}`)) + .catch((err) => console.error(`ERROR: ${err.message}`)) ``` If you're using Electron Packager's CLI, use the `--protocol` and `--protocol-name` flags. For diff --git a/docs/tutorial/local-ai-handler.md b/docs/tutorial/local-ai-handler.md index c8d23f056a..bb7bf84be1 100644 --- a/docs/tutorial/local-ai-handler.md +++ b/docs/tutorial/local-ai-handler.md @@ -61,7 +61,7 @@ localAIHandler.setPromptAPIHandler((details) => { // details.securityOrigin — origin of the calling page return class MyLanguageModel extends LanguageModelUtility { - static async create (options) { + static async create(options) { // options.signal - AbortSignal to cancel the creation of the model // options.initialPrompts - initial prompts to pass to the language model @@ -71,26 +71,26 @@ localAIHandler.setPromptAPIHandler((details) => { }) } - static async availability () { + static async availability() { // Return 'available', 'downloadable', 'downloading', or 'unavailable' return 'available' } - async prompt (input) { + async prompt(input) { // input is a LanguageModelMessage[] // Return a string response from your model, or a ReadableStream // to return a streaming response. return 'This is a response from your local LLM!' } - async clone () { + async clone() { return new MyLanguageModel({ contextUsage: this.contextUsage, contextWindow: this.contextWindow }) } - destroy () { + destroy() { // Clean up model resources } } diff --git a/docs/tutorial/mac-app-store-submission-guide.md b/docs/tutorial/mac-app-store-submission-guide.md index b04d6eac58..efb9f19c3d 100644 --- a/docs/tutorial/mac-app-store-submission-guide.md +++ b/docs/tutorial/mac-app-store-submission-guide.md @@ -266,7 +266,7 @@ With `@electron/osx-sign`, you can set custom entitlements per file as such: ```js @ts-nocheck const { signAsync } = require('@electron/osx-sign') -function getEntitlementsForFile (filePath) { +function getEntitlementsForFile(filePath) { if (filePath.startsWith('my-path-1')) { return './my-path-1.plist' } else { diff --git a/docs/tutorial/macos-dock.md b/docs/tutorial/macos-dock.md index 7d0a8a1d83..7b45b11ec2 100644 --- a/docs/tutorial/macos-dock.md +++ b/docs/tutorial/macos-dock.md @@ -49,7 +49,9 @@ app.whenReady().then(() => { const dockMenu = Menu.buildFromTemplate([ { label: 'New Window', - click: () => { const win = new BrowserWindow() } + click: () => { + const win = new BrowserWindow() + } } // add more menu options to the array ]) diff --git a/docs/tutorial/menus.md b/docs/tutorial/menus.md index c765b8f331..641e225393 100644 --- a/docs/tutorial/menus.md +++ b/docs/tutorial/menus.md @@ -306,8 +306,11 @@ To add visual aid to your menus, you can use the `icon` property to assign image const { nativeImage } = require('electron/common') const { MenuItem } = require('electron/main') -// highlight-next-line -const green = nativeImage.createFromDataURL('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAACOSURBVHgBpZLRDYAgEEOrEzgCozCCGzkCbKArOIlugJvgoRAUNcLRpvGH19TkgFQWkqIohhK8UEaKwKcsOg/+WR1vX+AlA74u6q4FqgCOSzwsGHCwbKliAF89Cv89tWmOT4VaVMoVbOBrdQUz+FrD6XItzh4LzYB1HFJ9yrEkZ4l+wvcid9pTssh4UKbPd+4vED2Nd54iAAAAAElFTkSuQmCC') +// highlight-start +const green = nativeImage.createFromDataURL( + 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAACOSURBVHgBpZLRDYAgEEOrEzgCozCCGzkCbKArOIlugJvgoRAUNcLRpvGH19TkgFQWkqIohhK8UEaKwKcsOg/+WR1vX+AlA74u6q4FqgCOSzwsGHCwbKliAF89Cv89tWmOT4VaVMoVbOBrdQUz+FrD6XItzh4LzYB1HFJ9yrEkZ4l+wvcid9pTssh4UKbPd+4vED2Nd54iAAAAAElFTkSuQmCC' +) +// highlight-end const item = new MenuItem({ label: 'Green Circle', @@ -328,7 +331,9 @@ const item = new MenuItem({ label: 'Log Message', // highlight-next-line sublabel: 'This will use the console.log utility', - click: () => { console.log('Logging via menu...') } + click: () => { + console.log('Logging via menu...') + } }) ``` diff --git a/docs/tutorial/message-ports.md b/docs/tutorial/message-ports.md index 37c48fad9a..ff533f3230 100644 --- a/docs/tutorial/message-ports.md +++ b/docs/tutorial/message-ports.md @@ -129,11 +129,11 @@ listeners. ```js title='preloadMain.js and preloadSecondary.js (Preload scripts)' @ts-window-type={electronMessagePort:MessagePort} const { ipcRenderer } = require('electron') -ipcRenderer.on('port', e => { +ipcRenderer.on('port', (e) => { // port received, make it globally available. window.electronMessagePort = e.ports[0] - window.electronMessagePort.onmessage = messageEvent => { + window.electronMessagePort.onmessage = (messageEvent) => { // handle message } }) @@ -245,18 +245,14 @@ Electron's built-in IPC methods only support two modes: fire-and-forget can implement a "response stream", where a single request responds with a stream of data. -```js title='renderer.js (Renderer Process)' @ts-expect-error=[18] +```js title='renderer.js (Renderer Process)' @ts-expect-error=[14] const makeStreamingRequest = (element, callback) => { // MessageChannels are lightweight--it's cheap to create a new one for each // request. const { port1, port2 } = new MessageChannel() // We send one end of the port to the main process ... - ipcRenderer.postMessage( - 'give-me-a-stream', - { element, count: 10 }, - [port2] - ) + ipcRenderer.postMessage('give-me-a-stream', { element, count: 10 }, [port2]) // ... and we hang on to the other end. The main process will send messages // to its end of the port, and close it when it's finished. @@ -343,7 +339,7 @@ const { ipcRenderer } = require('electron') // We need to wait until the main world is ready to receive the message before // sending the port. We create this promise in the preload so it's guaranteed // to register the onload listener before the load event is fired. -const windowLoaded = new Promise(resolve => { +const windowLoaded = new Promise((resolve) => { window.onload = resolve }) diff --git a/docs/tutorial/native-code-and-electron-objc-macos.md b/docs/tutorial/native-code-and-electron-objc-macos.md index 13175ef7f7..32cdae35cb 100644 --- a/docs/tutorial/native-code-and-electron-objc-macos.md +++ b/docs/tutorial/native-code-and-electron-objc-macos.md @@ -1105,7 +1105,7 @@ You're so close! We now have working Objective-C and thread-safe ways to expose const EventEmitter = require('node:events') class ObjcMacosAddon extends EventEmitter { - constructor () { + constructor() { super() if (process.platform !== 'darwin') { @@ -1120,19 +1120,19 @@ class ObjcMacosAddon extends EventEmitter { }) } - helloWorld (input = '') { + helloWorld(input = '') { return this.addon.helloWorld(input) } - helloGui () { + helloGui() { this.addon.helloGui() } - destroy () { + destroy() { this.addon.destroy() } - parse (payload) { + parse(payload) { const parsed = JSON.parse(payload) return { ...parsed, date: new Date(parsed.date) } diff --git a/docs/tutorial/native-code-and-electron-swift-macos.md b/docs/tutorial/native-code-and-electron-swift-macos.md index b675c61e81..49983b01c9 100644 --- a/docs/tutorial/native-code-and-electron-swift-macos.md +++ b/docs/tutorial/native-code-and-electron-swift-macos.md @@ -1118,7 +1118,7 @@ You're so close! We now have working Objective-C, Swift, and thread-safe ways to const EventEmitter = require('node:events') class SwiftAddon extends EventEmitter { - constructor () { + constructor() { super() if (process.platform !== 'darwin') { @@ -1141,19 +1141,19 @@ class SwiftAddon extends EventEmitter { }) } - helloWorld (input = '') { + helloWorld(input = '') { return this.addon.helloWorld(input) } - helloGui () { + helloGui() { this.addon.helloGui() } - destroy () { + destroy() { this.addon.destroy() } - parse (payload) { + parse(payload) { const parsed = JSON.parse(payload) return { ...parsed, date: new Date(parsed.date) } diff --git a/docs/tutorial/native-code-and-electron.md b/docs/tutorial/native-code-and-electron.md index 75788cdfdc..884894b09b 100644 --- a/docs/tutorial/native-code-and-electron.md +++ b/docs/tutorial/native-code-and-electron.md @@ -279,7 +279,7 @@ const native = bindings('my_addon') // Create a nice JavaScript wrapper class MyNativeAddon extends EventEmitter { - constructor () { + constructor() { super() // Create an instance of our C++ class @@ -287,7 +287,7 @@ class MyNativeAddon extends EventEmitter { } // Wrap the C++ method with a nicer JavaScript API - helloWorld (input = '') { + helloWorld(input = '') { if (typeof input !== 'string') { throw new TypeError('Input must be a string') } diff --git a/docs/tutorial/navigation-history.md b/docs/tutorial/navigation-history.md index 5460f945a6..5a67815eef 100644 --- a/docs/tutorial/navigation-history.md +++ b/docs/tutorial/navigation-history.md @@ -77,7 +77,7 @@ A common flow is that you want to restore the history of a webContents - for ins const firstWindow = new BrowserWindow() // Later, you want a second window to have the same history and navigation position -async function restore () { +async function restore() { const entries = firstWindow.webContents.navigationHistory.getAllEntries() const index = firstWindow.webContents.navigationHistory.getActiveIndex() diff --git a/docs/tutorial/notifications.md b/docs/tutorial/notifications.md index a0b4ae9bbf..f41c9078db 100644 --- a/docs/tutorial/notifications.md +++ b/docs/tutorial/notifications.md @@ -71,12 +71,10 @@ Notifications can be displayed directly from the renderer process with the ```js title='Renderer Process' const NOTIFICATION_TITLE = 'Title' -const NOTIFICATION_BODY = - 'Notification from the Renderer process. Click to log to console.' +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 Notification(NOTIFICATION_TITLE, { body: NOTIFICATION_BODY }).onclick = () => console.log(CLICK_MESSAGE) ``` Here's a full example that you can open with Electron Fiddle: diff --git a/docs/tutorial/performance.md b/docs/tutorial/performance.md index 9895f456ff..d0a5fee371 100644 --- a/docs/tutorial/performance.md +++ b/docs/tutorial/performance.md @@ -179,11 +179,11 @@ const fs = require('node:fs') const fooParser = require('foo-parser') class Parser { - constructor () { + constructor() { this.files = fs.readdirSync('.') } - getParsedFiles () { + getParsedFiles() { return fooParser.parse(this.files) } } @@ -202,16 +202,16 @@ do this work a little later, when `getParsedFiles()` is actually called? const fs = require('node:fs') class Parser { - async getFiles () { + async getFiles() { // Touch the disk as soon as `getFiles` is called, not sooner. // Also, ensure that we're not blocking other operations by using // the asynchronous version. - this.files = this.files || await fs.promises.readdir('.') + this.files = this.files || (await fs.promises.readdir('.')) return this.files } - async getParsedFiles () { + async getParsedFiles() { // Our fictitious foo-parser is a big and expensive module to load, so // defer that work until we actually need to parse files. // Since `require()` comes with a module cache, the `require()` call diff --git a/docs/tutorial/security.md b/docs/tutorial/security.md index 71b1e96021..2c41c9400b 100644 --- a/docs/tutorial/security.md +++ b/docs/tutorial/security.md @@ -291,22 +291,20 @@ const { session } = require('electron') const { URL } = require('node:url') -session - .defaultSession - .setPermissionRequestHandler((webContents, permission, callback) => { - const parsedUrl = new URL(webContents.getURL()) +session.defaultSession.setPermissionRequestHandler((webContents, permission, callback) => { + const parsedUrl = new URL(webContents.getURL()) - if (permission === 'notifications') { - // Approves the permissions request - callback(true) - } + if (permission === 'notifications') { + // Approves the permissions request + callback(true) + } - // Verify URL - if (parsedUrl.protocol !== 'https:' || parsedUrl.host !== 'example.com') { - // Denies the permissions request - return callback(false) - } - }) + // Verify URL + if (parsedUrl.protocol !== 'https:' || parsedUrl.host !== 'example.com') { + // Denies the permissions request + return callback(false) + } +}) ``` Note: `session.defaultSession` is only available after `app.whenReady` is called. @@ -395,7 +393,7 @@ session.defaultSession.webRequest.onHeadersReceived((details, callback) => { callback({ responseHeaders: { ...details.responseHeaders, - 'Content-Security-Policy': ['default-src \'none\''] + 'Content-Security-Policy': ["default-src 'none'"] } }) }) @@ -770,7 +768,7 @@ ipcMain.handle('get-secrets', (e) => { return getSecrets() }) -function validateSender (frame) { +function validateSender(frame) { // Validate the frame's origin against an allowlist. Use the origin, not the // URL: about:blank, blob: and sandboxed documents have URLs that do not // identify who controls them, and the frame may be null if it has gone away. diff --git a/docs/tutorial/snapcraft.md b/docs/tutorial/snapcraft.md index 9e6094c28c..cce19e9a28 100644 --- a/docs/tutorial/snapcraft.md +++ b/docs/tutorial/snapcraft.md @@ -75,8 +75,7 @@ programmatically. For more information, see the [Snapcraft API docs][snapcraft-s ```js @ts-nocheck const snap = require('electron-installer-snap') -snap(options) - .then(snapPath => console.log(`Created snap at ${snapPath}!`)) +snap(options).then((snapPath) => console.log(`Created snap at ${snapPath}!`)) ``` ## Using `snapcraft` with `@electron/packager` diff --git a/docs/tutorial/spellchecker.md b/docs/tutorial/spellchecker.md index 2df7b409ec..66c84da708 100644 --- a/docs/tutorial/spellchecker.md +++ b/docs/tutorial/spellchecker.md @@ -43,10 +43,12 @@ myWindow.webContents.on('context-menu', (event, params) => { // Add each spelling suggestion for (const suggestion of params.dictionarySuggestions) { - menu.append(new MenuItem({ - label: suggestion, - click: () => myWindow.webContents.replaceMisspelling(suggestion) - })) + menu.append( + new MenuItem({ + label: suggestion, + click: () => myWindow.webContents.replaceMisspelling(suggestion) + }) + ) } // Allow users to add the misspelled word to the dictionary diff --git a/docs/tutorial/tray.md b/docs/tutorial/tray.md index 346c496f3b..65cd2ad93d 100644 --- a/docs/tutorial/tray.md +++ b/docs/tutorial/tray.md @@ -59,14 +59,14 @@ const { app, Tray, Menu } = require('electron/main') let tray // 16x16 red circle data URL -const icon = nativeImage.createFromDataURL('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAACTSURBVHgBpZKBCYAgEEV/TeAIjuIIbdQIuUGt0CS1gW1iZ2jIVaTnhw+Cvs8/OYDJA4Y8kR3ZR2/kmazxJbpUEfQ/Dm/UG7wVwHkjlQdMFfDdJMFaACebnjJGyDWgcnZu1/lrCrl6NCoEHJBrDwEr5NrT6ko/UV8xdLAC2N49mlc5CylpYh8wCwqrvbBGLoKGvz8Bfq0QPWEUo/EAAAAASUVORK5CYII=') +const icon = nativeImage.createFromDataURL( + 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAACTSURBVHgBpZKBCYAgEEV/TeAIjuIIbdQIuUGt0CS1gW1iZ2jIVaTnhw+Cvs8/OYDJA4Y8kR3ZR2/kmazxJbpUEfQ/Dm/UG7wVwHkjlQdMFfDdJMFaACebnjJGyDWgcnZu1/lrCrl6NCoEHJBrDwEr5NrT6ko/UV8xdLAC2N49mlc5CylpYh8wCwqrvbBGLoKGvz8Bfq0QPWEUo/EAAAAASUVORK5CYII=' +) // The Tray can only be instantiated after the 'ready' event is fired app.whenReady().then(() => { tray = new Tray(icon) - const contextMenu = Menu.buildFromTemplate([ - { role: 'quit' } - ]) + const contextMenu = Menu.buildFromTemplate([{ role: 'quit' }]) tray.setContextMenu(contextMenu) }) ``` diff --git a/docs/tutorial/updates.md b/docs/tutorial/updates.md index 3afa6229c4..d9090eb239 100644 --- a/docs/tutorial/updates.md +++ b/docs/tutorial/updates.md @@ -221,15 +221,14 @@ 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): -```js title="main.js" @ts-expect-error=[11] +```js title="main.js" @ts-expect-error=[10] autoUpdater.on('update-downloaded', (event, releaseNotes, releaseName) => { const dialogOpts = { type: 'info', buttons: ['Restart', 'Later'], title: 'Application Update', message: process.platform === 'win32' ? releaseNotes : releaseName, - detail: - 'A new version has been downloaded. Restart the application to apply the updates.' + detail: 'A new version has been downloaded. Restart the application to apply the updates.' } dialog.showMessageBox(dialogOpts).then((returnValue) => { diff --git a/docs/tutorial/window-state-persistence.md b/docs/tutorial/window-state-persistence.md index 87e8ea6218..2065ee36b1 100644 --- a/docs/tutorial/window-state-persistence.md +++ b/docs/tutorial/window-state-persistence.md @@ -15,7 +15,7 @@ To enable Window State Persistence, set `windowStatePersistence: true` in your w ```js const { app, BrowserWindow } = require('electron') -function createWindow () { +function createWindow() { const win = new BrowserWindow({ name: 'main-window', width: 800, @@ -46,7 +46,7 @@ You can control which aspects of the window state are persisted by passing an ob ```js const { app, BrowserWindow } = require('electron') -function createWindow () { +function createWindow() { const win = new BrowserWindow({ name: 'main-window', width: 800, diff --git a/docs/tutorial/windows-taskbar.md b/docs/tutorial/windows-taskbar.md index e48b37c4d9..edf9587536 100644 --- a/docs/tutorial/windows-taskbar.md +++ b/docs/tutorial/windows-taskbar.md @@ -135,12 +135,17 @@ win.setThumbarButtons([ { tooltip: 'button1', icon: nativeImage.createFromPath(path.join(__dirname, 'button1.png')), - click () { console.log('button1 clicked') } - }, { + click() { + console.log('button1 clicked') + } + }, + { tooltip: 'button2', icon: nativeImage.createFromPath(path.join(__dirname, 'button2.png')), flags: ['enabled', 'dismissonclick'], - click () { console.log('button2 clicked.') } + click() { + console.log('button2 clicked.') + } } ]) ``` diff --git a/package.json b/package.json index 135f501ebc..81b5816109 100644 --- a/package.json +++ b/package.json @@ -50,12 +50,13 @@ "lint:objc": "node ./script/lint.js --objc", "lint:py": "node ./script/lint.js --py", "lint:gn": "node ./script/lint.js --gn", - "lint:docs": "npm run lint:js-in-markdown && npm run create-typescript-definitions && npm run lint:ts-check-js-in-markdown && npm run lint:docs-fiddles && npm run lint:docs-relative-links && npm run lint:markdown && npm run lint:api-history", + "lint:docs": "npm run lint:js-in-markdown && npm run lint:fmt-in-markdown && npm run create-typescript-definitions && npm run lint:ts-check-js-in-markdown && npm run lint:docs-fiddles && npm run lint:docs-relative-links && npm run lint:markdown && npm run lint:api-history", "lint:docs-fiddles": "oxlint docs/fiddles", "lint:docs-relative-links": "lint-roller-markdown-links --resource-root . --root docs \"**/*.md\"", "lint:markdown": "node ./script/lint.js --md", "lint:ts-check-js-in-markdown": "lint-roller-markdown-ts-check --root docs \"**/*.md\" --ignore \"breaking-changes.md\"", "lint:js-in-markdown": "lint-roller-markdown-oxlint --root docs \"**/*.md\"", + "lint:fmt-in-markdown": "lint-roller-markdown-oxfmt --root docs \"**/*.md\" --config docs/.oxfmtrc.json", "lint:api-history": "lint-roller-markdown-api-history --root \"./docs/api/\" --schema \"./docs/api-history.schema.json\" --breaking-changes-file \"./docs/breaking-changes.md\" --check-placement --check-strings \"*.md\"", "lint:chromium-roller": "node ./script/lint-roller-chromium-changes.mjs", "create-api-json": "node script/create-api-json.mjs",