UNPKG

@shopgate/pwa-common

Version:

Common library for the Shopgate Connect PWA.

164 lines (157 loc) 5.36 kB
import _inheritsLoose from "@babel/runtime/helpers/inheritsLoose"; import React, { Component } from 'react'; import PropTypes from 'prop-types'; import classNames from 'classnames'; import { embeddedMedia, configuration } from '@shopgate/engage/core/collections'; import { CONFIGURATION_COLLECTION_KEY_UNIVERSAL_LINK_HANDLER } from '@shopgate/engage/core/constants'; import EmbeddedMedia from "../EmbeddedMedia"; import parseHTML from "../../helpers/html/parseHTML"; import connect from "./connector"; /** * Checks if a link is a universal link. * @param {string} link The link to check. * @returns {boolean} True if the link is a universal link, false otherwise. */ import { jsx as _jsx } from "react/jsx-runtime"; const isUniversalLink = link => link.startsWith('http://') || link.startsWith('https://'); /** * HtmlSanitizer component. */ let HtmlSanitizer = /*#__PURE__*/function (_Component) { /** * @param {Object} props The component props. */ function HtmlSanitizer(props) { var _this; _this = _Component.call(this, props) || this; /** * If the user tapped a link element, prevent the default behavior. * @param {Object} event The touchstart event. */ _this.handleClick = event => { // Prevent multiple clicks on links while the first one is still being processed. if (_this.state.openingLink) { event.preventDefault(); return; } _this.setState({ openingLink: true }); const linkTag = event.target.closest('a'); if (!linkTag) return; const href = linkTag.getAttribute('href'); const target = linkTag.getAttribute('target') || ''; if (!href) return; event.preventDefault(); /** * Runs async logic to open links to potentially resolve universal links. */ const openLink = async () => { const universalLinkHandler = configuration.get(CONFIGURATION_COLLECTION_KEY_UNIVERSAL_LINK_HANDLER); let link = href; // If the universalLinkHandler is registered by an extension and the link looks like a // qualified URL, we try to resolve it as a universal link. if (typeof universalLinkHandler === 'function' && isUniversalLink(link)) { const { redirectLink = null, handled = false } = (await universalLinkHandler({ link })) ?? {}; if (handled) { _this.setState({ openingLink: false }); return; } if (redirectLink) { link = redirectLink; } } _this.setState({ openingLink: false }); if (!link) { return; } if (_this.props.settings.handleClick) { _this.props.settings.handleClick(link, target); } else { _this.props.navigate(link, target); } }; openLink(); }; _this.htmlContainer = /*#__PURE__*/React.createRef(); _this.state = { openingLink: false }; return _this; } /** * Registers the event handler for when the user taps inside the html content. */ _inheritsLoose(HtmlSanitizer, _Component); var _proto = HtmlSanitizer.prototype; _proto.componentDidMount = function componentDidMount() { embeddedMedia.add(this.htmlContainer.current); } /** * Only update if the HTML changed. * @param {Object} nextProps The next props for the component. * @return {boolean} */; _proto.shouldComponentUpdate = function shouldComponentUpdate(nextProps) { return nextProps.children !== this.props.children || nextProps.comfortCookiesAccepted !== this.props.comfortCookiesAccepted || nextProps.statisticsCookiesAccepted !== this.props.statisticsCookiesAccepted; } /** * Updates embedded media within the html container. */; _proto.componentDidUpdate = function componentDidUpdate() { embeddedMedia.add(this.htmlContainer.current); } /** * Removes the event handler. */; _proto.componentWillUnmount = function componentWillUnmount() { embeddedMedia.remove(this.htmlContainer.current); }; /** * Renders the component. * @returns {JSX} */ _proto.render = function render() { const cookieConsentSettings = { comfortCookiesAccepted: this.props.comfortCookiesAccepted, statisticsCookiesAccepted: this.props.statisticsCookiesAccepted }; const innerHTML = { __html: parseHTML(this.props.children, this.props.decode, this.props.settings, this.props.processStyles, cookieConsentSettings) }; const { wrapper: Wrapper } = this.props; return /*#__PURE__*/_jsx(Wrapper, { cookieConsentSettings: cookieConsentSettings, children: /*#__PURE__*/_jsx("div", { // eslint-disable-next-line react/no-danger dangerouslySetInnerHTML: innerHTML, ref: this.htmlContainer, className: classNames(this.props.className, 'common__html-sanitizer'), onClickCapture: this.handleClick }) }); }; return HtmlSanitizer; }(Component); HtmlSanitizer.defaultProps = { children: '', className: '', decode: false, processStyles: false, settings: {}, wrapper: EmbeddedMedia, comfortCookiesAccepted: false, statisticsCookiesAccepted: false }; export default connect(HtmlSanitizer);