async InitPopup() {
    const tab = await getActiveTab() || {};
    const { url = '', id: tabId } = tab;
    const data = commands.GetTabDomain(url);
    const badgeData = badges[tabId] || {};
    let failure = getFailureReason(url, badgeData, '');
    // FF injects content scripts after update/install/reload
    let reset = !IS_FIREFOX && !failure[0] && badgeData[INJECT] === undefined;
    let cachedSetPopup = cache.pop(getCacheKey(tabId));
    if (reset && (cachedSetPopup ? !cachedSetPopup[0] : cachedSetPopup = {})) {
      cachedSetPopup[0] = await augmentSetPopup(
        { [IDS]: {}, menus: {} },
        { tab, url, [kFrameId]: 0, [kTop]: 1 },
      );
    }
    if (!failure[0] && badgeData[INJECT] == null) {
      if (!await isInjectable(tabId, badgeData)) {
        failure = getFailureReason('');
      } else if (reset && (reset = cachedSetPopup[0][0])[SCRIPTS].length) {
        /* We also show this after the background script is reloaded inside devtools, which keeps
           the content script connected, but breaks GM_xxxValue, GM_xhr, and so on. */
        failure = [i18n('failureReasonRestarted'), IS_APPLIED];
        reset[INJECT_INTO] = 'off';
      }
    }
    data.tab = tab;
    return [cachedSetPopup, data, failure];
  }
@type {{[tabId: string]: chrome.runtime.Port}}