Dynamically Insert Content Script in New Window?

49 views
Skip to first unread message

John Gordon

unread,
Jun 25, 2024, 1:24:18 PM (4 days ago) Jun 25
to Chromium Extensions
I'm trying to avoid explicitly defining content scripts to match urls -- I'm trying to limit the amount of permissions I need on install -- and I'm running into an issue where a content script I'm attempting to insert via `executeScript()` isn't working when I create a new window and attempt to insert it.

These are my permissions:

optional_host_permissions: ["*://*/*"],
permissions: ["contextMenus", "activeTab", "scripting"],

The flow:

  1. ContextMenu onclick event fired
  2. Request Permissions with { origins: ["*://*.localhost/*"] } (this works)
  3. If I get them:
    1. Open the new window with url of ("http://my-app.localhost:8000/workflow/search")
    2. Insert the script with `executeScript()`, passing in the tabId of the first tab that is in the chrome.windows.Window object that's returned by the `create()` call
I don't get any error when I insert the script, I get back an InjectionResul[] containing:

  1. documentId: "8A5832935780B3A540A1A7103A6C8E9B"
  2. frameId: 0
  3. result: null
This looks good to me, but when I view the new popup window I created, the content script isn't injected.

The only way I've gotten this to work is to define the content script in my manifest, which also requires a `matches` string array to go with it. I don't want to specify the match expliciltly, so I use "*://*/*", but this has the result of displaying in the extension's permissions that I can manipulate any page, the opposite of what I want.

Any ideas for what's going on are greatly appreciated.

    John Gordon

    unread,
    Jun 25, 2024, 2:56:18 PM (4 days ago) Jun 25
    to Chromium Extensions, John Gordon
    For clarity, here's the code that's causing the problem. Permissions are requested, the window's open, the executeScript runs without error...but the content script isn't inserted.

    chrome.contextMenus.onClicked.addListener(async (_, tab) => {
    if (!tab) return;

    const permissionResult = await chrome.permissions.request({
    origins: ["*://*.localhost/*"],
    });

    if (!permissionResult) return;

    const window = await chrome.windows.create({
    url: "http://my-app.localhost:8000/workflow/search",
    type: "popup",
    focused: true,
    });

    await chrome.scripting.executeScript({
    target: {
    tabId: window.tabs![0].id!,
    },
    files: [contentScript],
    injectImmediately: true,
    });
    });

    Is it possible there's some sort of issue with a misconfigured manifest file? Do I have to make a reference to the content script for it to work (I don't think so, based on another extension I have)?

    John Gordon

    unread,
    Jun 25, 2024, 3:20:56 PM (4 days ago) Jun 25
    to Chromium Extensions, John Gordon
    I managed to get the content script to insert, but I think there's a bug, unless I'm doing something wrong (highly, highly possible). It turns out running the executeScript() within a timeout set for 125ms successfully inserts my content script into the newly created window. Should this be the case that you have to arbitrarily wait for the window to be ready (sounds like a bug just waiting to happen)?

    Here's the code that works with the timeout call:


    chrome.contextMenus.onClicked.addListener(async (_, tab) => {
    if (!tab) return;

    const permissionResult = await chrome.permissions.request({
    origins: ["*://*.localhost/*"],
    });

    if (!permissionResult) return;

    const newWindow = await chrome.windows.create({
    url: TARGET_URL,
    focused: true,
    type: "popup",
    });

    const newTab = newWindow.tabs![0];

    setTimeout(async () => {
    console.log("new tab status after waiting?", newTab.status);
    await chrome.scripting.executeScript({
    target: {
    tabId: newTab.id!,
    },
    files: [contentScript],
    });
    }, 125); // <-- if set to 62, the script isn't injected
    });

    Another thing to note is that the newTab.status was "loading".

    woxxom

    unread,
    Jun 25, 2024, 4:08:48 PM (4 days ago) Jun 25
    to Chromium Extensions, John Gordon
    Sounds exactly like a bug that was fixed for chrome.tabs.create, so it'd be nice if you report it in https://crbug.com, if it's not reported yet.

    Solution 1 is to use chrome.tabs.onUpdated to wait for the tab to start loading, example: https://stackoverflow.com/a/67244340

    Solution 2 is to use chrome.scripting.registerContentScripts instead of executeScript. There's no way to limit it by tabId though, so if that's a concern your content script will have to use chrome.runtime.sendMessage to confirm it should run.

    John Gordon

    unread,
    Jun 25, 2024, 4:22:52 PM (4 days ago) Jun 25
    to Chromium Extensions, woxxom, John Gordon
    I ran into this a few weeks ago on another extension I was working on, too, that I posted to this group. Bug Ticket created. Thanks for the help.
    Reply all
    Reply to author
    Forward
    0 new messages