New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: add 'dom-ready' event to WebFrameMain #29290
Conversation
Should this be a dom-ready event on the WebFrameMain class instead? Seems frame specific things should go their now we have it |
I see frame discovery as a potential limitation of that approach. Currently we don't have enough events provided to know the full lifecycle of a frame. There's no Adding Also, as an aside, does |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
API looks good to me.
@MarshallOfSound Here's a proposal for how I could see providing equivalent functionality with events moved into the frame itself. interface WebContents {
/** Emitted when an iframe is created within the page. */
on(event: 'frame-created', listener: (event: Event, frame: WebFrameMain) => void): this;
}
interface WebFrameMain {
/** Emitted when the DOM has finished loading. */
on(event: 'dom-ready', listener: (event: Event) => void): this;
} Example usage: const browserWindow = new BrowserWindow()
browserWindow.webContents.on('frame-created', (e, frame) => {
frame.on('dom-ready', () => {})
}) I'd be fine making these changes if the proposal looks okay. |
My concern is with I've had a thing on the backlog for a while to not emit events that don't have listeners (to avoid paying gin converter costs) but without that work this would contain an annoying memory / performance hit for folks with lots of frames |
That's a fair point, and likely pushes the API into a better design overall. How would you feel about a details object with the IDs to lookup the frame? interface FrameCreatedDetails {
processId: number;
routingId: number;
/** When we eventually feel more comfortable, we can extend the details to include the actual frame. */
// frame: Frame;
}
interface WebContents {
/** Emitted when an iframe is created within the page. */
on(event: 'frame-created', listener: (event: Event, details: FrameCreatedDetails) => void): this;
}
interface WebFrameMain {
/** Emitted when the DOM has finished loading. */
on(event: 'dom-ready', listener: (event: Event) => void): this;
} const browserWindow = new BrowserWindow()
browserWindow.webContents.on('frame-created', (e, details) => {
const frame = webFrameMain.fromId(details.processId, details.routingId)
frame.on('dom-ready', () => {})
}) |
That seems more reasonable although slightly less easy to use for folks that do really want that frame 🤷 I think it's the better side of the trade off though |
Do we have precedence for events that use getters? e.g. const details: FrameCreatedDetails = {
get frame(): WebFrameMain {
// lazily performs gin conversion
}
} I'm not familiar with how this could be done with v8, but I believe Chrome does this for a few of their globals such as |
No but doing this lazily sounds like a nice middle ground |
6909f4b
to
e3d5087
Compare
@MarshallOfSound @zcbenz @miniak The contents of this PR has changed to reflect the discussion above. Instead of emitting a 'frame-dom-ready' event from |
@samuelmaddock does it make sense to also have a |
What's the status of this PR @samuelmaddock ? |
It's now unblocked by #30076 so I'm planning to rebase and retest sometime this week hopefully. |
f754bed
to
1714368
Compare
This PR is ready for review again. WebContent's |
API LGTM. |
fix: test failing possibly caused by lazy loaded iframes? refactor: move frame-dom-ready event into WebFrameMain test: new WebFrameMain dom-ready event refactor: return bool refactor: add gin_helper::AccessorValue for gin accessor conversion refactor: call methods directly from electron:WebContents Writing static method boilerplate isn't fun feat: add WebFrameMain 'destroyed' event Update shell/common/gin_converters/frame_converter.cc Co-authored-by: Jeremy Rose <nornagon@nornagon.net> refactor: use persistent handle for rfh obj template docs: when the WebFrameMain 'destroyed' event can occur refactor: use dcheck and 'As' instead of 'Cast' chore: add type checking to internal fields refactor: add conditional for internal field count refactor: removed 'destroyed event and isDestroyed() This may be revisited at a later time. test: frame-created event
|old_host| may be nullptr if the previous RFH was shutdown.
0c1790e
to
3f63057
Compare
Build failures are unrelated. This has two API LGTMs, one from @zcbenz and one from myself, so I'm going to go ahead and merge. |
Release Notes Persisted
|
I have automatically backported this PR to "15-x-y", please check out #30801 |
Description of Change
resolves #27344
WebContents now emits a 'frame-dom-ready' event when either the top-level frame or a sub frame's document is ready.WebFrameMain now emits a 'dom-ready' event when the frame's document is ready.
Checklist
npm test
passesRelease Notes
Notes:
WebFrameMain
which emits when the frame's document is ready.WebContents
which emits when a frame is created in the page.