* chore: bump chromium in DEPS to 158.0.8106.0 * chore: update patches Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com> * 8526232: media: Group capture-related fields into CaptureMetadata Ref: https://chromium-review.googlesource.com/c/chromium/src/+/8526232 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * 8525546: [api] Advance deprecation of callback data APIs Upstream advanced FunctionCallbackInfo::Data() and PropertyCallbackInfo::Data() from V8_DEPRECATE_SOON to V8_DEPRECATED, which Electron builds with -Werror. Switched all call sites to DataV2(), casting through v8::Value where the target type's Cast() only accepts v8::Value. Ref: https://chromium-review.googlesource.com/c/v8/v8/+/8525546 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * 8577897: Enable DeprecateUnload and DeprecateUnloadByBucket by default. Unload handlers no longer run on http(s) pages unless the page opts in via Permissions-Policy. The detached-frame specs observe IPC sent from an unload handler during cross-origin navigation, so serve their test pages with `Permissions-Policy: unload=*`. Ref: https://chromium-review.googlesource.com/c/chromium/src/+/8577897 Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01We3DwyzcxvA6LqGJdoeHAX * fixup! 8577897: Enable DeprecateUnload and DeprecateUnloadByBucket by default. docs: add breaking change for unload deprecation Document that unload handlers no longer run in http(s) documents, how to migrate to pagehide/visibilitychange, and how to opt back in. Mention pagehide alongside unload in the webFrameMain `frame.detached` docs. Ref: https://chromium-review.googlesource.com/c/chromium/src/+/8577897 Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01We3DwyzcxvA6LqGJdoeHAX * fixup! 8577897: Enable DeprecateUnload and DeprecateUnloadByBucket by default. docs: drop DeprecateUnloadByBucket note from unload breaking change Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01We3DwyzcxvA6LqGJdoeHAX * chore: bump chromium in DEPS to 158.0.8107.0 * 8527334: [Linux] Fix GlobalShortcuts portal binding issues Upstream restructured GlobalAcceleratorListenerLinux's bind state machine around the set of IDs to bind and only binds when that set changes. Adapted the registration-resolved patch to it: - ListShortcuts failures no longer abort binding upstream, so they no longer resolve registrations as failed. - Groups in a bind request are collected from the IDs being bound. - Resolve as bound when a version 1 portal already lists every shortcut, and when a group's shortcuts are already bound in the current session (upstream no longer re-binds then). - Keep closing the session on a failed bind so the failed IDs are not recorded as bound in the session. Ref: https://chromium-review.googlesource.com/c/chromium/src/+/8527334 Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01We3DwyzcxvA6LqGJdoeHAX * chore: update patches * 8574624: [Linux] Prevent QT from loading GTK3 when GSettings schemas are invalid The GSettings schema check moved from ui/gtk to ui/base/glib/gsettings.cc, so the warning for the missing font-antialiasing key now reads "Invalid GSettings schema org.gnome.desktop.interface for key font-antialiasing: missing" instead of "Schema org.gnome.desktop.interface does not have key font-antialiasing". Accept either wording in the "creates and refreshes a menu when GTK cannot initialize" spec, since the CL was reverted and relanded. Ref: https://chromium-review.googlesource.com/c/chromium/src/+/8574624 Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01We3DwyzcxvA6LqGJdoeHAX --------- Co-authored-by: electron-roller[bot] <84116207+electron-roller[bot]@users.noreply.github.com> Co-authored-by: electron-claude[bot] <279139701+electron-claude[bot]@users.noreply.github.com> Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com> Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
12 KiB
webFrameMain
Control web pages and iframes.
Process: Main
The webFrameMain module can be used to lookup frames across existing
WebContents instances. Navigation events are the common
use case.
const { BrowserWindow, webFrameMain } = require('electron')
const win = new BrowserWindow({ width: 800, height: 1500 })
win.loadURL('https://twitter.com')
win.webContents.on(
'did-frame-navigate',
(event, url, httpResponseCode, httpStatusText, isMainFrame, frameProcessId, frameRoutingId) => {
const frame = webFrameMain.fromId(frameProcessId, frameRoutingId)
if (frame) {
const code = 'document.body.innerHTML = document.body.innerHTML.replaceAll("heck", "h*ck")'
frame.executeJavaScript(code)
}
}
)
You can also access frames of existing pages by using the mainFrame property
of WebContents.
const { BrowserWindow } = require('electron')
async function main() {
const win = new BrowserWindow({ width: 800, height: 600 })
await win.loadURL('https://reddit.com')
const youtubeEmbeds = win.webContents.mainFrame.frames.filter((frame) => {
try {
const url = new URL(frame.url)
return url.host === 'www.youtube.com'
} catch {
return false
}
})
console.log(youtubeEmbeds)
}
main()
Methods
These methods can be accessed from the webFrameMain module:
webFrameMain.fromId(processId, routingId)
processIdInteger - AnIntegerrepresenting the internal ID of the process which owns the frame.routingIdInteger - AnIntegerrepresenting the unique frame ID in the current renderer process. Routing IDs can be retrieved fromWebFrameMaininstances (frame.routingId) and are also passed by frame specificWebContentsnavigation events (e.g.did-frame-navigate).
Returns WebFrameMain | undefined - A frame with the given process and routing IDs,
or undefined if there is no WebFrameMain associated with the given IDs.
webFrameMain.fromFrameToken(processId, frameToken)
processIdInteger - AnIntegerrepresenting the internal ID of the process which owns the frame.frameTokenstring - Astringtoken identifying the unique frame. Can also be retrieved in the renderer process viawebFrame.frameToken.
Returns WebFrameMain | null - A frame with the given process and frame token,
or null if there is no WebFrameMain associated with the given IDs.
Class: WebFrameMain
Process: Main
This class is not exported from the 'electron' module. It is only available as a return value of other methods in the Electron API.
Instance Events
Event: 'dom-ready'
Emitted when the document is loaded.
Instance Methods
frame.executeJavaScript(code[, userGesture])
codestringuserGestureboolean (optional) - Default isfalse.
Returns Promise<unknown> - A promise that resolves with the result of the executed
code or is rejected if execution throws or results in a rejected promise.
Evaluates code in page.
In the browser window some HTML APIs like requestFullScreen can only be
invoked by a gesture from the user. Setting userGesture to true will remove
this limitation.
frame.reload()
Returns boolean - Whether the reload was initiated successfully. Only results in false when the frame has no history.
frame.isDestroyed()
Returns boolean - Whether the frame is destroyed.
frame.send(channel, ...args)
channelstring...argsany[]
Send an asynchronous message to the renderer process via channel, along with
arguments. Arguments will be serialized with the Structured Clone Algorithm,
just like postMessage, so prototype chains will not be included.
Sending Functions, Promises, Symbols, WeakMaps, or WeakSets will throw an exception.
The renderer process can handle the message by listening to channel with the
ipcRenderer module.
frame.postMessage(channel, message, [transfer])
channelstringmessageanytransferMessagePortMain[] (optional)
Send a message to the renderer process, optionally transferring ownership of
zero or more MessagePortMain objects.
The transferred MessagePortMain objects will be available in the renderer
process by accessing the ports property of the emitted event. When they
arrive in the renderer, they will be native DOM MessagePort objects.
For example:
// Main process
const win = new BrowserWindow()
const { port1, port2 } = new MessageChannelMain()
win.webContents.mainFrame.postMessage('port', { message: 'hello' }, [port1])
// Renderer process
ipcRenderer.on('port', (e, msg) => {
const [port] = e.ports
// ...
})
frame.collectJavaScriptCallStack() Experimental
Returns Promise<string> | Promise<void> - A promise that resolves with the currently running JavaScript call
stack. If no JavaScript runs in the frame, the promise will never resolve. In cases where the call stack is
otherwise unable to be collected, it will return undefined.
This can be useful to determine why the frame is unresponsive in cases where there's long-running JavaScript. For more information, see the proposed Crash Reporting API.
const { app } = require('electron')
app.commandLine.appendSwitch('enable-features', 'DocumentPolicyIncludeJSCallStacksInCrashReports')
app.on('web-contents-created', (_, webContents) => {
webContents.on('unresponsive', async () => {
// Interrupt execution and collect call stack from unresponsive renderer
const callStack = await webContents.mainFrame.collectJavaScriptCallStack()
console.log('Renderer unresponsive\n', callStack)
})
})
frame.copyVideoFrameAt(x, y)
xIntegeryInteger
When executed on a video media element, copies the frame at (x, y) to the clipboard.
frame.saveVideoFrameAs(x, y)
xIntegeryInteger
When executed on a video media element, shows a save dialog and saves the frame at (x, y) to disk.
frame.printToPDF(options)
optionsPrintToPDFOptions
Returns Promise<Buffer> - Resolves with the generated PDF data.
Prints the frame's web page as PDF.
Unlike webContents.printToPDF,
this method prints only the contents of the frame it is called on. This can be
used to print an individual <iframe> from the main process.
The landscape will be ignored if @page CSS at-rule is used in the web page.
An example of printing an iframe to PDF:
const { app, BrowserWindow } = require('electron')
const fs = require('node:fs')
const os = require('node:os')
const path = require('node:path')
app.whenReady().then(() => {
const win = new BrowserWindow()
win.loadFile('page-with-iframe.html')
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}`)
})
})
.catch((error) => {
console.log(`Failed to write PDF to ${pdfPath}: `, error)
})
})
})
See Page.printToPdf for more information.
Instance Properties
frame.ipc Readonly
An IpcMain instance scoped to the frame.
IPC messages sent with ipcRenderer.send, ipcRenderer.sendSync or
ipcRenderer.postMessage will be delivered in the following order:
contents.on('ipc-message')contents.mainFrame.on(channel)contents.ipc.on(channel)ipcMain.on(channel)
Handlers registered with invoke will be checked in the following order. The
first one that is defined will be called, the rest will be ignored.
contents.mainFrame.handle(channel)contents.handle(channel)ipcMain.handle(channel)
In most cases, only the main frame of a WebContents can send or receive IPC
messages. However, if the nodeIntegrationInSubFrames option is enabled, it is
possible for child frames to send and receive IPC messages also. The
WebContents.ipc interface may be more
convenient when nodeIntegrationInSubFrames is not enabled.
frame.url Readonly
A string representing the current URL of the frame.
frame.origin Readonly
A string representing the current origin of the frame, serialized according
to RFC 6454. This may be different
from the URL. For instance, if the frame is a child window opened to
about:blank, then frame.origin will return the parent frame's origin, while
frame.url will return the empty string. Pages without a scheme/host/port
triple origin will have the serialized origin of "null" (that is, the string
containing the letters n, u, l, l).
frame.top Readonly
A WebFrameMain | null representing top frame in the frame hierarchy to which frame
belongs.
frame.parent Readonly
A WebFrameMain | null representing parent frame of frame, the property would be
null if frame is the top frame in the frame hierarchy.
frame.frames Readonly
A WebFrameMain[] collection containing the direct descendents of frame.
frame.framesInSubtree Readonly
A WebFrameMain[] collection containing every frame in the subtree of frame,
including itself. This can be useful when traversing through all frames.
frame.frameTreeNodeId Readonly
An Integer representing the id of the frame's internal FrameTreeNode
instance. This id is browser-global and uniquely identifies a frame that hosts
content. The identifier is fixed at the creation of the frame and stays
constant for the lifetime of the frame. When the frame is removed, the id is
not used again.
frame.name Readonly
A string representing the frame name.
frame.frameToken Readonly
A string which uniquely identifies the frame within its associated renderer
process. This is equivalent to webFrame.frameToken.
frame.osProcessId Readonly
An Integer representing the operating system pid of the process which owns this frame.
frame.processId Readonly
An Integer representing the Chromium internal pid of the process which owns this frame.
This is not the same as the OS process ID; to read that use frame.osProcessId.
frame.routingId Readonly
An Integer representing the unique frame id in the current renderer process.
Distinct WebFrameMain instances that refer to the same underlying frame will
have the same routingId.
frame.visibilityState Readonly
A string representing the visibility state of the frame.
See also how the Page Visibility API is affected by other Electron APIs.
frame.detached Readonly
A Boolean representing whether the frame is detached from the frame tree. If a frame is accessed
while the corresponding page is running any pagehide or unload listeners, it may become detached as the
newly navigated page replaced it in the frame tree.