diff options
Diffstat (limited to 'toolkit/content/widgets/moz-support-link')
-rw-r--r-- | toolkit/content/widgets/moz-support-link/moz-support-link.mjs | 92 | ||||
-rw-r--r-- | toolkit/content/widgets/moz-support-link/moz-support-link.stories.mjs | 69 |
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", +}; |