UNPKG

@gravatar-com/hovercards

Version:
912 lines (881 loc) 43.3 kB
/******/ // The require scope /******/ var __webpack_require__ = {}; /******/ /************************************************************************/ /******/ /* webpack/runtime/define property getters */ /******/ (() => { /******/ // define getter functions for harmony exports /******/ __webpack_require__.d = (exports, definition) => { /******/ for(var key in definition) { /******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) { /******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] }); /******/ } /******/ } /******/ }; /******/ })(); /******/ /******/ /* webpack/runtime/hasOwnProperty shorthand */ /******/ (() => { /******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop)) /******/ })(); /******/ /************************************************************************/ var __webpack_exports__ = {}; // EXPORTS __webpack_require__.d(__webpack_exports__, { S: () => (/* reexport */ Hovercards) }); ;// CONCATENATED MODULE: ./src/assign-position.ts var paddingMap = { top: 'paddingBottom', bottom: 'paddingTop', left: 'paddingRight', right: 'paddingLeft' }; /** * Computes and assigns the position of the card element. * * @param {HTMLElement} ref - The ref element. * @param {HTMLDivElement} card - The card element. * @param {Options} [options={}] - The placement, offset, auto-flip, and auto-shift options. * @return {void} */ function assignPosition(ref, card, _temp) { var _ref = _temp === void 0 ? {} : _temp, _ref$placement = _ref.placement, placement = _ref$placement === void 0 ? 'right-start' : _ref$placement, _ref$offset = _ref.offset, offset = _ref$offset === void 0 ? 0 : _ref$offset, _ref$autoFlip = _ref.autoFlip, autoFlip = _ref$autoFlip === void 0 ? true : _ref$autoFlip, _ref$autoShift = _ref.autoShift, autoShift = _ref$autoShift === void 0 ? true : _ref$autoShift; // Reset the card's padding for re-calculation card.style.padding = '0'; var refRect = ref.getBoundingClientRect(); var cardRect = card.getBoundingClientRect(); var refScrollT = refRect.top + scrollY; var refScrollB = refRect.bottom + scrollY; var refScrollR = refRect.right + scrollX; var refScrollL = refRect.left + scrollX; var topSpace = refRect.top; var bottomSpace = innerHeight - refRect.bottom; var leftSpace = refRect.left; var rightSpace = innerWidth - refRect.right; var x = 0; var y = 0; var _placement$split = placement.split('-'), dir = _placement$split[0], align = _placement$split[1]; offset = Math.max(0, offset); // Auto flip the card when there's not enough space if (autoFlip) { var dirSpaceV = cardRect.height + offset; var dirSpaceH = cardRect.width + offset; if (dir === 'top' && topSpace < dirSpaceV && bottomSpace > topSpace) { dir = 'bottom'; } else if (dir === 'bottom' && bottomSpace < dirSpaceV && topSpace > bottomSpace) { dir = 'top'; } else if (dir === 'left' && leftSpace < dirSpaceH && rightSpace > leftSpace) { dir = 'right'; } else if (dir === 'right' && rightSpace < dirSpaceH && leftSpace > rightSpace) { dir = 'left'; } } // Auto shift the card when there's not enough space if (autoShift) { var alignSpaceV = cardRect.height - refRect.height; var alignSpaceH = cardRect.width - refRect.width; var halfAlignSpaceV = alignSpaceV / 2; var halfAlignSpaceH = alignSpaceH / 2; if (dir === 'top' || dir === 'bottom') { if (align === 'start' && rightSpace < alignSpaceH) { if (rightSpace < halfAlignSpaceH) { align = 'end'; } else { align = undefined; } } else if (align === 'end' && leftSpace < alignSpaceH) { if (leftSpace < halfAlignSpaceH) { align = 'start'; } else { align = undefined; } } else if (align === undefined && (rightSpace < halfAlignSpaceH || leftSpace < halfAlignSpaceH)) { if (rightSpace > leftSpace) { align = 'start'; } else { align = 'end'; } } } if (dir === 'right' || dir === 'left') { if (align === 'start' && bottomSpace < alignSpaceV) { if (bottomSpace < halfAlignSpaceV) { align = 'end'; } else { align = undefined; } } else if (align === 'end' && topSpace < alignSpaceV) { if (topSpace < halfAlignSpaceV) { align = 'start'; } else { align = undefined; } } else if (align === undefined && (bottomSpace < halfAlignSpaceV || topSpace < halfAlignSpaceV)) { if (bottomSpace > topSpace) { align = 'start'; } else { align = 'end'; } } } } // Calculate the position of the card if (dir === 'top' || dir === 'bottom') { x = refScrollL + refRect.width / 2 - cardRect.width / 2; // The bottom offset will be filled with the card's padding y = dir === 'top' ? refScrollT - cardRect.height - offset : refScrollB; if (align === 'start') { x = refScrollL; } if (align === 'end') { x = refScrollR - cardRect.width; } } else { // The right offset will be filled with the card's padding x = dir === 'right' ? refScrollR : refScrollL - cardRect.width - offset; y = refScrollT + refRect.height / 2 - cardRect.height / 2; if (align === 'start') { y = refScrollT; } if (align === 'end') { y = refScrollB - cardRect.height; } } card.style.position = 'absolute'; card.style.left = x + "px"; card.style.top = y + "px"; // To bridge the gap between the ref and the hovercard, // ensuring that the hovercard remains visible when the mouse hovers over the gap card.style[paddingMap[dir]] = offset + "px"; } ;// CONCATENATED MODULE: ./src/sanitizer.ts function escHtml(str) { var htmlEntities = { '&': '&amp;', '<': '&lt;', '>': '&gt;', '"': '&quot;', "'": '&#39;', '`': '&#x60;' }; // Don't escape if already escaped. return str.replace(/&(amp|lt|gt|quot|#39|x60);|[\&<>"'`]/g, function (match) { return match[0] === '&' ? match : htmlEntities[match]; }); } function escUrl(url) { return encodeURI(url); } ;// CONCATENATED MODULE: ./src/add-query-arg.ts /** * Adds or updates a query parameter to the given URL. * * @param {string} url - The URL to which the query parameter will be added. * @param {string} key - The query parameter key to add or update. * @param {string} value - The value of the query parameter to add or update. * @return {string} - The updated URL with the new or updated query parameter, or an empty string if the URL is invalid. */ function addQueryArg(url, key, value) { var _url$split = url.split('?'), baseUrl = _url$split[0], queryStr = _url$split[1]; var queryParams = new URLSearchParams(queryStr || ''); queryParams.set(key, value); return baseUrl + "?" + queryParams.toString(); } ;// CONCATENATED MODULE: ./src/i18n.ts function __t(i18n, key) { return i18n[key] || key; } ;// CONCATENATED MODULE: ./src/core.ts var _Hovercards; function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); } var BASE_API_URL = 'https://api.gravatar.com/v3/profiles'; var dc = document; var Hovercards = /*#__PURE__*/function () { function Hovercards(_temp) { var _this = this; var _ref = _temp === void 0 ? {} : _temp, _ref$placement = _ref.placement, placement = _ref$placement === void 0 ? 'right-start' : _ref$placement, _ref$offset = _ref.offset, offset = _ref$offset === void 0 ? 10 : _ref$offset, _ref$autoFlip = _ref.autoFlip, autoFlip = _ref$autoFlip === void 0 ? true : _ref$autoFlip, _ref$autoShift = _ref.autoShift, autoShift = _ref$autoShift === void 0 ? true : _ref$autoShift, _ref$hideOnTargetClic = _ref.hideOnTargetClick, hideOnTargetClick = _ref$hideOnTargetClic === void 0 ? false : _ref$hideOnTargetClic, _ref$delayToShow = _ref.delayToShow, delayToShow = _ref$delayToShow === void 0 ? 500 : _ref$delayToShow, _ref$delayToHide = _ref.delayToHide, delayToHide = _ref$delayToHide === void 0 ? 300 : _ref$delayToHide, _ref$additionalClass = _ref.additionalClass, additionalClass = _ref$additionalClass === void 0 ? '' : _ref$additionalClass, _ref$myHash = _ref.myHash, myHash = _ref$myHash === void 0 ? '' : _ref$myHash, _ref$onQueryHovercard = _ref.onQueryHovercardRef, onQueryHovercardRef = _ref$onQueryHovercard === void 0 ? function (ref) { return ref; } : _ref$onQueryHovercard, _ref$onFetchProfileSt = _ref.onFetchProfileStart, onFetchProfileStart = _ref$onFetchProfileSt === void 0 ? function () {} : _ref$onFetchProfileSt, _ref$onFetchProfileSu = _ref.onFetchProfileSuccess, onFetchProfileSuccess = _ref$onFetchProfileSu === void 0 ? function () {} : _ref$onFetchProfileSu, _ref$onFetchProfileFa = _ref.onFetchProfileFailure, onFetchProfileFailure = _ref$onFetchProfileFa === void 0 ? function () {} : _ref$onFetchProfileFa, _ref$onHovercardShown = _ref.onHovercardShown, onHovercardShown = _ref$onHovercardShown === void 0 ? function () {} : _ref$onHovercardShown, _ref$onHovercardHidde = _ref.onHovercardHidden, onHovercardHidden = _ref$onHovercardHidde === void 0 ? function () {} : _ref$onHovercardHidde, _ref$onCanShowHoverca = _ref.onCanShowHovercard, onCanShowHovercard = _ref$onCanShowHoverca === void 0 ? function () { return true; } : _ref$onCanShowHoverca, _ref$i18n = _ref.i18n, i18n = _ref$i18n === void 0 ? {} : _ref$i18n; // Options this._i18n = {}; // Variables this._hovercardRefs = []; this._showHovercardTimeoutIds = new Map(); this._hideHovercardTimeoutIds = new Map(); this._cachedProfiles = new Map(); /** * Attaches event listeners on or within the target element. * * @param {HTMLElement} target - The target element to set. * @param {Object} [options={}] - The optional parameters. * @param {string} options.dataAttributeName - Data attribute name associated with Gravatar hashes. * @param {string} options.ignoreSelector - The selector to ignore certain elements. * @return {void} */ this.attach = function (target, _temp2) { var _ref2 = _temp2 === void 0 ? {} : _temp2, _ref2$dataAttributeNa = _ref2.dataAttributeName, dataAttributeName = _ref2$dataAttributeNa === void 0 ? 'gravatar-hash' : _ref2$dataAttributeNa, ignoreSelector = _ref2.ignoreSelector; if (!target) { return; } _this.detach(); _this._queryHovercardRefs(target, dataAttributeName, ignoreSelector).forEach(function (hovercardRef) { hovercardRef.ref.addEventListener('mouseenter', hovercardRef.onEnter); hovercardRef.ref.addEventListener('mouseleave', hovercardRef.onLeave); hovercardRef.ref.addEventListener('click', hovercardRef.onClick); }); }; /** * Removes event listeners from hovercard refs and resets the stored list of these refs. * * @return {void} */ this.detach = function () { if (!_this._hovercardRefs.length) { return; } _this._hovercardRefs.forEach(function (hovercardRef) { var _dc$getElementById; hovercardRef.ref.removeEventListener('mouseenter', hovercardRef.onEnter); hovercardRef.ref.removeEventListener('mouseleave', hovercardRef.onLeave); hovercardRef.ref.removeEventListener('click', hovercardRef.onClick); // Clear the hovercard show timeout and remove the hovercard element. clearInterval(_this._showHovercardTimeoutIds.get(hovercardRef.id)); (_dc$getElementById = dc.getElementById(hovercardRef.id)) == null || _dc$getElementById.remove(); }); _this._hovercardRefs = []; }; this._placement = placement; this._offset = offset; this._autoFlip = autoFlip; this._autoShift = autoShift; this._hideOnTargetClick = hideOnTargetClick; this._delayToShow = delayToShow; this._delayToHide = delayToHide; this._additionalClass = additionalClass; this._myHash = myHash; this._onQueryHovercardRef = onQueryHovercardRef; this._onFetchProfileStart = onFetchProfileStart; this._onFetchProfileSuccess = onFetchProfileSuccess; this._onFetchProfileFailure = onFetchProfileFailure; this._onHovercardShown = onHovercardShown; this._onHovercardHidden = onHovercardHidden; this._canShowHovercard = onCanShowHovercard; this._i18n = i18n; } /** * Queries hovercard refs on or within the target element. * * @param {HTMLElement} target - The element to query. * @param {string} dataAttributeName - Data attribute name associated with Gravatar hashes. * @param {string} [ignoreSelector] - The selector to ignore certain elements. * @return {HovercardRef[]} - The queried hovercard refs. * @private */ var _proto = Hovercards.prototype; _proto._queryHovercardRefs = function _queryHovercardRefs(target, dataAttributeName, ignoreSelector) { var _this2 = this; var refs = []; var camelAttrName = dataAttributeName.replace(/-([a-z])/g, function (g) { return g[1].toUpperCase(); }); var ignoreRefs = ignoreSelector ? Array.from(dc.querySelectorAll(ignoreSelector)) : []; var matchPath = 'gravatar.com/avatar/'; if (camelAttrName && target.dataset[camelAttrName] || target.tagName === 'IMG' && target.src.includes(matchPath)) { refs = [target]; } else { refs = Array.from(target.querySelectorAll("img[src*=\"" + matchPath + "\"]")); if (dataAttributeName) { refs = [].concat(refs.filter(function (img) { return !img.hasAttribute("data-" + dataAttributeName); }), Array.from(target.querySelectorAll("[data-" + dataAttributeName + "]"))); } } this._hovercardRefs = refs.map(function (ref, idx) { if (ignoreRefs.includes(ref)) { return null; } var hash; var params; var dataAttrValue = ref.dataset[camelAttrName]; if (dataAttrValue) { var part = dataAttrValue.split('?'); hash = part[0]; params = part.length > 1 ? part[1] : ''; } else if (ref.tagName === 'IMG') { var _part = ref.src.split('/').pop().split('?'); hash = _part[0]; params = _part.length > 1 ? _part[1] : ''; } if (!hash) { return null; } var p = new URLSearchParams(params); var d = p.get('d') || p.get('default'); var f = p.get('f') || p.get('forcedefault'); var r = p.get('r') || p.get('rating'); var initials = p.get('initials'); var name = p.get('name'); var txtColor = p.get('txt_color'); var bgColor = p.get('bg_color'); params = [d && "d=" + d, f && "f=" + f, r && "r=" + r, initials && "initials=" + initials, name && "name=" + name, txtColor && "txt_color=" + txtColor, bgColor && "bg_color=" + bgColor].filter(Boolean).join('&'); return { id: "gravatar-hovercard-" + hash + "-" + idx, hash: hash, params: params ? "?" + params : '', ref: _this2._onQueryHovercardRef(ref) || ref }; }).filter(Boolean).map(function (hovercardRef) { return _extends({}, hovercardRef, { onEnter: function onEnter(e) { return _this2._handleMouseEnter(e, hovercardRef); }, onLeave: function onLeave(e) { return _this2._handleMouseLeave(e, hovercardRef); }, onClick: function onClick() { return _this2._handleMouseClick(hovercardRef); } }); }); return this._hovercardRefs; } /** * Creates a hovercard element with the provided profile data. * * @param {ProfileData} profileData - The profile data to populate the hovercard. * @param {Object} [options] - Optional parameters for the hovercard. * @param {string} [options.additionalClass] - Additional CSS class for the hovercard. * @param {string} [options.myHash] - The hash of the current user. * @param {Object} [options.i18n] - The i18n object. * @return {HTMLDivElement} - The created hovercard element. */; /** * Creates a hovercard drawer. * * @param {string} name - The drawer name. * @param {string} titleText - The title shown at the drawer's header. * @param {string} content - The drawer inner content. * @return {string} - The drawer HTML string. * @private */ Hovercards._createDrawer = function _createDrawer(name, titleText, content) { return "\n\t\t\t<div class=\"gravatar-hovercard__drawer\" data-drawer-name=\"" + name + "\">\n\t\t\t\t<div class=\"gravatar-hovercard__drawer-backdrop\" data-target-drawer=\"" + name + "\"></div>\n\t\t\t\t<div class=\"gravatar-hovercard__drawer-card\">\n\t\t\t\t\t<div class=\"gravatar-hovercard__drawer-header\">\n\t\t\t\t\t\t<h2 class=\"gravatar-hovercard__drawer-title\">" + titleText + "</h2>\n\t\t\t\t\t\t<button class=\"gravatar-hovercard__drawer-close\" data-target-drawer=\"" + name + "\">\n\t\t\t\t\t\t\t<svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n\t\t\t\t\t\t\t\t<path d=\"M12 13.0607L15.7123 16.773L16.773 15.7123L13.0607 12L16.773 8.28772L15.7123 7.22706L12 10.9394L8.28771 7.22705L7.22705 8.28771L10.9394 12L7.22706 15.7123L8.28772 16.773L12 13.0607Z\" fill=\"#101517\"></path>\n\t\t\t\t\t\t\t</svg>\n\t\t\t\t\t\t</button>\n\t\t\t\t\t</div>\n\t\t\t\t\t<ul class=\"gravatar-hovercard__drawer-items\">\n\t\t\t\t\t\t" + content + "\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t"; } /** * Opens a hovercard drawer. * * @param {HTMLElement} target - The target drawer. * @param {HTMLElement} container - The container context to search for the drawer. * @return {void} * @private */; Hovercards._openDrawer = function _openDrawer(target, container) { var drawer = container.querySelector(".gravatar-hovercard__drawer[data-drawer-name=\"" + target.dataset.targetDrawer + "\"]"); if (!drawer) { return; } drawer.classList.add('gravatar-hovercard__drawer--open'); } /** * Closes a hovercard drawer. * * @param {HTMLElement} target - The drawer selector. * @param {HTMLElement} container - The container context to search for the drawer. * @return {void} * @private */; Hovercards._closeDrawer = function _closeDrawer(target, container) { var drawer = container.querySelector(".gravatar-hovercard__drawer[data-drawer-name=\"" + target.dataset.targetDrawer + "\"]"); if (!drawer) { return; } drawer.classList.add('gravatar-hovercard__drawer--closing'); drawer.classList.remove('gravatar-hovercard__drawer--open'); setTimeout(function () { drawer.classList.remove('gravatar-hovercard__drawer--closing'); }, 300); } /** * Creates the contact drawer content. * * @param {Record< string, any >[]} contactsData - The user's contact data. * @param {Object} [options] - Optional parameters for the contact drawer. * @param {Record<string, string>} [options.i18n] - The i18n object. * @return {string} - The contact drawer content. * @private */; Hovercards._createContactDrawerContent = function _createContactDrawerContent(contactsData, _temp3) { var _ref3 = _temp3 === void 0 ? {} : _temp3, _ref3$i18n = _ref3.i18n, i18n = _ref3$i18n === void 0 ? {} : _ref3$i18n; var icons = { email: 'icons/mail.svg', home_phone: 'icons/home-phone.svg', work_phone: 'icons/work-phone.svg', cell_phone: 'icons/mobile-phone.svg', contact_form: 'icons/envelope.svg', calendar: 'icons/calendar.svg', calendly: 'icons/calendly.svg' }; var labels = { email: __t(i18n, 'Email'), home_phone: __t(i18n, 'Home Phone'), work_phone: __t(i18n, 'Work Phone'), cell_phone: __t(i18n, 'Cell Phone'), contact_form: __t(i18n, 'Contact Form'), calendar: __t(i18n, 'Calendar') }; var getUrl = function getUrl(type, value) { switch (type) { case 'email': return "mailto:" + value; case 'contact_form': case 'calendar': case 'calendly': return value.startsWith('http') ? value : "https://" + value; default: return null; } }; var items = contactsData.map(function (_ref4) { var _labels$key; var key = _ref4[0], value = _ref4[1]; var url = getUrl(key, value); var text = value.replace(/^(https?:\/\/)?(www\.)?/, ''); text = text.endsWith('/') ? text.slice(0, -1) : text; if (url) { text = "<a class=\"gravatar-hovercard__drawer-item-link\" href=\"" + url + "\" target=\"_blank\">" + text + "</a>"; } return "\n\t\t\t\t<li class=\"gravatar-hovercard__drawer-item\">\n\t\t\t\t\t<img\n\t\t\t\t\t\tclass=\"gravatar-hovercard__drawer-item-icon\"\n\t\t\t\t\t\twidth=\"24\"\n\t\t\t\t\t\theight=\"24\"\n\t\t\t\t\t\tsrc=\"https://s.gravatar.com/" + icons[key] + "\"\n\t\t\t\t\t\talt=\"\"\n\t\t\t\t\t>\n\t\t\t\t\t<div class=\"gravatar-hovercard__drawer-item-info\">\n\t\t\t\t\t\t<span class=\"gravatar-hovercard__drawer-item-label\">" + ((_labels$key = labels[key]) != null ? _labels$key : key.replace('_', ' ')) + "</span>\n\t\t\t\t\t\t<span class=\"gravatar-hovercard__drawer-item-text\">" + text + "</span>\n\t\t\t\t\t</div>\n\t\t\t\t</li>\n\t\t\t"; }); return items.join(''); } /** * Creates the send money drawer content. * * @param {Payments} payments - The user's payment data. * @return {string} - The send money drawer content. * @private */; Hovercards._createSendMoneyDrawerContent = function _createSendMoneyDrawerContent(payments) { var _payments$links, _payments$crypto_wall; var items = []; (_payments$links = payments.links) == null || _payments$links.forEach(function (item) { items.push("\n\t\t\t\t<li class=\"gravatar-hovercard__drawer-item\">\n\t\t\t\t\t<img class=\"gravatar-hovercard__drawer-item-icon\" width=\"24\" height=\"24\" src=\"https://s.gravatar.com/icons/link.svg\" alt=\"\">\n\t\t\t\t\t<div class=\"gravatar-hovercard__drawer-item-info\">\n\t\t\t\t\t\t<span class=\"gravatar-hovercard__drawer-item-label\">" + item.label + "</span>\n\t\t\t\t\t\t<span class=\"gravatar-hovercard__drawer-item-text\">\n\t\t\t\t\t\t\t<a class=\"gravatar-hovercard__drawer-item-link\" href=\"" + item.url + "\" target=\"_blank\">\n\t\t\t\t\t\t\t\t" + item.url.replace(/^(https?:\/\/)/, '') + "\n\t\t\t\t\t\t\t</a>\n\t\t\t\t\t\t</span>\n\t\t\t\t\t</div>\n\t\t\t\t</li>\n\t\t\t"); }); (_payments$crypto_wall = payments.crypto_wallets) == null || _payments$crypto_wall.forEach(function (item) { items.push("\n\t\t\t\t<li class=\"gravatar-hovercard__drawer-item\">\n\t\t\t\t\t<img class=\"gravatar-hovercard__drawer-item-icon\" width=\"24\" height=\"24\" src=\"https://s.gravatar.com/icons/link.svg\" alt=\"\">\n\t\t\t\t\t<div class=\"gravatar-hovercard__drawer-item-info\">\n\t\t\t\t\t\t<span class=\"gravatar-hovercard__drawer-item-label\">" + item.label + "</span>\n\t\t\t\t\t\t<span class=\"gravatar-hovercard__drawer-item-text\">" + item.address + "</span>\n\t\t\t\t\t</div>\n\t\t\t\t</li>\n\t\t\t"); }); return items.join(''); } /** * Creates a skeleton hovercard element. * * @param {Object} [options] - Optional parameters for the skeleton hovercard. * @param {string} [options.additionalClass] - Additional CSS class for the skeleton hovercard. * @return {HTMLDivElement} - The created skeleton hovercard element. */; /** * Waits for a specified delay and fetches the user's profile data, * then shows the hovercard relative to the ref element. * * @param {HovercardRef} hovercardRef - The hovercard ref object. * @return {void} * @private */ _proto._showHovercard = function _showHovercard(_ref5) { var _this3 = this; var id = _ref5.id, hash = _ref5.hash, params = _ref5.params, ref = _ref5.ref; var timeoutId = setTimeout(function () { if (dc.getElementById(id)) { return; } // Let client decide if we can show the hovercard if (!_this3._canShowHovercard(hash)) { return; } var urlParams = new URLSearchParams(params); urlParams["delete"]('size'); urlParams.set('s', '256'); params = "?" + urlParams.toString(); var hovercard; var positionOptions = { placement: _this3._placement, offset: _this3._offset, autoFlip: _this3._autoFlip, autoShift: _this3._autoShift }; if (_this3._cachedProfiles.has(hash)) { var profile = _this3._cachedProfiles.get(hash); hovercard = Hovercards.createHovercard(_extends({}, profile, { avatarUrl: profile.avatarUrl + params }), { additionalClass: _this3._additionalClass, myHash: _this3._myHash, i18n: _this3._i18n }); _this3._onHovercardShown(hash, hovercard); } else { hovercard = Hovercards.createHovercardSkeleton({ additionalClass: _this3._additionalClass }); _this3._onFetchProfileStart(hash); fetch(addQueryArg(BASE_API_URL + "/" + hash, 'source', 'hovercard')).then(function (res) { // API error handling if (res.status !== 200) { throw res.status; } return res.json(); }).then(function (data) { var _data$verified_accoun; _this3._cachedProfiles.set(hash, { hash: data.hash, avatarUrl: data.avatar_url, profileUrl: data.profile_url, displayName: data.display_name, location: data.location, description: data.description, jobTitle: data.job_title, company: data.company, headerImage: data.header_image, hideDefaultHeaderImage: data.hide_default_header_image, backgroundColor: data.background_color, verifiedAccounts: (_data$verified_accoun = data.verified_accounts) == null ? void 0 : _data$verified_accoun.map(function (account) { return { type: account.service_type, label: account.service_label, icon: account.service_icon, url: account.url, isHidden: account.is_hidden }; }), contactInfo: data.contact_info, payments: data.payments }); var profile = _this3._cachedProfiles.get(hash); var hovercardInner = Hovercards.createHovercard(_extends({}, profile, { avatarUrl: profile.avatarUrl + params }), { additionalClass: _this3._additionalClass, myHash: _this3._myHash, i18n: _this3._i18n }).firstElementChild; hovercard.classList.remove('gravatar-hovercard--skeleton'); hovercard.replaceChildren(hovercardInner); // Recalculate the hovercard position after fetching the user data assignPosition(ref, hovercard, positionOptions); _this3._onFetchProfileSuccess(hash, _this3._cachedProfiles.get(hash)); _this3._onHovercardShown(hash, hovercard); })["catch"](function (code) { var message = __t(_this3._i18n, 'Sorry, we are unable to load this Gravatar profile.'); switch (code) { case 403: message = __t(_this3._i18n, 'This profile is private.'); break; case 404: message = __t(_this3._i18n, 'Gravatar not found.'); break; case 429: message = __t(_this3._i18n, 'Too Many Requests.'); break; case 500: message = __t(_this3._i18n, 'Internal Server Error.'); break; } var additionalMessage = code === 404 ? "\n\t\t\t\t\t\t\t\t<i class=\"gravatar-hovercard__error-message gravatar-hovercard__error-message--claim-gravatar\">\n\t\t\t\t\t\t\t\t\t" + __t(_this3._i18n, 'Is this you?') + " \n\t\t\t\t\t\t\t\t\t<a href=\"https://gravatar.com/signup?utm_source=hovercard\" target=\"_blank\">\n\t\t\t\t\t\t\t\t\t\t" + __t(_this3._i18n, 'Claim your free profile.') + "\n\t\t\t\t\t\t\t\t\t</a>\n\t\t\t\t\t\t\t\t</i>\n\t\t\t\t\t\t\t\t" : ''; var hovercardInner = Hovercards.createHovercardError("https://0.gravatar.com/avatar/" + hash + params, message, { additionalClass: _this3._additionalClass, additionalMessage: additionalMessage }).firstElementChild; hovercard.classList.add('gravatar-hovercard--error'); hovercard.classList.remove('gravatar-hovercard--skeleton'); hovercard.replaceChildren(hovercardInner); _this3._onFetchProfileFailure(hash, { code: code, message: message }); }); } // Set the hovercard ID here to avoid the show / hide side effect hovercard.id = id; // Don't hide the hovercard when the mouse is over the hovercard from the ref hovercard.addEventListener('mouseenter', function () { return clearInterval(_this3._hideHovercardTimeoutIds.get(id)); }); hovercard.addEventListener('mouseleave', function () { return _this3._hideHovercard(id); }); // Placing the hovercard at the top-level of the document to avoid being clipped by overflow dc.body.appendChild(hovercard); assignPosition(ref, hovercard, positionOptions); }, this._delayToShow); this._showHovercardTimeoutIds.set(id, timeoutId); } /** * Waits for a specified delay and hides the hovercard. * * @param {string} id - The ID associated with the hovercard. * @param {number} [delay] - The delay in milliseconds before hiding the hovercard. * @return {void} * @private */; _proto._hideHovercard = function _hideHovercard(id, delay) { var _this4 = this; if (delay === void 0) { delay = this._delayToHide; } var timeoutId = setTimeout(function () { var hovercard = dc.getElementById(id); if (hovercard) { hovercard.remove(); _this4._onHovercardHidden(id, hovercard); } }, delay); this._hideHovercardTimeoutIds.set(id, timeoutId); } /** * Handles the mouseenter event for hovercard refs. * * @param {MouseEvent} e - The mouseenter event object. * @param {HovercardRef} hovercardRef - The hovercard ref object. * @return {void} * @private */; _proto._handleMouseEnter = function _handleMouseEnter(e, hovercardRef) { if ('ontouchstart' in dc) { return; } e.stopImmediatePropagation(); // Don't hide the hovercard when the mouse is over the ref from the hovercard clearInterval(this._hideHovercardTimeoutIds.get(hovercardRef.id)); this._showHovercard(hovercardRef); } /** * Handles the mouseleave event for hovercard refs. * * @param {MouseEvent} e - The mouseleave event object. * @param {HovercardRef} hovercardRef - The hovercard ref object. * @param {string} hovercardRef.id - The ID associated with the hovercard. * @return {void} * @private */; _proto._handleMouseLeave = function _handleMouseLeave(e, _ref6) { var id = _ref6.id; if ('ontouchstart' in dc) { return; } e.stopImmediatePropagation(); clearInterval(this._showHovercardTimeoutIds.get(id)); this._hideHovercard(id); } /** * Handles the click event for hovercard refs. * * @param {HovercardRef} hovercardRef - The hovercard ref object. * @param {string} hovercardRef.id - The ID associated with the hovercard. * @return {void} * @private */; _proto._handleMouseClick = function _handleMouseClick(_ref7) { var id = _ref7.id; if ('ontouchstart' in dc || !this._hideOnTargetClick) { return; } clearInterval(this._showHovercardTimeoutIds.get(id)); this._hideHovercard(id, 0); }; return Hovercards; }(); _Hovercards = Hovercards; Hovercards.createHovercard = function (profileData, _temp4) { var _payments$links2, _payments$crypto_wall2; var _ref8 = _temp4 === void 0 ? {} : _temp4, additionalClass = _ref8.additionalClass, myHash = _ref8.myHash, _ref8$i18n = _ref8.i18n, i18n = _ref8$i18n === void 0 ? {} : _ref8$i18n; var hash = profileData.hash, avatarUrl = profileData.avatarUrl, profileUrl = profileData.profileUrl, displayName = profileData.displayName, location = profileData.location, description = profileData.description, jobTitle = profileData.jobTitle, company = profileData.company, headerImage = profileData.headerImage, hideDefaultHeaderImage = profileData.hideDefaultHeaderImage, _profileData$verified = profileData.verifiedAccounts, verifiedAccounts = _profileData$verified === void 0 ? [] : _profileData$verified, payments = profileData.payments, contactInfo = profileData.contactInfo, backgroundColor = profileData.backgroundColor; var hovercard = dc.createElement('div'); hovercard.className = "gravatar-hovercard" + (additionalClass ? " " + additionalClass : ''); var calendly = verifiedAccounts.find(function (account) { return account.type === 'calendly' && !account.isHidden; }); if (contactInfo && calendly) { contactInfo.calendly = calendly.url; } var trackedProfileUrl = escUrl(addQueryArg(profileUrl, 'utm_source', 'hovercard')); var username = escHtml(displayName); var isEditProfile = !description && myHash === hash; var jobInfo = [jobTitle, company].filter(Boolean).join(', '); var hasPayments = (payments == null || (_payments$links2 = payments.links) == null ? void 0 : _payments$links2.length) || (payments == null || (_payments$crypto_wall2 = payments.crypto_wallets) == null ? void 0 : _payments$crypto_wall2.length); var nonEmptyContacts = Object.entries(contactInfo || {}).filter(function (_ref9) { var _ = _ref9[0], value = _ref9[1]; return !!value; }); var renderSocialLinks = verifiedAccounts.slice(0, 3).reduce(function (links, _ref10) { var label = _ref10.label, icon = _ref10.icon, url = _ref10.url, type = _ref10.type, isHidden = _ref10.isHidden; if (isHidden) { return links; } links.push("\n\t\t\t\t\t<a class=\"gravatar-hovercard__social-link\" href=\"" + escUrl(url) + "\" target=\"_blank\" data-service-name=\"" + type + "\">\n\t\t\t\t\t\t<img class=\"gravatar-hovercard__social-icon\" src=\"" + escUrl(icon) + "\" width=\"32\" height=\"32\" alt=\"" + escHtml(label) + "\" />\n\t\t\t\t\t</a>\n\t\t\t\t"); return links; }, []).join(''); var headerImageHtml = ''; var ctaButtons = ''; var contactsDrawer = ''; var sendMoneyDrawer = ''; if (headerImage || !hideDefaultHeaderImage) { var img = "<img class=\"gravatar-hovercard__header-image-img\" src=\"" + escUrl(avatarUrl) + "\" alt=\"\"/>"; headerImageHtml = "<div class=\"gravatar-hovercard__header-image\">" + (!headerImage ? img : '') + "</div>"; } if (nonEmptyContacts.length || hasPayments) { if (nonEmptyContacts.length) { ctaButtons += "\n\t\t\t\t\t<button class=\"gravatar-hovercard__button\" data-target-drawer=\"contact\">" + __t(i18n, 'Contact') + "</button>\n\t\t\t\t"; contactsDrawer = _Hovercards._createDrawer('contact', __t(i18n, 'Contact'), _Hovercards._createContactDrawerContent(nonEmptyContacts, { i18n: i18n })); } if (hasPayments) { ctaButtons += "\n\t\t\t\t\t<button class=\"gravatar-hovercard__button\" data-target-drawer=\"send-money\">" + __t(i18n, 'Send money') + "</button>\n\t\t\t\t"; sendMoneyDrawer = _Hovercards._createDrawer('send-money', __t(i18n, 'Send money'), _Hovercards._createSendMoneyDrawerContent(payments)); } ctaButtons = "\n\t\t\t\t<div class=\"gravatar-hovercard__buttons\">" + ctaButtons + "</div>\n\t\t\t"; } hovercard.innerHTML = "\n\t\t\t<div class=\"gravatar-hovercard__inner\">\n\t\t\t\t" + headerImageHtml + "\n\t\t\t\t<div class=\"gravatar-hovercard__header\">\n\t\t\t\t\t<a class=\"gravatar-hovercard__avatar-link\" href=\"" + trackedProfileUrl + "\" target=\"_blank\">\n\t\t\t\t\t\t<img class=\"gravatar-hovercard__avatar\" src=\"" + escUrl(avatarUrl) + "\" width=\"104\" height=\"104\" alt=\"" + username + "\" />\n\t\t\t\t\t</a>\n\t\t\t\t\t<a class=\"gravatar-hovercard__personal-info-link\" href=\"" + trackedProfileUrl + "\" target=\"_blank\">\n\t\t\t\t\t\t<h4 class=\"gravatar-hovercard__name\">" + username + "</h4>\n\t\t\t\t\t\t" + (jobInfo ? "<p class=\"gravatar-hovercard__job\">" + escHtml(jobInfo) + "</p>" : '') + "\n\t\t\t\t\t\t" + (location ? "<p class=\"gravatar-hovercard__location\">" + escHtml(location) + "</p>" : '') + "\n\t\t\t\t\t</a>\n\t\t\t\t</div>\n\t\t\t\t" + (description ? "<div class=\"gravatar-hovercard__body\">\n\t\t\t\t\t\t\t\t<p class=\"gravatar-hovercard__description\">" + escHtml(description) + "</p>\n\t\t\t\t\t\t\t</div>" : '') + "\n\t\t\t\t<div class=\"gravatar-hovercard__social-links\">\n\t\t\t\t\t<a class=\"gravatar-hovercard__social-link\" href=\"" + trackedProfileUrl + "\" target=\"_blank\" data-service-name=\"gravatar\">\n\t\t\t\t\t\t<img class=\"gravatar-hovercard__social-icon\" src=\"https://s.gravatar.com/icons/gravatar.svg\" width=\"32\" height=\"32\" alt=\"Gravatar\" />\n\t\t\t\t\t</a>\n\t\t\t\t\t" + renderSocialLinks + "\n\t\t\t\t</div>\n\t\t\t\t" + ctaButtons + "\n\t\t\t\t<div class=\"gravatar-hovercard__footer\">\n\t\t\t\t\t<a class=\"gravatar-hovercard__profile-url\" title=\"" + profileUrl + "\" href=\"" + trackedProfileUrl + "\" target=\"_blank\">\n\t\t\t\t\t\t" + profileUrl.replace('https://', '') + "\n\t\t\t\t\t</a>\n\t\t\t\t\t<a\n\t\t\t\t\t\tclass=\"gravatar-hovercard__profile-link" + (isEditProfile ? ' gravatar-hovercard__profile-link--edit' : '') + "\"\n\t\t\t\t\t\thref=\"" + (isEditProfile ? 'https://gravatar.com/profiles/edit?utm_source=hovercard' : trackedProfileUrl) + "\"\n\t\t\t\t\t\ttarget=\"_blank\"\n\t\t\t\t\t>\n\t\t\t\t\t\t" + (isEditProfile ? __t(i18n, 'Edit your profile →') : __t(i18n, 'View profile →')) + "\n\t\t\t\t\t</a>\n\t\t\t\t</div>\n\t\t\t\t" + contactsDrawer + "\n\t\t\t\t" + sendMoneyDrawer + "\n\t\t\t\t" + (backgroundColor ? '<div class="gravatar-hovercard__profile-color"></div>' : '') + "\n\t\t\t</div>\n\t\t"; var hovercardInner = hovercard.querySelector('.gravatar-hovercard__inner'); var headerImageEl = hovercardInner.querySelector('.gravatar-hovercard__header-image'); var profileColorEl = hovercardInner.querySelector('.gravatar-hovercard__profile-color'); if (headerImage && headerImageEl) { headerImageEl.style.background = headerImage; } if (backgroundColor && profileColorEl) { profileColorEl.style.background = backgroundColor; } hovercardInner.querySelectorAll('.gravatar-hovercard__button').forEach(function (el) { el.addEventListener('click', function () { return _Hovercards._openDrawer(el, hovercardInner); }); }); hovercardInner.querySelectorAll('.gravatar-hovercard__drawer-close').forEach(function (el) { el.addEventListener('click', function () { return _Hovercards._closeDrawer(el, hovercardInner); }); }); hovercardInner.querySelectorAll('.gravatar-hovercard__drawer-backdrop').forEach(function (el) { el.addEventListener('click', function () { return _Hovercards._closeDrawer(el, hovercardInner); }); }); return hovercard; }; Hovercards.createHovercardSkeleton = function (_temp5) { var _ref11 = _temp5 === void 0 ? {} : _temp5, additionalClass = _ref11.additionalClass; var hovercard = dc.createElement('div'); hovercard.className = "gravatar-hovercard gravatar-hovercard--skeleton" + (additionalClass ? " " + additionalClass : ''); hovercard.innerHTML = "\n\t\t\t<div class=\"gravatar-hovercard__inner\">\n\t\t\t\t<div class=\"gravatar-hovercard__header\">\n\t\t\t\t\t<div class=\"gravatar-hovercard__avatar-link\"></div>\n\t\t\t\t\t<div class=\"gravatar-hovercard__personal-info-link\"></div>\n\t\t\t\t</div>\n\t\t\t\t<div class=\"gravatar-hovercard__social-links\">\n\t\t\t\t\t<div class=\"gravatar-hovercard__social-link\"></div>\n\t\t\t\t\t<div class=\"gravatar-hovercard__social-link\"></div>\n\t\t\t\t</div>\n\t\t\t\t<div class=\"gravatar-hovercard__footer\">\n\t\t\t\t\t<div class=\"gravatar-hovercard__profile-url\"></div>\n\t\t\t\t\t<div class=\"gravatar-hovercard__profile-link\"></div>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t"; return hovercard; }; /** * Creates an error hovercard element. * * @param {string} avatarUrl - The URL of the avatar image. * @param {string} message - The error message to display. * @param {Object} [options] - Optional parameters for the error hovercard. * @param {string} [options.avatarAlt] - The alt text for the avatar image. * @param {string} [options.additionalClass] - Additional CSS class for the error hovercard. * @param {string} [options.additionalMessage] - Additional message to display in the error hovercard. * @return {HTMLDivElement} - The created error hovercard element. */ Hovercards.createHovercardError = function (avatarUrl, message, _temp6) { var _ref12 = _temp6 === void 0 ? {} : _temp6, _ref12$avatarAlt = _ref12.avatarAlt, avatarAlt = _ref12$avatarAlt === void 0 ? 'Avatar' : _ref12$avatarAlt, additionalClass = _ref12.additionalClass, _ref12$additionalMess = _ref12.additionalMessage, additionalMessage = _ref12$additionalMess === void 0 ? '' : _ref12$additionalMess; var hovercard = dc.createElement('div'); hovercard.className = "gravatar-hovercard gravatar-hovercard--error" + (additionalClass ? " " + additionalClass : ''); hovercard.innerHTML = "\n\t\t\t<div class=\"gravatar-hovercard__inner\">\n\t\t\t\t<img class=\"gravatar-hovercard__avatar\" src=\"" + avatarUrl + "\" width=\"104\" height=\"104\" alt=\"" + avatarAlt + "\" />\n\t\t\t\t<div class=\"gravatar-hovercard__error-message-wrapper\">\n\t\t\t\t\t<i class=\"gravatar-hovercard__error-message\">" + message + "</i>\n\t\t\t\t\t" + additionalMessage + "\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t"; return hovercard; }; ;// CONCATENATED MODULE: ./src/index.ts var __webpack_exports__Hovercards = __webpack_exports__.S; export { __webpack_exports__Hovercards as Hovercards }; //# sourceMappingURL=index.mjs.map