summaryrefslogtreecommitdiffstats
path: root/toolkit/content/widgets/moz-support-link/moz-support-link.mjs
diff options
context:
space:
mode:
Diffstat (limited to 'toolkit/content/widgets/moz-support-link/moz-support-link.mjs')
-rw-r--r--toolkit/content/widgets/moz-support-link/moz-support-link.mjs129
1 files changed, 129 insertions, 0 deletions
diff --git a/toolkit/content/widgets/moz-support-link/moz-support-link.mjs b/toolkit/content/widgets/moz-support-link/moz-support-link.mjs
new file mode 100644
index 0000000000..23f18ac434
--- /dev/null
+++ b/toolkit/content/widgets/moz-support-link/moz-support-link.mjs
@@ -0,0 +1,129 @@
+/* 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;
+}