Search code examples
xcodesafarisafari-extension

tabs onUpdated event not detected on Safari extension?


I am trying to develop a simple web extension/addon under Safari, which is using the tabs onUpdated event. I used the Safari XCRUN converter: https://developer.apple.com/documentation/safariservices/safari_web_extensions/converting_a_web_extension_for_safari

What I am trying to do is :

  1. Open new tab on Google Scholar with set prefs params, from "options.js" script (Options page code below)

  2. Listen for this tab to be updated and ready (e.g. tab status is complete)

  3. Then, inject a content script that will simulate the user click on save button (i.e. on GScholar page)

  4. Then remove the listener, and wait 1,5s (for GS tab to reload and finish saving) in order to finally close this tab.

    // Detect browser language
    const gsUrl = currentBrowser.i18n.getUILanguage().includes("fr")
      ? GSCHOLAR_SET_PREFS_FR_URL
      : GSCHOLAR_SET_PREFS_COM_URL;
    // Listener to detect when the GS tab has finished loading
    const gsTabListener = (tabId, changeInfo, tabInfo) => {
      if (changeInfo.url && changeInfo.url.startsWith(GSCHOLAR_HOST)) {
        currentBrowser.tabs.executeScript(
          tabId,
          {
            code: `document.getElementsByName("save")[0].click();`,
          },
          () => {
            currentBrowser.tabs.onUpdated.removeListener(gsTabListener);
            setTimeout(() => currentBrowser.tabs.remove(tabId), 1500);
          }
        );
      }
    };
    currentBrowser.tabs.onUpdated.addListener(gsTabListener); // Add tab listener
    currentBrowser.tabs.create({
      url: `${gsUrl}?inst=${gScholarInstIdList.join("&inst=")}&save=#2`,
      active: false,
    }); // Open GS tab according to browser language

The problem is that it works well on Chrome/Edge/Firefox (on MacOS), but not on Safari : the GS tab is opended but isn't closed and nothing happens :-/

PS:

  • It seems tabs onUpdated event is well supported on Safari according to MDN.

https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/tabs/onUpdated

  • I have also tried webNavigation onCompleted event, but same !

  • Developing on : MacBookAir under MacOS Monterey 12.4, Safari 15.4 (17613.2.7.18), XCode 13.3.1 (13E500a), extension is bundled with Webpack 5.68.0 (e.g. building all assets files).

I really don't see what I am doing wrong and why wouldn't this tab event be intercepted ?

Thanks for your feedback.


Solution

  • After debugging I finally sloved this by noticing that in fact the events were triggered, but missed because of the availability and values of parameters passed into callabck (changeInfo, details) depending on the browser we're on.

    So I switched from onUpdated to webNavigation.onCompleted API, which is better suited to our need (tab page fully loaded) and whose parameter is simple and consistent across browsers :-)

    const uiLanguage = currentBrowser.i18n.getUILanguage().includes("fr")
      ? "fr"
      : "com"; // Detect browser language
    const gsUrl = `${GSCHOLAR_SETTINGS_HOST}.${uiLanguage}`;
    // Listener to detect when the GS tab has finished loading
    const gsTabListener = (details) => {
      if (details && details.url && details.tabId) {
        if (details.url.startsWith(`${gsUrl}/scholar_settings?`)) {
          currentBrowser.tabs.executeScript(details.tabId, {
            code: `document.getElementsByName("save")[0].click();`,
          });
        } else if (details.url.startsWith(`${gsUrl}/scholar?`)) {
          currentBrowser.webNavigation.onCompleted.removeListener(
            gsTabListener
          );
          currentBrowser.tabs.remove(details.tabId);
        }
      }
    };
    currentBrowser.webNavigation.onCompleted.addListener(gsTabListener); // Add GS tab listener
    currentBrowser.tabs.create({
      url: `${gsUrl}/scholar_settings?inst=${gScholarInstIdList.join(
        "&inst="
      )}&save=#2`,
      active: false,
    }); // Open GS tab according to browser language