w3c / webextensions

Charter and administrivia for the WebExtensions Community Group (WECG)

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

API limitation: content scripts URL matches and History API, Navigation API, BFCache

bershanskiy opened this issue · comments

Summary

Content Script declarations can contain match patterns with non-empty paths (e.g., https://example.com/subpage with path /subpage). The match is evaluated only on the initial document navigation and not on URL replacement in response to History API invocation. (BFCache discards a document if there was an extension-related event affecting it between document entering BFCache and getting restored.)
To sum up, currently CS match patterns with non-/* or /*/*paths may not be reliable when pages use History or Navigation API.

Example

Example extension

manifest.json

{
  "name": "Demo",
  "manifest_version": 2,
  "version":"1",
  "content_scripts": [{
    "js": ["content-script.js"],
    "matches": ["https://example.com/sub"]
  }]
}

content-script.js

console.error('ran');

Steps

  1. Go to https://example.com/
  2. Open console and observe no error logged ran
  3. Replace URL via History API by running this in console: history.replaceState(undefined,undefined,"/sub")
  4. Observe that the URL changed to https://example.com/sub but the ran did not appear
  5. Reload the page via reload button and observe ran error message logged in the console

This would help avoid injecting unnecessarily in the entire site with a listener for navigation.onnavigate (Chrome only as of now) or using the background script with chrome.tabs.onUpdated (wakes up the background script for unrelated URLs) or chrome.webNavigation.onHistoryStateUpdated (adds a scary installation warning).

Since it would be a breaking change, a new key in the declaration is necessary e.g. "match_soft_navigation": true

This seems worth discussion, but I expect this may be behaviour we want to keep and just ensure we have adequately documented. When the URL changes to one that matches a content script, this isn't too tricky - we can just inject the script. This gets a lot harder if we try to be consistent with when you navigate away though - there's no way to "uninject" a content script that is already running and may have made changes to the page.

there's no way to "uninject" a content script that is already running and may have made changes to the page.

That applies to the reverse situation though: first load matches, successive AJAX loads and URL changes no longer match.

That applies to the reverse situation though: first load matches, successive AJAX loads and URL changes no longer match.

For sure. I think the thing we need to decide is whether having some soft navigation controls increases the confusion because now it seems like we have handling for that.

This is pretty much the same request as #446.

Meeting on 15 Feb 2024: agreed to keep implementation as is and add notes to MDN.