Skip to content

Content script context event #1778

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

Draft
wants to merge 6 commits into
base: main
Choose a base branch
from

Conversation

sleekslush
Copy link
Contributor

Overview

Manual Testing

Related Issue

This PR closes #<issue_number>

Copy link

netlify bot commented Jun 30, 2025

Deploy Preview for creative-fairy-df92c4 ready!

Name Link
🔨 Latest commit f24fb95
🔍 Latest deploy log https://app.netlify.com/projects/creative-fairy-df92c4/deploys/6862f6d0a889910008d2a438
😎 Deploy Preview https://deploy-preview-1778--creative-fairy-df92c4.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@Timeraa Timeraa requested a review from Copilot July 24, 2025 16:37
Copy link

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR removes the script lifecycle management functionality from the ContentScriptContext class and adds a guard condition to prevent event listeners when the context is invalid. The changes eliminate the automatic invalidation mechanism that was used to stop older content script instances when new ones were loaded.

  • Removes script lifecycle management (starting/stopping old scripts detection)
  • Simplifies the constructor by removing frame detection and script lifecycle setup
  • Adds a guard condition in addEventListener to prevent registration when context is invalid


target.addEventListener?.(
eventType,
() => this.isInvalid, // signals the abort controller when invalid
Copy link
Preview

Copilot AI Jul 24, 2025

Choose a reason for hiding this comment

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

The first addEventListener call is registering a function that returns a boolean as an event handler, which is incorrect. Event handlers should be functions that handle events, not functions that return boolean values.

Suggested change
() => this.isInvalid, // signals the abort controller when invalid
(event) => {
if (this.isInvalid) {
this.abortController.abort(); // Abort the controller if invalid
}
},

Copilot uses AI. Check for mistakes.

Comment on lines +211 to 226
const eventType = type.startsWith('wxt:') ? getUniqueEventName(type) : type

target.addEventListener?.(
eventType,
() => this.isInvalid, // signals the abort controller when invalid
{
capture: true,
signal: this.signal,
},
);

target.addEventListener?.(
type.startsWith('wxt:') ? getUniqueEventName(type) : type,
eventType,
handler,
{
...options,
Copy link
Preview

Copilot AI Jul 24, 2025

Choose a reason for hiding this comment

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

The eventType variable is calculated but then the same logic is duplicated by having two separate addEventListener calls. This creates unnecessary complexity and potential for inconsistency.

Copilot uses AI. Check for mistakes.

@Timeraa
Copy link
Member

Timeraa commented Jul 24, 2025

Oops did not want to assign copilot to this, could you add more context to this (haha funny coincidence) to better understand this?

@sleekslush
Copy link
Contributor Author

Oops did not want to assign copilot to this, could you add more context to this (haha funny coincidence) to better understand this?

Yea I don't care if this PR gets selected, but the problem that we're facing is this.

Every content script injection will cause this class to initiate a window.postMessage on each page load that it's whitelisted to. Our extension injects on <all_urls> for a variety of reasons. This normally isn't a huge problem, but we have encountered some customer complaints where the JS on the page is listening for window messages, checks the origin correctly, but then doesn't inspect the shape of the message itself before using it. This causes the page to basically break in a variety of cases and we have no way to disable this behavior from wxt, even when we aren't using it.

This PR is a different approach, maybe not the correct one, but basically defers removal of these event handlers to the next time the events fire. This means it's not immediate, but there's no window messaging involved and it solves the former issues I described.

If this isn't something we want to change or do, that's totally fair, but then at a minimum, we should have some way in wxt to prevent this window.postMessage behavior from happening if we aren't using the context object.

@ion1
Copy link

ion1 commented Jul 24, 2025

Every content script injection will cause this class to initiate a window.postMessage on each page load that it's whitelisted to. Our extension injects on <all_urls> for a variety of reasons. This normally isn't a huge problem, but we have encountered some customer complaints where the JS on the page is listening for window messages, checks the origin correctly, but then doesn't inspect the shape of the message itself before using it. This causes the page to basically break in a variety of cases and we have no way to disable this behavior from wxt, even when we aren't using it.

Using postMessage also makes it easier to fingerprint the users of the extension.

One alternative would be using a custom event based on the extension ID on the window object. Websites would at least need to check for every extension by their ID separately to fingerprint users.

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.

3 participants