@sheerid/jslib-nightly
Version:
SheerID JavaScript Library
396 lines (394 loc) • 14 kB
JavaScript
/**
* VERSION: 2.154.0-alpha.1
* BUILD_TIMESTAMP: 1763401559038
* BUILD_DATE: Mon Nov 17 2025 17:45:59 GMT+0000 (Coordinated Universal Time)
* BUILD_COMMIT: 73f4468155aaed0f31ab0d59dc3394018b939b6d
*/
const S = "installPageUrl", A = "installType", T = {
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"
}, v = "SheerID Verification Form", o = {
CLASS_NAMES: T,
DEFAULT_MOBILE_THRESHOLD_WIDTH: 620,
MODAL_OPACITY_TRANSITION_PERIOD: 300
}, _ = {}, M = async () => _, y = () => window.navigator.globalPrivacyControl, d = () => window.NREUM && !y();
function a(i, e) {
try {
return i();
} catch {
return e;
}
}
let h = 4, c = "";
const I = {
info: 1,
log: 2,
warn: 3,
error: 4,
silent: 5
}, f = {
info: "#26c1db",
log: "#09f979",
warn: "#f6b13f",
error: "#e12046"
}, m = "color: white; font-weight: bold; padding: 2px 10px;";
let p;
const O = (i) => i && i.stack && i.message, u = (...i) => {
h <= 3 && console.warn(`%c${c} warn`, `background: ${f.warn};${m}`, ...i);
}, N = (...i) => {
h <= 2 && console.log(`%c${c} log`, `background: ${f.log};${m}`, ...i);
}, R = (...i) => {
h <= 1 && console.log(`%c${c} info`, `background: ${f.info};${m}`, ...i);
}, P = async (i, e = "unknown group", t = {}) => {
if (h <= 4) {
if (!i) {
console.error(new Error("An error must be supplied"));
return;
}
let s;
typeof i == "string" && (s = new Error(i)), O(i) && (s = i), s || (s = new Error("Unknown error"));
let n = { errorMessageGroup: e };
try {
n = {
...await M(),
...n
}, delete n.jslibVersionActual;
} catch (r) {
d() ? window.NREUM.noticeError(s, n) : u("Unable to assemble GA error attributes", r);
}
try {
if (p && p.getState) {
const r = p.getState(), w = a(() => r.verificationResponse.errorIds);
n = {
...n,
programId: a(() => r.programId),
isLoading: a(() => r.isLoading),
isErrored: a(() => r.isErrored),
errorIdsFromVerRsp: Array.isArray(w) ? w.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.154.0-alpha.1", "?"),
...t
};
}
} catch (r) {
d() ? window.NREUM.noticeError(s, n) : u("Unable to assemble useful error attributes", r);
}
d() && window.NREUM.noticeError(s, n), console.error(
`%c${c} error`,
`background: ${f.error};${m}`,
s,
n
);
}
}, C = (i, e = {}) => {
d() && window.NREUM.addPageAction(i, e);
}, D = (i, e) => {
C("API-calls-timing", {
api_call: i,
api_response_time: e
});
}, L = {
error: P,
warn: u,
log: N,
info: R,
/** @deprecated use newRelicPageAction() instead */
logAPIResponseTime: D,
setLogLevel: (i) => {
if (!I.hasOwnProperty(i))
throw new Error(`Unknown logLevel '${i}'`);
h = I[i], console.log(
`%c${c} log level set to ${i}`,
`background: ${f[i]};${m}`
), d() || u("Offsite logging not enabled");
},
setPrefix: (i) => {
c = i;
},
init: (i) => {
p = i;
}
}, x = (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);
}, b = (i) => {
const e = new URL(i);
return new URL(window.location.href).searchParams.forEach((s, n) => {
e.searchParams.has(n) || e.searchParams.set(n, s);
}), e.href;
};
class B {
subscribers = /* @__PURE__ */ new Set();
sub(e) {
return this.subscribers.add(e), () => this.subscribers.delete(e);
}
pub(e) {
this.subscribers.forEach((t) => t(e));
}
}
class $ {
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 B()), 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 s = this.on(e, (n) => (s(), t(n)));
return s;
}
/**
* 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 U = {
className: o.CLASS_NAMES.INLINE_IFRAME_CONTENT,
title: v
}, W = (i) => {
if (typeof i != "function")
throw new Error(`Expected type "function", but received ${typeof i}`);
};
class l extends $ {
containerElement;
verificationUrl;
isMobileDevice;
iframe;
verificationIframeUid;
locale;
hasLoaded = !1;
onLoadEvents = [];
onCleanupEvents = [];
installType = "cdn_inline_iframe";
constructor(e, t) {
super(), l.isValidHttpUrl(t) ? (this.containerElement = e, this.verificationUrl = new URL(b(t)), this.verificationIframeUid = l.createUniqueId()) : L.error("Invalid URL. Provide a proper URL: https://example.com/", "iframe url");
}
cleanup() {
this.onCleanupEvents.forEach((e) => e());
}
static createUniqueId() {
return Math.random().toString(36).substr(2, 9);
}
static isValidHttpUrl(e) {
try {
const t = new URL(e);
return t.protocol === "http:" || t.protocol === "https:";
} catch {
return !1;
}
}
createIframe(e) {
return this.iframe = document.createElement("iframe"), this.iframe.classList.add(e.className), this.iframe.title = e.title, this.iframe.src = this.getIframeUrl(), this.iframe.allow = "camera *;microphone *;geolocation *;clipboard-read *;clipboard-write *", this.iframe.onload = () => this.onLoad(), this.iframe;
}
getIframeUrl() {
const e = new URL(this.verificationUrl);
return e.searchParams.set("verificationIframeUid", this.verificationIframeUid), e.searchParams.set(S, window.location.href), e.searchParams.set(A, this.installType), this.locale && e.searchParams.set("locale", this.locale), e.toString();
}
// If iFrame hasn't loaded yet, queue up the callback
// otherwise call it immediately
addOnLoadEvent(e) {
try {
W(e);
} catch {
L.error("Invalid callback provided to iFrame.onLoad()", "iframe addOnLoadEvent");
return;
}
this.hasLoaded ? e() : this.onLoadEvents.push(e);
}
onLoad() {
this.hasLoaded = !0, this.onLoadEvents.forEach((e) => e());
}
/**
* Using this to add parent window message listeners gives us
* - Event Cleanup for modals
* - verification of origin, verificationIframeUid, and message data structure
*/
addWindowMessageListener(e) {
const t = (s) => {
this.verificationUrl.origin === s.origin && s.data.verificationIframeUid === this.verificationIframeUid && (s.data.action && s.data.action.type ? e(s.data.action) : s.data.action && s.data.height && e(s.data));
};
window.addEventListener("message", t), this.onCleanupEvents.push(() => window.removeEventListener("message", t));
}
addActionListener() {
this.addWindowMessageListener((e) => {
e.type === "hook" && this.emit(e.hook.name, e.hook.data), (e.action && e.action === "updateHeight" || e.type === "updateHeight") && (this.iframe.scrolling = "no", this.iframe.style.height = `${e.height}px`);
});
}
setViewModel(e) {
const t = {
action: "setViewModel",
viewModel: e
};
this.addOnLoadEvent(() => {
this.iframe.contentWindow.postMessage(t, this.verificationUrl.origin);
});
}
setOptions(e) {
const t = {
action: "setOptions",
options: e
};
if (!this.hasLoaded && e.locale) {
this.locale = e.locale;
const s = this.getIframeUrl();
s !== this.iframe.src && (this.iframe.src = s);
}
this.addOnLoadEvent(() => {
this.iframe.contentWindow.postMessage(t, this.verificationUrl.origin);
});
}
setInstallType(e) {
this.installType = e;
}
init(e = !0) {
e && this.createIframe(U), this.addActionListener(), this.containerElement.appendChild(this.iframe);
}
}
class F extends l {
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 = (s) => {
this.verificationUrl.origin === s.origin && s.data.affinityIframeUid === this.verificationIframeUid && s.data.action && s.data.action.type && e(s.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({ ...U, title: "SheerID Affinity Offers" }), this.addActionListener(), this.containerElement.appendChild(this.iframe);
}
}
class E {
verificationUrl;
redirectOnMobile;
overlay;
wrapper;
iframeInstance;
on;
once;
isMobileDevice;
closeButtonText;
closeButton;
stopPropagation;
constructor(e, t) {
const s = t.mobileThreshold ? t.mobileThreshold : o.DEFAULT_MOBILE_THRESHOLD_WIDTH;
this.verificationUrl = b(e), this.redirectOnMobile = t.mobileRedirect || !1, this.isMobileDevice = window.document.body.clientWidth <= Number(s), this.closeButtonText = t.closeButtonText ? t.closeButtonText : "", this.closeButton = null, this.stopPropagation = t.stopPropagation || !1, this.overlay = E.createOverlay(), this.wrapper = this.createWrapper(), this.addFocusListener();
}
createCloseBtn() {
if (this.closeButton = document.createElement("button"), this.closeButton.classList.add(o.CLASS_NAMES.CLOSE_BUTTON), this.closeButton.setAttribute("aria-label", "close"), this.closeButtonText) {
const t = document.createElement("div");
t.classList.add(o.CLASS_NAMES.CLOSE_TEXT), t.innerHTML = this.closeButtonText, this.closeButton.appendChild(t);
}
const e = document.createElement("span");
return e.classList.add(o.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 = o.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(o.CLASS_NAMES.OVERLAY), e;
}
createWrapper() {
const e = document.createElement("div");
e.classList.add(o.CLASS_NAMES.MODAL_WRAPPER), e.tabIndex = -1, e.setAttribute("role", "dialog"), e.appendChild(this.createCloseBtn()), this.iframeInstance = new l(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: o.CLASS_NAMES.MODAL_IFRAME,
title: v
};
return this.iframeInstance.createIframe(t), e.appendChild(this.iframeInstance.iframe), e;
}
popStateEventHandler = () => this.closeModal();
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", () => {
x([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 k(i, e) {
const t = new l(i, e);
return t.init(), t;
}
function H(i, e = {}) {
const t = new E(i, e);
return t.init(), t;
}
function V(i, e) {
const t = new F(i, e);
return t.init(), t;
}
const Y = { loadInModal: H, loadInlineIframe: k };
export {
Y as default,
V as loadAffinityIFrame,
H as loadInModal,
k as loadInlineIframe
};