Skip to content
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

fix storeTabData caching wrong frame target values during prerendering #242

Merged
merged 6 commits into from
Jun 18, 2024

Conversation

fungairino
Copy link
Collaborator

@fungairino fungairino commented Jun 17, 2024

Fixes pixiebrix/pixiebrix-extension#8283

The storeTabData was caching the wrong frame value with its once usage when the browser prerenders the page (ex. the user starts typing the url in the search bar and the page is loaded (i.e. prerendered) in the background.

This change fixes the issue by waiting for the prerenderingchange event if the document is currently in prerendering state.

I tested these changes by running npm link and then in pixiebrix-extension ran npm link webext-messenger. I built the extension and tested the above-linked bug with a mod that reproduces the error. With this new change, the issue no longer is present.

Reviewer: @twschiller

Tag: @fregante

New dependency, p-event. MIT License
https://www.npmjs.com/package/p-event

source/thisTarget.ts Outdated Show resolved Hide resolved
source/thisTarget.ts Outdated Show resolved Hide resolved
Copy link
Contributor

@fregante fregante left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What happens if both calls to storeTabData are made while the tab is prerendering? The content script will be in a broken state: no tab data will ever be requested again, but this data is a hard requirement in the content script.

The only advised change here would look like this instead:

async function storeTabData() {
  if (document.prerendering) {
    await pEvent(document, 'prerenderingchange')
  }
  //continue

package.json Outdated Show resolved Hide resolved
source/thisTarget.ts Outdated Show resolved Hide resolved
source/thisTarget.ts Outdated Show resolved Hide resolved
@fungairino
Copy link
Collaborator Author

fungairino commented Jun 18, 2024

@fregante

What happens if both calls to storeTabData are made while the tab is prerendering? The content script will be in a broken state: no tab data will ever be requested again, but this data is a hard requirement in the content script.

I'm not sure I understand. What two calls are you referring to?

It seems to me that with this change we will make sure to refetch the tab data if/when it's needed again after the prerendered tab is activated.

@fregante
Copy link
Contributor

fregante commented Jun 18, 2024

storeTabData is only ever called twice in this package, you can search the two calls. The first one immediately on the first run, and it's blocked by this new prerendering check, the second one is called in the ping response handler. I reckon they could both happen while the document is prerendering, and therefore never save the tab data.

It should just wait until the document explicitly exits the prerendering stage instead.

@fungairino
Copy link
Collaborator Author

@fregante's suggested solution is simpler and also works, so I'll go with this approach!

async function storeTabData() {
  if (document.prerendering) {
    await pEvent(document, 'prerenderingchange')
  }

@fungairino fungairino requested a review from fregante June 18, 2024 13:17
@@ -65,6 +66,11 @@ const storeTabData = once(async () => {
return;
}

// If the page is prerendering, wait for the change to be able to get the tab data so the frameId is correct
if ("prerendering" in document && Boolean(document.prerendering)) {
await pEvent(document, 'prerenderingchange')
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@fungairino you might not need the if statement. The docs say that it might fire immediately if the document is already rendered: https://developer.mozilla.org/en-US/docs/Web/API/Document/prerenderingchange_event#examples

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

prerendering isnt a widely supported browser feature yet, so I'm leaning towards keeping the check to be more explicit. Especially since the linked example also still checks for the prerendering attribute.

@fungairino fungairino merged commit 31ac0c2 into pixiebrix:main Jun 18, 2024
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

FORM_GET_DEFINITION not found
3 participants