Search code examples
google-chrome-extension

chrome extensions : How do I navigate to a page on the active tab, and call a function onLoad


I need a very simple task, and it seems so hard to achieve.

I need to load a url in the active tab, and once loaded I need to call a function in content.js

I'm new to chrome extensions, so there are chances I'm drowning in a cup. What I did is that onClick on a button in my popup, I send a message to content.js to css query the page for the link, and if found click on it and wait until it's done.

My problem is that I cannot find a reliable way to react after the page ended loading. Here's my code:

popup.js

function goToProfileDetailsPage(generateBtn) {
    generateBtn.addEventListener('click', async () => {
        try {
            const [tab] = await chrome.tabs.query({active: true, currentWindow: true});
            let [{result}] = await chrome.scripting.executeScript({
                target: {tabId: tab.id},
                func: () => {
                    const PROFILE_LINK_SELECTOR = '.feed-identity-module__actor-meta a'

                    const el = document.querySelector(PROFILE_LINK_SELECTOR);
                    if (el) el.click();
                    return !!el;
                },
            });
            if (!result) {
                alert('Please go to your linkedIn profile page before pressing the generate button')
                return
            }
            await new Promise(resolve => {
                chrome.tabs.onUpdated.addListener(async function listener(tabId, info) {
                    if (tabId === tab.id && info.status === 'complete') {
                        chrome.tabs.onUpdated.removeListener(listener);
                        console.log("Finished loading profile page")
                        await generateCvAndOpenTab(tab)
                        // [{result}] = await chrome.scripting.executeScript({
                        //     target: {tabId: tab.id},
                        //     func: generateCvAndOpenTab,
                        //     arguments:{tab}
                        // });

                        resolve();
                    }
                });
            });

        console.log( "after the onUpdated event" )

        } catch (e) {
            document.body.append(e.message);
        }
    });
}

The lines

console.log("Finished loading profile page")

and

console.log( "after the onUpdated event" )

are never executed.


Solution

  • Use executeScript directly in the popup.
    For this task there's even no need for messages.

    The action popup is an extension page, which has a chrome-extension:// URL and hence is capable of using all granted chrome API. The popup is a separate window so it has its own separate devtools: right-click inside the popup and select "inspect" in the menu.

    Note that executeScript runs the function/file as a content script in the web page, so this code can access DOM of the web page directly, but it can't access DOM of the popup or any variables or functions in the outer scope. The returned value must be JSON-compatible (string, number, boolean, null, Array/Object of these types), any other types will transfer as undefined or {}.

    generateBtn.addEventListener('click', async () => {
      try {
        const [tab] = await chrome.tabs.query({active: true, currentWindow: true});
        let [{result}] = await chrome.scripting.executeScript({
          target: {tabId: tab.id},
          func: () => {
            const el = document.querySelector('.feed-identity-module__actor-meta a');
            if (el) el.click();
            return !!el;
          },
        });
        if (!result) return;
        await new Promise(resolve => {
          chrome.tabs.onUpdated.addListener(function listener(tabId, info) {
            if (tabId === tab.id && info.status === 'complete') {
              chrome.tabs.onUpdated.removeListener(listener);
              resolve();
            }
          });
        });
        [{result}] = await chrome.scripting.executeScript({
          target: {tabId: tab.id},
          func: () => {
            // do something on the new page
          },
        });
      } catch (e) {
        document.body.append(e.message);
      }
    });