From 26a029d407be480d791972afb5975cf62c9360a6 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Fri, 19 Apr 2024 02:47:55 +0200 Subject: Adding upstream version 124.0.1. Signed-off-by: Daniel Baumann --- .../widgets/moz-support-link/moz-support-link.mjs | 129 +++++++++++++++++++++ .../moz-support-link/moz-support-link.stories.mjs | 67 +++++++++++ 2 files changed, 196 insertions(+) create mode 100644 toolkit/content/widgets/moz-support-link/moz-support-link.mjs create mode 100644 toolkit/content/widgets/moz-support-link/moz-support-link.stories.mjs (limited to 'toolkit/content/widgets/moz-support-link') 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; +} 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..9afb80fcd7 --- /dev/null +++ b/toolkit/content/widgets/moz-support-link/moz-support-link.stories.mjs @@ -0,0 +1,67 @@ +/* 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("toolkit/global/mozSupportLink.ftl"); + +const fluentStrings = [ + "storybook-amo-test", + "storybook-fluent-test", + "moz-support-link-text", +]; + +export default { + title: "UI Widgets/Support Link", + component: "moz-support-link", + argTypes: { + "data-l10n-id": { + options: [fluentStrings[0], fluentStrings[1], fluentStrings[2]], + control: { type: "select" }, + }, + onClick: { action: "clicked" }, + }, + parameters: { + status: "stable", + }, +}; + +const Template = ({ + "data-l10n-id": dataL10nId, + "support-page": supportPage, + "utm-content": utmContent, +}) => html` + + +`; + +export const withAMOUrl = Template.bind({}); +withAMOUrl.args = { + "data-l10n-id": fluentStrings[0], + "support-page": "addons", + "utm-content": "promoted-addon-badge", +}; + +export const Primary = Template.bind({}); +Primary.args = { + "support-page": "preferences", + "utm-content": "", +}; + +export const withFluentId = Template.bind({}); +withFluentId.args = { + "data-l10n-id": fluentStrings[1], + "support-page": "preferences", + "utm-content": "", +}; -- cgit v1.2.3