in src/js/other-websites/inpage_menu.js [365:495]
free: async (relaySiteOrigin) => {
const fxRelayMenuBody = document.getElementById("fxRelayMenuBody");
const signedInContentFree = document.querySelector(
".fx-content-signed-in-free"
);
const signedInContentPremium = document.querySelector(
".fx-content-signed-in-premium"
);
signedInContentPremium?.remove();
// Create "You have .../.. remaining relay address" message
const remainingAliasesSpan = document.querySelector(
".fx-relay-menu-remaining-aliases"
);
const { maxNumAliases } = await browser.storage.local.get(
"maxNumAliases"
);
const maskLists = document.querySelectorAll(".fx-relay-menu-masks-list");
masks = await getMasks();
const currentPageHostName = await browser.runtime.sendMessage({
method: "getCurrentPageHostname",
});
maskLists?.forEach(async (maskList) => {
// Set Mask List label names
const label = maskList.querySelector(".fx-relay-menu-masks-list-label");
const stringId = label.dataset.stringId;
label.textContent = browser.i18n.getMessage(stringId);
// If there are no masks used on the current site, we need to change the label for the other masks:
if (
!checkIfAnyMasksWereGeneratedOnCurrentWebsite(
masks,
currentPageHostName
) &&
maskList.classList.contains("fx-relay-menu-masks-free-other")
) {
label.textContent = browser.i18n.getMessage(
"pageInputIconSelectFromYourCurrentEmailMasks"
);
}
if (masks.length > 0) {
// Populate mask lists, but filter by current website
const buildFilteredMaskList = maskList.classList.contains(
"fx-relay-menu-masks-free-this-website"
);
const filteredMasks = buildFilteredMaskList
? masks.filter(
(mask) =>
mask.generated_for === currentPageHostName ||
hasMaskBeenUsedOnCurrentSite(mask, currentPageHostName)
)
: masks.filter(
(mask) =>
mask.generated_for !== currentPageHostName &&
!hasMaskBeenUsedOnCurrentSite(mask, currentPageHostName)
);
filteredMasks.sort((a, b) => (a.created_at < b.created_at ? 1 : -1));
await populateFreeMaskList(maskList, filteredMasks);
}
});
const numAliasesRemaining = maxNumAliases - masks.length;
const maxNumAliasesReached = numAliasesRemaining <= 0;
// Check if premium features are available
const premiumCountryAvailability = (await browser.storage.local.get("periodicalPremiumPlans")).periodicalPremiumPlans?.PERIODICAL_PREMIUM_PLANS
// Set Generate Mask button
buildContent.components.setUnlimitedButton(
relaySiteOrigin,
premiumCountryAvailability
);
// Free user: Set text informing them how many aliases they can create
remainingAliasesSpan.textContent = browser.i18n.getMessage(
"popupRemainingFreeMasks",
[numAliasesRemaining, maxNumAliases]
);
const generateAliasBtn = document.querySelector(
".fx-relay-menu-generate-alias-btn"
);
if (maxNumAliasesReached) {
generateAliasBtn.remove();
sendInPageEvent("viewed-menu", "input-menu-max-aliases-message");
remainingAliasesSpan.textContent = browser.i18n.getMessage(
"pageNoMasksRemaining"
);
const getUnlimitedAliasesBtn = document.querySelector(
".fx-relay-menu-get-unlimited-aliases"
);
getUnlimitedAliasesBtn.classList.remove("t-secondary");
getUnlimitedAliasesBtn.classList.add("t-primary");
// Focus on "Get unlimited alias" button
getUnlimitedAliasesBtn.focus();
// In the UX, there are three+ elements (from top to bottom): "Generate more" button, the list(s) and the upgrade button. When the user has maxed out their available masks, the "Generate more" button is hidden/replaced with the upgrade button. The order change is necessary to match the UX.
document.querySelector(".fx-relay-menu-masks-lists").style.order = "2";
} else {
// Set Generate Mask button
await buildContent.components.generateMaskButton();
// Focus on "Generate New Alias" button
generateAliasBtn.focus();
}
fxRelayMenuBody.classList.remove("is-loading");
// User is signed in/free: Remove the premium section from DOM so there are no hidden/screen readable-elements available
fxRelayMenuBody.classList.remove("is-premium");
signedInContentFree?.classList.remove("is-hidden");
browser.runtime.sendMessage({
method: "updateIframeHeight",
height: fxRelayMenuBody.scrollHeight,
});
},