UNPKG

@braze/web-sdk

Version:

Braze SDK for web sites and other JS platforms.

212 lines (211 loc) 7.1 kB
import rr from "./base-feed.js"; import { getCardId as be, markCardAsRead as ye, } from "../Card/display/card-display.js"; import { bottomIsInView as B, topIsInView as x } from "../util/dom-utils.js"; import { Card, ControlCard } from "../Card/index.js"; import { cardToHtml as Fe } from "../Card/display/card-display.js"; import { isArray as z } from "../util/code-utils.js"; import { KeyCodes as mt } from "../util/key-codes.js"; import ge from "../l10n/l10n-manager-factory.js"; import { removeSubscription } from "../Core/remove-subscription.js"; import { logger as N, Guid as G } 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 jt, ineligibleBrazeActionURLErrorMessage as dt, getDecodedBrazeAction as eo, containsUnknownBrazeAction as ft, } from "../util/braze-actions.js"; import { bottomHadImpression as xe, impressOnBottom as j, impressOnTop as $, topHadImpression as Ee, } from "./detect-impression.js"; import { SUBSCRIPTION_ID_DATA_ATTRIBUTE as f } from "./constants.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 destroyFeedHtml(e) { e && ((e.className = e.className.replace("ab-show", "ab-hide")), setTimeout(() => { e && e.parentNode && e.parentNode.removeChild(e); }, rr.Ih)); const t = e.getAttribute(f); null != t && removeSubscription(t); const o = e.getAttribute("data-listener-id"); null != o && (window.removeEventListener("scroll", scrollListeners[o]), delete scrollListeners[o]); } export function generateFeedBody(e, t) { const o = ge.ea(), s = document.createElement("div"); if ( ((s.className = "ab-feed-body"), s.setAttribute("aria-label", "Feed"), s.setAttribute("role", "feed"), null == e.lastUpdated) ) { const e = document.createElement("div"); e.className = "ab-no-cards-message"; const t = document.createElement("i"); (t.className = "fa fa-spinner fa-spin fa-4x ab-initial-spinner"), e.appendChild(t), s.appendChild(e); } else { let n = !1; const logCardClick = (t) => e.logCardClick(t); for (const r of e.cards) { const i = r instanceof ControlCard; !i || e.nr() ? (s.appendChild(Fe(r, logCardClick, t, o.Oo())), (n = n || !i)) : N.error( "Received a control card for a legacy news feed. Control cards are only supported with content cards.", ); } if (!n) { const e = document.createElement("div"); (e.className = "ab-no-cards-message"), (e.innerHTML = o.get("NO_CARDS_MESSAGE") || ""), e.setAttribute("role", "article"), s.appendChild(e); } } return s; } export function detectFeedImpressions(e, t) { if (null != e && null != t) { const o = [], s = t.querySelectorAll(".ab-card"); e._o || (e._o = {}); for (let t = 0; t < s.length; t++) { const n = be(s[t]), r = x(s[t]), i = B(s[t]); if (e._o[n]) { r || i || ye(s[t]); continue; } let a = Ee(s[t]), d = xe(s[t]); const l = a, c = d; if ( (!a && r && ((a = !0), $(s[t])), !d && i && ((d = !0), j(s[t])), a && d) ) { if (l && c) continue; for (const t of e.cards) if (t.id === n) { (e._o[t.id] = !0), o.push(t); break; } } } o.length > 0 && e.logCardImpressions(o); } } export function refreshFeed(e, t) { if (null == e || null == t) return; t.setAttribute("aria-busy", "true"); const o = t.querySelectorAll(".ab-refresh-button")[0]; null != o && (o.className += " fa-spin"); const s = new Date().valueOf().toString(); t.setAttribute("data-last-requested-refresh", s), setTimeout(() => { if (t.getAttribute("data-last-requested-refresh") === s) { const e = t.querySelectorAll(".fa-spin"); for (let t = 0; t < e.length; t++) e[t].className = e[t].className.replace(/fa-spin/g, ""); const o = t.querySelectorAll(".ab-initial-spinner")[0]; if (null != o) { const e = document.createElement("span"); (e.innerHTML = ge.ea().get("FEED_TIMEOUT_MESSAGE") || ""), null != o.parentNode && (o.parentNode.appendChild(e), o.parentNode.removeChild(o)); } "true" === t.getAttribute("aria-busy") && t.setAttribute("aria-busy", "false"); } }, rr.Ro), e.sr(); } export function feedToHtml(e, t, o) { const s = document.createElement("div"); (s.className = "ab-feed ab-hide ab-effect-slide"), s.setAttribute("role", "dialog"), s.setAttribute("aria-label", "Feed"), s.setAttribute("tabindex", "-1"); const n = document.createElement("div"); (n.className = "ab-feed-buttons-wrapper"), n.setAttribute("role", "group"), s.appendChild(n); 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 i = (e) => { destroyFeedHtml(s), e.stopPropagation(); }; r.addEventListener("keydown", (e) => { (e.keyCode !== mt.Wo && e.keyCode !== mt.Xo) || i(e); }), (r.onclick = i); const a = document.createElement("i"); (a.className = "fa fa-refresh ab-refresh-button"), e && null == e.lastUpdated && (a.className += " fa-spin"), a.setAttribute("aria-label", "Refresh Feed"), a.setAttribute("tabindex", "0"), a.setAttribute("role", "button"); const d = (t) => { refreshFeed(e, s), t.stopPropagation(); }; a.addEventListener("keydown", (e) => { (e.keyCode !== mt.Wo && e.keyCode !== mt.Xo) || d(e); }), (a.onclick = d), n.appendChild(a), n.appendChild(r), s.appendChild(generateFeedBody(e, t)); const l = () => detectFeedImpressions(e, s); if ((s.addEventListener("scroll", l), !o)) { window.addEventListener("scroll", l); const e = G.ce(); (scrollListeners[e] = l), s.setAttribute("data-listener-id", e); } return s; } export function updateFeedCards(e, t, o, s, n) { if (!z(t)) return; const r = []; for (const e of t) if (e instanceof Card) { if (e.url && to.test(e.url)) { const t = eo(e.url); if (ft(t)) { N.error(dt(jt.Tr, "Content Card")); continue; } } r.push(e); } if (((e.cards = r), (e.lastUpdated = o), null != s)) if ((s.setAttribute("aria-busy", "false"), null == e.lastUpdated)) destroyFeedHtml(s); else { const t = s.querySelectorAll(".ab-feed-body")[0]; if (null != t) { const o = generateFeedBody(e, n); t.parentNode && t.parentNode.replaceChild(o, t), detectFeedImpressions(e, o.parentNode); } } } export function registerFeedSubscriptionId(e, t) { e && t.setAttribute(f, e); }