tabs.executeScript and tabs.insertCSS not always executed from webRequest.onHeadersReceived

RESOLVED WONTFIX

Status

RESOLVED WONTFIX
a year ago
2 months ago

People

(Reporter: blask, Unassigned)

Tracking

55 Branch

Firefox Tracking Flags

(Not tracked)

Details

(Reporter)

Description

a year ago
User Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:53.0) Gecko/20100101 Firefox/53.0
Build ID: 20170524180630

Steps to reproduce:

I am trying to insert CSS/Javascript into image pages, so I do:

browser.webRequest.onHeadersReceived.addListener(
    checkHeaders,
    {
        types: ["main_frame"],
        urls: ["<all_urls>"],
    },
    ["responseHeaders"]
);

function checkHeaders(details) {
    for (let header of details.responseHeaders) {
        if (header.name === "Content-Type" && header.value.indexOf("image/") === 0) {
            console.log(header.value, details.url, details.tabId);
            modifyTab(details.tabId);
            return;
        }
    }
}

function modifyTab(tabId) {
    console.log("executeScript");
    browser.tabs.executeScript(
        tabId,
        {
            file: "content.js",
            runAt: "document_start",
        }
    );
    console.log("insertCSS");
    browser.tabs.insertCSS(
        tabId,
        {
            code: `
                img {
                    width: auto;
                    height: auto;
                }
            `,
        }
    );
} 

content.js contains just a console.log("load")


Actual results:

For all image URLs:

Opening a link in the same tab by clicking on it doesn't work.
Opening a link in another tab works.
Manually entering the URL in the location bar works.
Ctrl-Shift-R works
Ctrl-R doesn't work.

Where "works" means I get  "executeScript", "insertCSS" and "load" in the console and Javascript/CSS are applied.
"doesn't work" means I do get  "executeScript" and "insertCSS" in the console but not "load" and the Javascript/CSS are not applied.


Expected results:

Javascript and CSS should always be applied.
Component: Untriaged → WebExtensions: Request Handling
Product: Firefox → Toolkit
Page load cycles are extremely complicated. At the time that we receive request headers for a top-level document request, the document global for that request hasn't been created yet, since how it's created depends on the results of those headers. And insertCSS and executeScript only work if the document in the tab when the load request gets to the content process is the same as it was when insertCSS/executeScript was called.

The few cases that do work only work because we have special handling for the first non-blank document loaded into a tab, where we can reuse the original blank document for the final load.

So if you want to do something like this, you need to use webNavigation events, or a mix of webRequest and and tabs events.
Status: UNCONFIRMED → RESOLVED
Last Resolved: a year ago
Resolution: --- → WONTFIX
(Reporter)

Comment 2

a year ago
Fair enough. It worked on Chrome, so I thought it might be something that should/could be fixed. If webextensions get standardized, it would be great to include the ordering of events of different APIs, because it's very hard to combine different APIs otherwise. After some experimentation this seems to be the only thing that works reliably (adding an onComitted listener in onHeaderReceived did not work reliably either...):

var knownImageURLs = new Set();

browser.webRequest.onHeadersReceived.addListener(
    checkForImageURL,
    {
        types: ["main_frame"],
        urls: ["<all_urls>"],
    },
    ["responseHeaders"]
);

browser.webNavigation.onCommitted.addListener(maybeModifyTab);

function checkForImageURL(details) {
    if (knownImageURLs.has(details.url)) {
        return;
    }

    for (let header of details.responseHeaders) {
        if (header.name === "Content-Type" && header.value.indexOf("image/") === 0) {
            knownImageURLs.add(details.url);
            return;
        }
    }
}

function maybeModifyTab(details) {
    if (!knownImageURLs.has(details.url) || details.frameId !== 0) {
        return;
    }

    modifyTab(details.tabId);
}

Updated

2 months ago
Product: Toolkit → WebExtensions
You need to log in before you can comment on or make changes to this bug.