/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ window.MozXULElement?.insertFTLIfNeeded("toolkit/global/mozSupportLink.ftl"); /** * An extension of the anchor element that helps create links to Mozilla's * support documentation. This should be used for SUMO links only - other "Learn * more" links can use the regular anchor element. * * @tagname moz-support-link * @attribute {string} support-page - Short-hand string from SUMO to the specific support page. * @attribute {string} utm-content - UTM parameter for a URL, if it is an AMO URL. * @attribute {string} data-l10n-id - Fluent ID used to generate the text content. */ export default class MozSupportLink extends HTMLAnchorElement { static SUPPORT_URL = "https://www.mozilla.org/"; static get observedAttributes() { return ["support-page", "utm-content"]; } /** * Handles setting up the SUPPORT_URL preference getter. * Without this, the tests for this component may not behave * as expected. * @private * @memberof MozSupportLink */ #register() { if (window.document.nodePrincipal?.isSystemPrincipal) { // eslint-disable-next-line no-shadow let { XPCOMUtils } = window.XPCOMUtils ? window : ChromeUtils.importESModule( "resource://gre/modules/XPCOMUtils.sys.mjs" ); XPCOMUtils.defineLazyPreferenceGetter( MozSupportLink, "SUPPORT_URL", "app.support.baseURL", "", null, val => Services.urlFormatter.formatURL(val) ); } else if (!window.IS_STORYBOOK) { MozSupportLink.SUPPORT_URL = window.RPMGetFormatURLPref( "app.support.baseURL" ); } } connectedCallback() { this.#register(); this.#setHref(); this.setAttribute("target", "_blank"); this.addEventListener("click", this); if ( !this.getAttribute("data-l10n-id") && !this.getAttribute("data-l10n-name") && !this.childElementCount ) { document.l10n.setAttributes(this, "moz-support-link-text"); } document.l10n.translateFragment(this); } disconnectedCallback() { this.removeEventListener("click", this); } handleEvent(e) { if (e.type == "click") { if (window.openTrustedLinkIn) { let where = whereToOpenLink(e, false, true); if (where == "current") { where = "tab"; } e.preventDefault(); openTrustedLinkIn(this.href, where); } } } attributeChangedCallback(attrName, oldVal, newVal) { if (attrName === "support-page" || attrName === "utm-content") { this.#setHref(); } } #setHref() { let supportPage = this.getAttribute("support-page") ?? ""; let base = MozSupportLink.SUPPORT_URL + supportPage; this.href = this.hasAttribute("utm-content") ? formatUTMParams(this.getAttribute("utm-content"), base) : base; } } customElements.define("moz-support-link", MozSupportLink, { extends: "a" }); /** * Adds UTM parameters to a given URL, if it is an AMO URL. * * @param {string} contentAttribute * Identifies the part of the UI with which the link is associated. * @param {string} url * @returns {string} * The url with UTM parameters if it is an AMO URL. * Otherwise the url in unmodified form. */ export function formatUTMParams(contentAttribute, url) { if (!contentAttribute) { return url; } let parsedUrl = new URL(url); let domain = `.${parsedUrl.hostname}`; if ( !domain.endsWith(".mozilla.org") && // For testing: addons-dev.allizom.org and addons.allizom.org !domain.endsWith(".allizom.org") ) { return url; } parsedUrl.searchParams.set("utm_source", "firefox-browser"); parsedUrl.searchParams.set("utm_medium", "firefox-browser"); parsedUrl.searchParams.set("utm_content", contentAttribute); return parsedUrl.href; }