UNPKG

@braze/web-sdk

Version:

Braze SDK for web sites and other JS platforms.

212 lines (211 loc) 7.21 kB
import { getCardId as xt, markCardAsRead as Rt, } from "../Card/display/card-display.js"; import { bottomIsInView as x, topIsInView as g } from "../util/dom-utils.js"; import { Card, ControlCard } from "../Card/index.js"; import { cardToHtml as Ht } from "../Card/display/card-display.js"; import { isArray as D } from "../util/code-utils.js"; import { KeyCodes as ie } from "../util/key-codes.js"; import fe from "../l10n/l10n-manager-factory.js"; import { removeSubscription } from "../Core/remove-subscription.js"; import { logger as E, Guid as P } from "../../shared-lib/index.js"; import { BRAZE_ACTION_URI_REGEX as to } from "../util/validation-utils.js"; import { INELIGIBLE_BRAZE_ACTION_URL_ERROR_TYPES as vt, ineligibleBrazeActionURLErrorMessage as jt, getDecodedBrazeAction as eo, containsUnknownBrazeAction as dt, } from "../util/braze-actions.js"; import { bottomHadImpression as kt, impressOnBottom as d, impressOnTop as j, topHadImpression as qt, } from "./detect-impression.js"; import { SUBSCRIPTION_ID_DATA_ATTRIBUTE as f } from "./constants.js"; import ContentCards from "../ContentCards/content-cards.js"; export const LAST_REQUESTED_REFRESH_DATA_ATTRIBUTE = "data-last-requested-refresh"; export const SCROLL_LISTENER_ID = "data-listener-id"; export const scrollListeners = {}; export function destroyContentCardsHtml(t) { t && ((t.className = t.className.replace("ab-show", "ab-hide")), setTimeout(() => { t && t.parentNode && t.parentNode.removeChild(t); }, ContentCards.cr)); const e = t.getAttribute(f); null != e && removeSubscription(e); const n = t.getAttribute("data-listener-id"); null != n && (window.removeEventListener("scroll", scrollListeners[n]), delete scrollListeners[n]); } export function generateContentCardsUI(t, e) { const n = fe.ea(), o = document.createElement("div"); if ( ((o.className = "ab-feed-body"), o.setAttribute("aria-label", "Feed"), o.setAttribute("role", "feed"), null == t.lastUpdated) ) { const t = document.createElement("div"); t.className = "ab-no-cards-message"; const e = document.createElement("i"); (e.className = "fa fa-spinner fa-spin fa-4x ab-initial-spinner"), t.appendChild(e), o.appendChild(t); } else { let s = !1; const r = (e) => t.nr(e); for (const a of t.cards) { const i = a instanceof ControlCard; !i || t.ar() ? (o.appendChild(Ht(a, r, e, n.So())), (s = s || !i)) : E.error( "Received a control card for a legacy news feed. Control cards are only supported with content cards.", ); } if (!s) { const t = document.createElement("div"); (t.className = "ab-no-cards-message"), (t.innerHTML = n.get("NO_CARDS_MESSAGE") || ""), t.setAttribute("role", "article"), o.appendChild(t); } } return o; } export function detectContentCardsImpressions(t, e) { if (null != t && null != e) { const n = [], o = e.querySelectorAll(".ab-card"); t.Qn || (t.Qn = {}); for (let e = 0; e < o.length; e++) { const s = xt(o[e]), r = g(o[e]), a = x(o[e]); if (t.Qn[s]) { r || a || Rt(o[e]); continue; } let i = qt(o[e]), l = kt(o[e]); const c = i, f = l; if ( (!i && r && ((i = !0), j(o[e])), !l && a && ((l = !0), d(o[e])), i && l) ) { if (c && f) continue; for (const e of t.cards) if (e.id === s) { (t.Qn[e.id] = !0), n.push(e); break; } } } n.length > 0 && t.sr(n); } } export function refreshContentCardsUI(t, e) { if (null == t || null == e) return; e.setAttribute("aria-busy", "true"); const n = e.querySelectorAll(".ab-refresh-button")[0]; null != n && (n.className += " fa-spin"); const o = new Date().valueOf().toString(); e.setAttribute("data-last-requested-refresh", o), setTimeout(() => { if (e.getAttribute("data-last-requested-refresh") === o) { const t = e.querySelectorAll(".fa-spin"); for (let e = 0; e < t.length; e++) t[e].className = t[e].className.replace(/fa-spin/g, ""); const n = e.querySelectorAll(".ab-initial-spinner")[0]; if (null != n) { const t = document.createElement("span"); (t.innerHTML = fe.ea().get("FEED_TIMEOUT_MESSAGE") || ""), null != n.parentNode && (n.parentNode.appendChild(t), n.parentNode.removeChild(n)); } "true" === e.getAttribute("aria-busy") && e.setAttribute("aria-busy", "false"); } }, ContentCards.Cr), t.dr(); } export function contentCardsToHtml(t, e, n) { const o = document.createElement("div"); (o.className = "ab-feed ab-hide ab-effect-slide"), o.setAttribute("role", "dialog"), o.setAttribute("aria-label", "Feed"), o.setAttribute("tabindex", "-1"); const s = document.createElement("div"); (s.className = "ab-feed-buttons-wrapper"), s.setAttribute("role", "group"), o.appendChild(s); const r = document.createElement("i"); (r.className = "fa fa-times ab-close-button"), r.setAttribute("aria-label", "Close Feed"), r.setAttribute("tabindex", "0"), r.setAttribute("role", "button"); const a = (t) => { destroyContentCardsHtml(o), t.stopPropagation(); }; r.addEventListener("keydown", (t) => { (t.keyCode !== ie.lo && t.keyCode !== ie.Ze) || a(t); }), (r.onclick = a); const i = document.createElement("i"); (i.className = "fa fa-refresh ab-refresh-button"), t && null == t.lastUpdated && (i.className += " fa-spin"), i.setAttribute("aria-label", "Refresh Feed"), i.setAttribute("tabindex", "0"), i.setAttribute("role", "button"); const l = (e) => { refreshContentCardsUI(t, o), e.stopPropagation(); }; i.addEventListener("keydown", (t) => { (t.keyCode !== ie.lo && t.keyCode !== ie.Ze) || l(t); }), (i.onclick = l), s.appendChild(i), s.appendChild(r), o.appendChild(generateContentCardsUI(t, e)); const d = () => detectContentCardsImpressions(t, o); if ((o.addEventListener("scroll", d), !n)) { window.addEventListener("scroll", d); const t = P.oe(); (scrollListeners[t] = d), o.setAttribute("data-listener-id", t); } return o; } export function updateContentCards(t, e, n, o, s) { if (!D(e)) return; const r = []; for (const t of e) if (t instanceof Card) { if (t.url && to.test(t.url)) { const e = eo(t.url); if (dt(e)) { E.error(jt(vt.Li, "Content Card")); continue; } } r.push(t); } if (((t.cards = r), (t.lastUpdated = n), null != o)) if ((o.setAttribute("aria-busy", "false"), null == t.lastUpdated)) destroyContentCardsHtml(o); else { const e = o.querySelectorAll(".ab-feed-body")[0]; if (null != e) { const n = generateContentCardsUI(t, s); e.parentNode && e.parentNode.replaceChild(n, e), detectContentCardsImpressions(t, n.parentNode); } } } export function registerContentCardsSubscriptionId(t, e) { t && e.setAttribute(f, t); }