Scripting API can't inject into newly created tab (race condition)
Categories
(WebExtensions :: Compatibility, enhancement, P3)
Tracking
(firefox109 affected, firefox110 affected, firefox111 affected)
People
(Reporter: juraj.masiar, Unassigned)
References
(Blocks 1 open bug)
Details
(Whiteboard: [addons-jira])
User Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/110.0
Steps to reproduce:
-
install any addon with "scripting" and some hosts permission, for example:
https://addons.mozilla.org/addon/search_result_previews/ -
in the addon page that opens after installation, open console and execute:
(async () => {
const tab = await browser.tabs.create({url: 'https://www.google.com/'});
//await new Promise(r => setTimeout(r, 1000));
await browser.scripting.executeScript({
target: {tabId: tab.id},
func: () => document.body.style.background = 'darkred',
}).catch(console.error);
})()
Actual results:
Google page opens but the background color is not changed.
In the addon page console is error:
Error: An unexpected error occurred
Expected results:
It should make the google background red.
The bug is present in ESR 102 and above.
The bug is not present in Chrome.
This is a regression - when using browser.tabs.executeScript
, it will work:
(async () => {
const tab = await browser.tabs.create({url: 'https://www.google.com/'});
//await new Promise(r => setTimeout(r, 1000));
await browser.tabs.executeScript(tab.id, {
code: `document.body.style.background = 'darkred'`,
}).catch(console.error);
})()
Comment 1•2 years ago
|
||
This is only a regression when compared with tabs.executeScript
. This is not a regression in scripting.executeScript
itself, because that has been the implementation since the start.
I just confirmed that Chrome does indeed run the content script on the new tab, even if there is a large delay between in receiving the response.
When a same-origin redirect is involved, the script runs in the final document too.
When a cross-origin redirect is involved, the script does not run at all (no errors).
I'd imagine that replicating the work-around mentioned in https://bugzilla.mozilla.org/show_bug.cgi?id=1656756#c4 would fix the issue, but this makes the implementation more complex, while the result is not unambiguously desirable.
If you were to open http://google.com
and it redirects to https://www.google.com/
, would you expect the script to run there?
Reporter | ||
Comment 2•2 years ago
|
||
Regarding the regression, yes, well, I mean from the developer point of view - those that will migrate from MV2 to MV3 will have their code broken, even though the new API provides the same capability, just MV3 compatible.
Regarding the redirects, I would say as long as it's the same second-level domain "google.com", it sounds fine to inject.
In any case, I would go with whatever Chrome is using to keep things as compatible as possible.
Comment 3•2 years ago
|
||
Hello,
I reproduced the issue on the latest Nightly (111.0a1/20230131210346), Beta (110.0b8/20230131190033) and Release (109.0.1/20230127170202) under Windows 10 x64 and Ubuntu 16.04 LTS.
The issue occurs as described: running the script from Comment 0 in the console of the add-on page that opens after installation, opens a new tab with Google, however the background is not red as per the expected results. Closing the tab with Google will also log a Error: An unexpected error occurred
in the console.
Updated•2 years ago
|
Updated•2 years ago
|
Comment 4•2 years ago
|
||
Patches are welcome.
The relevant implementation details have been mentioned at https://bugzilla.mozilla.org/show_bug.cgi?id=1656756#c4
promiseTabWhenReady
at https://searchfox.org/mozilla-central/rev/ddbeacddc15008936e8f619c8c3a05fac6eab8d8/browser/components/extensions/parent/ext-tabs.js#582-598tabListener
https://searchfox.org/mozilla-central/rev/ddbeacddc15008936e8f619c8c3a05fac6eab8d8/browser/components/extensions/parent/ext-tabs.js#78-152
This logic would have to become available at a location that's more readily available location in the code. After doing that, it would be trivial to call promiseTabWhenReady
when needed.
Description
•