UNPKG

@sheerid/jslib-nightly

Version:

SheerID JavaScript Library

397 lines (395 loc) • 14.3 kB
/** * VERSION: 2.113.0-alpha.0 * BUILD_TIMESTAMP: 1750184630462 * BUILD_DATE: Tue Jun 17 2025 18:23:50 GMT+0000 (Coordinated Universal Time) * BUILD_COMMIT: 896154e79f58fffa6d52f3ed37f2db760a63df88 */ var S = Object.defineProperty; var T = (i, e, t) => e in i ? S(i, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : i[e] = t; var s = (i, e, t) => T(i, typeof e != "symbol" ? e + "" : e, t); const _ = "installPageUrl", M = "installType", y = { INLINE_IFRAME_CONTENT: "sid-inline-iframe", MODAL_WRAPPER: "sid-modal__wrapper", MODAL_IFRAME: "sid-modal__iframe", OVERLAY: "sid-modal__overlay", CLOSE_BUTTON: "sid-modal__close-button", CLOSE_TEXT: "sid-modal__close-text", CLOSE_ICON: "sid-modal__close-icon" }, b = "SheerID Verification Form", c = { CLASS_NAMES: y, DEFAULT_MOBILE_THRESHOLD_WIDTH: 620, MODAL_OPACITY_TRANSITION_PERIOD: 300 }, O = {}, N = async () => O, R = () => window.navigator.globalPrivacyControl, h = () => window.NREUM && !R(); function a(i, e) { try { return i(); } catch { return e; } } let f = 4, l = ""; const L = { info: 1, log: 2, warn: 3, error: 4 }, m = { info: "#26c1db", log: "#09f979", warn: "#f6b13f", error: "#e12046" }, p = "color: white; font-weight: bold; padding: 2px 10px;"; let u; const P = (i) => i && i.stack && i.message, E = (...i) => { f <= 3 && console.warn(`%c${l} warn`, `background: ${m.warn};${p}`, ...i); }, C = (...i) => { f <= 2 && console.log(`%c${l} log`, `background: ${m.log};${p}`, ...i); }, $ = (...i) => { f <= 1 && console.log(`%c${l} info`, `background: ${m.info};${p}`, ...i); }, D = async (i, e = "unknown group", t = {}) => { if (f <= 4) { if (!i) { console.error(new Error("An error must be supplied")); return; } let n; typeof i == "string" && (n = new Error(i)), P(i) && (n = i), n || (n = new Error("Unknown error")); let o = { errorMessageGroup: e }; try { o = { ...await N(), ...o }, delete o.jslibVersionActual; } catch (r) { h() ? window.NREUM.noticeError(n, o) : E("Unable to assemble GA error attributes", r); } try { if (u && u.getState) { const r = u.getState(), I = a(() => r.verificationResponse.errorIds); o = { ...o, programId: a(() => r.programId), isLoading: a(() => r.isLoading), isErrored: a(() => r.isErrored), errorIdsFromVerRsp: Array.isArray(I) ? I.join(", ") : void 0, verificationId: a(() => r.verificationResponse.verificationId), currentStep: a(() => r.verificationResponse.currentStep), locale: a(() => r.programTheme.intl.locale), isTestMode: a(() => r.programTheme.isTestMode), openOrgSearchEnabled: a(() => r.programTheme.openOrgSearchEnabled), jslibVerActual: a(() => "2.113.0-alpha.0", "?"), ...t }; } } catch (r) { h() ? window.NREUM.noticeError(n, o) : E("Unable to assemble useful error attributes", r); } h() && window.NREUM.noticeError(n, o), console.error( `%c${l} error`, `background: ${m.error};${p}`, n, o ); } }, x = (i, e = {}) => { h() && window.NREUM.addPageAction(i, e); }, B = (i, e) => { x("API-calls-timing", { api_call: i, api_response_time: e }); }, v = { error: D, warn: E, log: C, info: $, /** @deprecated use newRelicPageAction() instead */ logAPIResponseTime: B, setLogLevel: (i) => { if (!L.hasOwnProperty(i)) throw new Error(`Unknown logLevel '${i}'`); f = L[i], console.log( `%c${l} log level set to ${i}`, `background: ${m[i]};${p}` ), h() || E("Offsite logging not enabled"); }, setPrefix: (i) => { l = i; }, init: (i) => { u = i; } }, W = (i) => { i.forEach((e) => { e.classList.add("fade-in"); }); }, g = (i, e) => { i.classList.remove("fade-in"), window.setTimeout(() => { document.body.style.overflow = "auto", i.parentNode.removeChild(i); }, e); }, U = (i) => { const e = new URL(i); return new URL(window.location.href).searchParams.forEach((n, o) => { e.searchParams.has(o) || e.searchParams.set(o, n); }), e.href; }; class k { constructor() { s(this, "subscribers", /* @__PURE__ */ new Set()); } sub(e) { return this.subscribers.add(e), () => this.subscribers.delete(e); } pub(e) { this.subscribers.forEach((t) => t(e)); } } class F { constructor() { s(this, "events", /* @__PURE__ */ new Map()); } /** * Registers a listener that will be called when the named event is emitted * @returns An unsubscribe function that will turn off this listener. */ on(e, t) { return this.events.has(e) || this.events.set(e, new k()), this.events.get(e).sub(t); } /** * Registers a listener that will be called a single time when the named event * is emitted * @returns An unsubscribe function that will turn off this listener. */ once(e, t) { const n = this.on(e, (o) => (n(), t(o))); return n; } /** * Removes all event listeners for the given key * @returns void */ off(e) { this.events.delete(e); } /** * Used to emit events to all registered hook listeners * * @private */ emit(e, t) { this.events.has(e) && this.events.get(e).pub(t); } } const A = { className: c.CLASS_NAMES.INLINE_IFRAME_CONTENT, title: b }, H = (i) => { if (typeof i != "function") throw new Error(`Expected type "function", but received ${typeof i}`); }; class d extends F { constructor(t, n) { super(); s(this, "containerElement"); s(this, "verificationUrl"); s(this, "isMobileDevice"); s(this, "iframe"); s(this, "verificationIframeUid"); s(this, "hasLoaded", !1); s(this, "onLoadEvents", []); s(this, "onCleanupEvents", []); s(this, "installType", "cdn_inline_iframe"); d.isValidHttpUrl(n) ? (this.containerElement = t, this.verificationUrl = new URL(U(n)), this.verificationIframeUid = d.createUniqueId()) : v.error("Invalid URL. Provide a proper URL: https://example.com/", "iframe url"); } cleanup() { this.onCleanupEvents.forEach((t) => t()); } static createUniqueId() { return Math.random().toString(36).substr(2, 9); } static isValidHttpUrl(t) { try { const n = new URL(t); return n.protocol === "http:" || n.protocol === "https:"; } catch { return !1; } } createIframe(t) { this.iframe = document.createElement("iframe"), this.iframe.classList.add(t.className), this.iframe.title = t.title; let n = "?"; return this.verificationUrl.search && (n = "&"), this.iframe.src = `${this.verificationUrl.href}${n}verificationIframeUid=${this.verificationIframeUid}&${_}=${encodeURIComponent( window.location.href )}&${M}=${this.installType}`, this.iframe.allow = "camera *;microphone *;geolocation *;clipboard-read *;clipboard-write *", this.iframe.onload = () => this.onLoad(), this.iframe; } // If iFrame hasn't loaded yet, queue up the callback // otherwise call it immediately addOnLoadEvent(t) { try { H(t); } catch { v.error("Invalid callback provided to iFrame.onLoad()", "iframe addOnLoadEvent"); return; } this.hasLoaded ? t() : this.onLoadEvents.push(t); } onLoad() { this.hasLoaded = !0, this.onLoadEvents.forEach((t) => t()); } /** * Using this to add parent window message listeners gives us * - Event Cleanup for modals * - verification of origin, verificationIframeUid, and message data structure */ addWindowMessageListener(t) { const n = (o) => { this.verificationUrl.origin === o.origin && o.data.verificationIframeUid === this.verificationIframeUid && (o.data.action && o.data.action.type ? t(o.data.action) : o.data.action && o.data.height && t(o.data)); }; window.addEventListener("message", n), this.onCleanupEvents.push(() => window.removeEventListener("message", n)); } addActionListener() { this.addWindowMessageListener((t) => { t.type === "hook" && this.emit(t.hook.name, t.hook.data), (t.action && t.action === "updateHeight" || t.type === "updateHeight") && (this.iframe.scrolling = "no", this.iframe.style.height = `${t.height}px`); }); } setViewModel(t) { const n = { action: "setViewModel", viewModel: t }; this.addOnLoadEvent(() => { this.iframe.contentWindow.postMessage(n, this.verificationUrl.origin); }); } setOptions(t) { const n = { action: "setOptions", options: t }; this.addOnLoadEvent(() => { this.iframe.contentWindow.postMessage(n, this.verificationUrl.origin); }); } setInstallType(t) { this.installType = t; } init(t = !0) { t && this.createIframe(A), this.addActionListener(), this.containerElement.appendChild(this.iframe); } } class V extends d { constructor(e, t) { super(e, t), this.verificationUrl = new URL(this.getAffinityUrlWithUID(t)); } static createUniqueId() { return Math.random().toString(36).substr(2, 9); } getAffinityUrlWithUID(e) { const t = new URL(e); return t.searchParams.set("affinityIframeUid", this.verificationIframeUid), t.toString(); } addWindowMessageListener(e) { const t = (n) => { this.verificationUrl.origin === n.origin && n.data.affinityIframeUid === this.verificationIframeUid && n.data.action && n.data.action.type && e(n.data.action); }; window.addEventListener("message", t), this.onCleanupEvents.push(() => window.removeEventListener("message", t)); } createIframe(e) { return this.iframe = document.createElement("iframe"), this.iframe.classList.add(e.className), this.iframe.title = e.title, this.iframe.src = this.verificationUrl.href, this.iframe.allow = "camera;microphone", this.iframe.onload = () => this.onLoad(), this.iframe; } init() { this.createIframe({ ...A, title: "SheerID Affinity Offers" }), this.addActionListener(), this.containerElement.appendChild(this.iframe); } } class w { constructor(e, t) { s(this, "verificationUrl"); s(this, "redirectOnMobile"); s(this, "overlay"); s(this, "wrapper"); s(this, "iframeInstance"); s(this, "on"); s(this, "once"); s(this, "isMobileDevice"); s(this, "closeButtonText"); s(this, "closeButton"); s(this, "stopPropagation"); s(this, "popStateEventHandler", () => this.closeModal()); const n = t.mobileThreshold ? t.mobileThreshold : c.DEFAULT_MOBILE_THRESHOLD_WIDTH; this.verificationUrl = U(e), this.redirectOnMobile = t.mobileRedirect || !1, this.isMobileDevice = window.document.body.clientWidth <= Number(n), this.closeButtonText = t.closeButtonText ? t.closeButtonText : "", this.closeButton = null, this.stopPropagation = t.stopPropagation || !1, this.overlay = w.createOverlay(), this.wrapper = this.createWrapper(), this.addFocusListener(); } createCloseBtn() { if (this.closeButton = document.createElement("button"), this.closeButton.classList.add(c.CLASS_NAMES.CLOSE_BUTTON), this.closeButton.setAttribute("aria-label", "close"), this.closeButtonText) { const t = document.createElement("div"); t.classList.add(c.CLASS_NAMES.CLOSE_TEXT), t.innerHTML = this.closeButtonText, this.closeButton.appendChild(t); } const e = document.createElement("span"); return e.classList.add(c.CLASS_NAMES.CLOSE_ICON), e.setAttribute("role", "img"), this.closeButton.appendChild(e), this.closeButton.addEventListener("click", (t) => { t.preventDefault(), this.stopPropagation && t.stopPropagation(), this.closeModal(); }), this.closeButton; } closeModal() { window.removeEventListener("popstate", this.popStateEventHandler); const e = c.MODAL_OPACITY_TRANSITION_PERIOD; g(this.overlay, e), g(this.wrapper, e), this.iframeInstance.cleanup(); } static createOverlay() { const e = document.createElement("div"); return e.classList.add(c.CLASS_NAMES.OVERLAY), e; } createWrapper() { const e = document.createElement("div"); e.classList.add(c.CLASS_NAMES.MODAL_WRAPPER), e.tabIndex = -1, e.setAttribute("role", "dialog"), e.appendChild(this.createCloseBtn()), this.iframeInstance = new d(e, this.verificationUrl), this.iframeInstance.setInstallType("cdn_modal_iframe"), this.on = this.iframeInstance.on.bind(this.iframeInstance), this.once = this.iframeInstance.once.bind(this.iframeInstance); const t = { className: c.CLASS_NAMES.MODAL_IFRAME, title: b }; return this.iframeInstance.createIframe(t), e.appendChild(this.iframeInstance.iframe), e; } addPopStateListener() { window.addEventListener("popstate", this.popStateEventHandler); } addFocusListener() { this.iframeInstance.addWindowMessageListener((e) => { e.type === "focus" && e.focusOn === "firstElement" && this.closeButton.focus(); }), document.addEventListener("keydown", (e) => { e.key === "Tab" && e.shiftKey && document.activeElement === this.closeButton && (this.iframeInstance.iframe.contentWindow.postMessage({ focusOn: "lastElement" }, "*"), e.preventDefault()); }); } isInLightboxPostMessage(e) { this.iframeInstance.iframe.contentWindow.postMessage({ isInLightBox: e }, "*"); } displayModal() { this.iframeInstance.iframe.addEventListener("load", () => { W([this.overlay, this.wrapper]), document.body.style.overflow = "hidden", this.isInLightboxPostMessage("true"); }), document.body.appendChild(this.overlay), document.body.appendChild(this.wrapper), this.addPopStateListener(); } init() { this.redirectOnMobile && this.isMobileDevice ? window.top.location.href = this.verificationUrl : (this.displayModal(), this.iframeInstance.init(!1)); } setViewModel(e) { this.iframeInstance.setViewModel(e); } setOptions(e) { this.iframeInstance.setOptions(e); } } function Y(i, e) { const t = new d(i, e); return t.init(), t; } function j(i, e = {}) { const t = new w(i, e); return t.init(), t; } function q(i, e) { const t = new V(i, e); return t.init(), t; } const Q = { loadInModal: j, loadInlineIframe: Y }; export { Q as default, q as loadAffinityIFrame, j as loadInModal, Y as loadInlineIframe };