import icon from "src/decidim/icon" const DEFAULT_MESSAGES = { externalLink: "External link", opensInNewTab: "Opens in new tab" }; let MESSAGES = DEFAULT_MESSAGES; /** * Appends an icon to distinguish those links pointing out of decidim. * It will apply to all a[target="_blank"] found in the document * * This behaviour can be omitted adding data-external-link="false" attribute to the anchor tag * e.g. ... * * If you do not want to display the external link indicator, you still need to indicate that * the link opens in a new tab to the screen readers. This can be done by adding * data-external-link="text-only" attribute to the anchor tag, * e.g. ... * * In addition, if you want to disable the external link warning for the link, you can add the * data-external-domain-link="false" attribute to the anchor tag, * e.g. ... */ export default class ExternalLink { static configureMessages(messages) { MESSAGES = { ...DEFAULT_MESSAGES, ...messages }; } constructor(node) { if (node.closest(".editor-container")) { return; } if (!node.querySelector("span[data-external-link]")) { if (node.dataset.externalLink === "text-only") { this.setupTextOnly(node); } else { this.setup(node); } } } setup(node) { const span = document.createElement("span"); span.dataset.externalLink = true; span.innerHTML = `${this.generateIcon()}${this.generateScreenReaderLabel(node)}` span.classList.add("inline-block", "mx-0.5"); return node.appendChild(span); } setupTextOnly(node) { const dummy = document.createElement("span"); dummy.innerHTML = this.generateScreenReaderLabel(node); return node.appendChild(dummy.firstChild); } generateIcon() { return icon("external-link-line", { class: "fill-current" }); } generateScreenReaderLabel(node) { let text = MESSAGES.opensInNewTab; if (this._isExternalLink(node)) { text = MESSAGES.externalLink; } return `(${text})`; } _isExternalLink(node) { const externalMatches = [ // Links to the internal link page /link?external_url=https%3A%2F%2Fdecidim.org new RegExp("^/link\\?external_url="), // Links starting with http/s and not to the current host new RegExp(`^https?://((?!${location.host}).)+`) ]; const href = node.getAttribute("href") || ""; return externalMatches.some(((regexp) => href.match(regexp))); } }