PluginProbe
Blockenberg — 600+ Advanced Gutenberg Blocks & AI Agent for WordPress Block Editor / 2.0.7
Blockenberg — 600+ Advanced Gutenberg Blocks & AI Agent for WordPress Block Editor v2.0.7
2.0.13 2.0.12 2.0.11 2.0.10 2.0.9 trunk 2.0.2 2.0.3 2.0.4 2.0.5 2.0.6 2.0.7 2.0.8
blockenberg / blocks / social-proof-popup / frontend.js

frontend.js in Blockenberg — 600+ Advanced Gutenberg Blocks & AI Agent for WordPress Block Editor 2.0.7, at blocks/social-proof-popup/frontend.js

214 lines 8.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 (function () {
2 'use strict';
3
4 var _typoKeys = {
5 family: 'font-family', weight: 'font-weight', style: 'font-style',
6 decoration: 'text-decoration', transform: 'text-transform',
7 sizeDesktop: 'font-size-d', sizeTablet: 'font-size-t', sizeMobile: 'font-size-m',
8 sizeUnit: null,
9 lineHeightDesktop: 'line-height-d', lineHeightTablet: 'line-height-t', lineHeightMobile: 'line-height-m',
10 letterSpacingDesktop: 'letter-spacing-d', letterSpacingTablet: 'letter-spacing-t', letterSpacingMobile: 'letter-spacing-m',
11 wordSpacingDesktop: 'word-spacing-d', wordSpacingTablet: 'word-spacing-t', wordSpacingMobile: 'word-spacing-m'
12 };
13
14 function typoCssVarsForEl(el, typoObj, prefix) {
15 if (!typoObj || typeof typoObj !== 'object') return;
16 var unit = typoObj.sizeUnit || 'px';
17 Object.keys(typoObj).forEach(function (k) {
18 var v = typoObj[k]; if (v === undefined || v === '' || v === null) return;
19 var prop = _typoKeys[k]; if (!prop) return;
20 var val = (prop.indexOf('font-size') === 0 || prop.indexOf('letter-spacing') === 0 || prop.indexOf('word-spacing') === 0 || prop.indexOf('line-height') === 0)
21 ? v + unit : String(v);
22 el.style.setProperty(prefix + prop, val);
23 });
24 }
25
26 function init() {
27 document.querySelectorAll('.bkbg-spop-app').forEach(function (appEl) {
28 if (appEl.dataset.rendered) return;
29 appEl.dataset.rendered = '1';
30
31 var opts;
32 try { opts = JSON.parse(appEl.dataset.opts || '{}'); } catch (e) { opts = {}; }
33 var o = Object.assign({
34 entries: [],
35 position: 'bottom-left',
36 displayTime: 4000,
37 pauseBetween: 3000,
38 animationType: 'slide',
39 showAvatar: true,
40 showTime: true,
41 showClose: true,
42 loop: true,
43 startDelay: 2000,
44 borderRadius: 12,
45 shadow: true,
46 maxWidth: 300,
47 bgColor: '#ffffff',
48 textColor: '#1e293b',
49 nameColor: '#0f172a',
50 actionColor: '#475569',
51 timeColor: '#94a3b8',
52 borderColor: '#e2e8f0',
53 avatarBg: '#f0f9ff',
54 closeBtnColor: '#94a3b8'
55 }, opts);
56
57 if (!o.entries || o.entries.length === 0) return;
58
59 // Create fixed container
60 var container = document.createElement('div');
61 container.className = 'bkbg-spop-container pos-' + o.position;
62 container.dataset.pos = o.position;
63 container.dataset.anim = o.animationType;
64 document.body.appendChild(container);
65
66 // Apply typography CSS vars on the container
67 typoCssVarsForEl(container, o.nameTypo, '--bkspop-nm-');
68 typoCssVarsForEl(container, o.actionTypo, '--bkspop-ac-');
69
70 // Build a popup DOM element
71 function makePopup(entry) {
72 var popup = document.createElement('div');
73 popup.className = 'bkbg-spop-popup';
74 popup.style.background = o.bgColor;
75 popup.style.color = o.textColor;
76 popup.style.borderColor = o.borderColor;
77 popup.style.borderRadius = o.borderRadius + 'px';
78 popup.style.maxWidth = o.maxWidth + 'px';
79 popup.style.boxShadow = o.shadow ? '0 4px 24px rgba(0,0,0,.12), 0 1px 4px rgba(0,0,0,.08)' : 'none';
80 popup.style.transition = 'opacity .35s ease, transform .35s ease';
81 popup.style.border = '1px solid ' + o.borderColor;
82
83 if (o.showAvatar) {
84 var avatar = document.createElement('div');
85 avatar.className = 'bkbg-spop-avatar';
86 avatar.style.background = o.avatarBg;
87 if (entry.emoji) {
88 var emojiSpan = document.createElement('span');
89 emojiSpan.className = 'bkbg-spop-emoji';
90 emojiSpan.textContent = entry.emoji;
91 avatar.appendChild(emojiSpan);
92 } else {
93 var initial = document.createElement('span');
94 initial.className = 'bkbg-spop-initial';
95 initial.textContent = (entry.name || 'U').charAt(0).toUpperCase();
96 avatar.appendChild(initial);
97 }
98 popup.appendChild(avatar);
99 }
100
101 var content = document.createElement('div');
102 content.className = 'bkbg-spop-content';
103
104 var nameLine = document.createElement('div');
105 nameLine.className = 'bkbg-spop-name';
106 nameLine.style.color = o.nameColor;
107 nameLine.textContent = entry.name || '';
108 if (entry.location) {
109 var locSpan = document.createElement('span');
110 locSpan.className = 'bkbg-spop-location';
111 locSpan.textContent = ' · ' + entry.location;
112 nameLine.appendChild(locSpan);
113 }
114 content.appendChild(nameLine);
115
116 var actionLine = document.createElement('div');
117 actionLine.className = 'bkbg-spop-action';
118 actionLine.style.color = o.actionColor;
119 actionLine.textContent = entry.action || '';
120 content.appendChild(actionLine);
121
122 if (o.showTime && entry.timeAgo) {
123 var timeLine = document.createElement('div');
124 timeLine.className = 'bkbg-spop-time';
125 timeLine.style.color = o.timeColor;
126 timeLine.textContent = entry.timeAgo;
127 content.appendChild(timeLine);
128 }
129
130 popup.appendChild(content);
131
132 if (o.showClose) {
133 var closeBtn = document.createElement('button');
134 closeBtn.className = 'bkbg-spop-close';
135 closeBtn.textContent = '×';
136 closeBtn.style.color = o.closeBtnColor;
137 closeBtn.addEventListener('click', function () {
138 hidePopup(popup);
139 });
140 popup.appendChild(closeBtn);
141 }
142
143 return popup;
144 }
145
146 function showPopup(popup) {
147 container.appendChild(popup);
148 // Force reflow
149 popup.getBoundingClientRect();
150 popup.classList.add('is-visible');
151 }
152
153 function hidePopup(popup) {
154 popup.classList.remove('is-visible');
155 setTimeout(function () {
156 if (popup.parentNode) popup.parentNode.removeChild(popup);
157 }, 400);
158 }
159
160 var currentIdx = 0;
161 var timer = null;
162 var dismissed = false;
163
164 function showNext() {
165 if (dismissed || o.entries.length === 0) return;
166
167 var entry = o.entries[currentIdx];
168 var popup = makePopup(entry);
169 showPopup(popup);
170
171 // Auto-hide after displayTime
172 var hideTimer = setTimeout(function () {
173 hidePopup(popup);
174 // Schedule next
175 timer = setTimeout(function () {
176 currentIdx++;
177 if (currentIdx >= o.entries.length) {
178 if (o.loop) currentIdx = 0;
179 else return; // done
180 }
181 showNext();
182 }, o.pauseBetween);
183 }, o.displayTime);
184
185 // If close button was clicked, cancel the main timers
186 popup.addEventListener('click', function (e) {
187 if (e.target.classList.contains('bkbg-spop-close')) {
188 clearTimeout(hideTimer);
189 clearTimeout(timer);
190 timer = setTimeout(function () {
191 currentIdx++;
192 if (currentIdx >= o.entries.length) {
193 if (o.loop) currentIdx = 0;
194 else return;
195 }
196 showNext();
197 }, o.pauseBetween);
198 }
199 });
200 }
201
202 // Start after delay
203 setTimeout(function () {
204 showNext();
205 }, o.startDelay);
206
207 appEl.style.display = 'none';
208 });
209 }
210
211 if (document.readyState !== 'loading') { init(); }
212 else { document.addEventListener('DOMContentLoaded', init); }
213 })();
214