summaryrefslogtreecommitdiffstats
path: root/toolkit/content/widgets/moz-support-link
diff options
context:
space:
mode:
Diffstat (limited to 'toolkit/content/widgets/moz-support-link')
-rw-r--r--toolkit/content/widgets/moz-support-link/moz-support-link.mjs92
-rw-r--r--toolkit/content/widgets/moz-support-link/moz-support-link.stories.mjs69
2 files changed, 161 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..b4e1585201
--- /dev/null
+++ b/toolkit/content/widgets/moz-support-link/moz-support-link.mjs
@@ -0,0 +1,92 @@
+/* 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/. */
+
+MozXULElement.insertFTLIfNeeded("browser/components/mozSupportLink.ftl");
+
+export default class MozSupportLink extends HTMLAnchorElement {
+ static SUPPORT_URL = "https://www.mozilla.org/";
+ static get observedAttributes() {
+ return ["support-page", "utm-content", "data-l10n-id"];
+ }
+
+ /**
+ * 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.IS_STORYBOOK) {
+ 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)
+ );
+ }
+ }
+
+ connectedCallback() {
+ this.#register();
+ this.#setHref();
+ this.setAttribute("target", "_blank");
+ if (!this.getAttribute("data-l10n-id")) {
+ document.l10n.setAttributes(this, "moz-support-link-text");
+ document.l10n.translateFragment(this);
+ }
+ }
+
+ attributeChangedCallback(name, oldVal, newVal) {
+ if (name === "support-page" || name === "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;
+}
diff --git a/toolkit/content/widgets/moz-support-link/moz-support-link.stories.mjs b/toolkit/content/widgets/moz-support-link/moz-support-link.stories.mjs
new file mode 100644
index 0000000000..893fce3ad6
--- /dev/null
+++ b/toolkit/content/widgets/moz-support-link/moz-support-link.stories.mjs
@@ -0,0 +1,69 @@
+/* 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/. */
+
+import { html, ifDefined } from "../vendor/lit.all.mjs";
+// eslint-disable-next-line import/no-unassigned-import
+import "./moz-support-link.mjs";
+
+MozXULElement.insertFTLIfNeeded(
+ "locales-preview/moz-support-link-storybook.ftl"
+);
+MozXULElement.insertFTLIfNeeded("browser/components/mozSupportLink.ftl");
+
+const fluentStrings = [
+ "storybook-amo-test",
+ "storybook-fluent-test",
+ "moz-support-link-text",
+];
+
+export default {
+ title: "Design System/Experiments/MozSupportLink",
+ argTypes: {
+ dataL10nId: {
+ type: "string",
+ options: [fluentStrings[0], fluentStrings[1], fluentStrings[2]],
+ control: { type: "select" },
+ description: "Fluent ID used to generate the text content.",
+ },
+ supportPage: {
+ type: "string",
+ description:
+ "Short-hand string from SUMO to the specific support page. **Note:** changing this will not create a valid URL since we don't have access to the generated support link used in Firefox",
+ },
+ utmContent: {
+ type: "string",
+ description:
+ "UTM parameter for a URL, if it is an AMO URL. **Note:** changing this will not create a valid URL since we don't have access to the generated support link used in Firefox",
+ },
+ onClick: { action: "clicked" },
+ },
+};
+
+const Template = ({ dataL10nId, supportPage, utmContent }) => html`
+ <a
+ is="moz-support-link"
+ data-l10n-id=${ifDefined(dataL10nId)}
+ support-page=${ifDefined(supportPage)}
+ utm-content=${ifDefined(utmContent)}
+ >
+ </a>
+`;
+
+export const withAMOUrl = Template.bind({});
+withAMOUrl.args = {
+ dataL10nId: fluentStrings[0],
+ supportPage: "addons",
+ utmContent: "promoted-addon-badge",
+};
+
+export const Primary = Template.bind({});
+Primary.args = {
+ supportPage: "preferences",
+};
+
+export const withFluentId = Template.bind({});
+withFluentId.args = {
+ dataL10nId: fluentStrings[1],
+ supportPage: "preferences",
+};