PluginProbe
Blockenberg — 600+ Advanced Gutenberg Blocks & AI Agent for WordPress Block Editor / 2.0.11
Blockenberg — 600+ Advanced Gutenberg Blocks & AI Agent for WordPress Block Editor v2.0.11
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 / popup / frontend.js

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

252 lines 11.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 (function () {
2 var _typoKeys = {
3 family:'font-family', weight:'font-weight', style:'font-style',
4 decoration:'text-decoration', transform:'text-transform',
5 sizeDesktop:'font-size-d', sizeTablet:'font-size-t', sizeMobile:'font-size-m',
6 lineHeightDesktop:'line-height-d', lineHeightTablet:'line-height-t', lineHeightMobile:'line-height-m',
7 letterSpacingDesktop:'letter-spacing-d', letterSpacingTablet:'letter-spacing-t', letterSpacingMobile:'letter-spacing-m',
8 wordSpacingDesktop:'word-spacing-d', wordSpacingTablet:'word-spacing-t', wordSpacingMobile:'word-spacing-m'
9 };
10 function typoCssVarsForEl(el, obj, prefix) {
11 if (!obj || typeof obj !== 'object') return;
12 Object.keys(_typoKeys).forEach(function (k) {
13 var v = obj[k];
14 if (v === undefined || v === '' || v === null) return;
15 if (k === 'sizeDesktop' || k === 'sizeTablet' || k === 'sizeMobile') v = v + (obj.sizeUnit || 'px');
16 else if (k === 'lineHeightDesktop' || k === 'lineHeightTablet' || k === 'lineHeightMobile') v = v + (obj.lineHeightUnit || '');
17 else if (k === 'letterSpacingDesktop' || k === 'letterSpacingTablet' || k === 'letterSpacingMobile') v = v + (obj.letterSpacingUnit || 'px');
18 else if (k === 'wordSpacingDesktop' || k === 'wordSpacingTablet' || k === 'wordSpacingMobile') v = v + (obj.wordSpacingUnit || 'px');
19 el.style.setProperty(prefix + _typoKeys[k], String(v));
20 });
21 }
22
23 function init() {
24 document.querySelectorAll('.bkbg-pop-app').forEach(function (appEl) {
25 if (appEl.dataset.rendered) return;
26 appEl.dataset.rendered = '1';
27
28 var opts;
29 try { opts = JSON.parse(appEl.dataset.opts || '{}'); } catch (e) { opts = {}; }
30
31 var o = Object.assign({
32 triggerLabel: 'Open Popup', triggerStyle: 'filled', triggerSize: 'md',
33 triggerAlign: 'center', triggerType: 'click', scrollDepth: 40, timeDelay: 3,
34 showOnce: 'always', popupPosition: 'center', popupSize: 'md', popupWidth: 560,
35 popupAnimation: 'scale', borderRadius: 16, closeOnOverlay: true, showCloseBtn: true,
36 imageUrl: '', imageAlt: '', imagePosition: 'top',
37 heading: 'Get 20% Off Today',
38 subtext: 'Subscribe to our newsletter and get your exclusive discount code instantly.',
39 ctaLabel: 'Claim Your Discount', ctaUrl: '#', ctaNewTab: false,
40 showCta: true, ctaStyle: 'filled', dismissLabel: 'No thanks', showDismiss: true,
41 paddingTop: 0, paddingBottom: 0,
42 overlayColor: '#000000', overlayOpacity: 60, popupBg: '#ffffff',
43 headingColor: '#111827', textColor: '#4b5563',
44 btnBg: '#6366f1', btnColor: '#ffffff',
45 triggerBg: '#6366f1', triggerColor: '#ffffff', dismissColor: '#9ca3af',
46 headingTypo: {}, bodyTypo: {}
47 }, opts);
48
49 /* Unique ID for frequency tracking */
50 var uid = 'bkbg-pop-' + (appEl.dataset.uid || Math.random().toString(36).slice(2));
51 appEl.dataset.uid = uid;
52
53 /* Check show frequency */
54 function canShow() {
55 if (o.showOnce === 'session') return !sessionStorage.getItem(uid);
56 if (o.showOnce === 'once') return !localStorage.getItem(uid);
57 return true;
58 }
59 function markShown() {
60 if (o.showOnce === 'session') sessionStorage.setItem(uid, '1');
61 if (o.showOnce === 'once') localStorage.setItem(uid, '1');
62 }
63
64 /* Build overlay */
65 var overlay = document.createElement('div');
66 overlay.className = 'bkbg-pop-overlay pos-' + o.popupPosition;
67 overlay.style.background = hexToRgba(o.overlayColor, o.overlayOpacity / 100);
68
69 var pwMap = { sm: '400px', md: '560px', lg: '760px', custom: o.popupWidth + 'px' };
70 var pw = pwMap[o.popupSize] || '560px';
71
72 var box = document.createElement('div');
73 box.className = 'bkbg-pop-box anim-' + o.popupAnimation;
74 box.style.cssText = 'max-width:' + pw + ';border-radius:' + o.borderRadius + 'px;background:' + o.popupBg;
75 box.setAttribute('role', 'dialog');
76 box.setAttribute('aria-modal', 'true');
77
78 typoCssVarsForEl(box, o.headingTypo, '--bkbg-pop-hd-');
79 typoCssVarsForEl(box, o.bodyTypo, '--bkbg-pop-bd-');
80
81 /* Close button */
82 if (o.showCloseBtn) {
83 var closeBtn = document.createElement('button');
84 closeBtn.className = 'bkbg-pop-close';
85 closeBtn.innerHTML = '×';
86 closeBtn.setAttribute('aria-label', 'Close');
87 closeBtn.addEventListener('click', closePopup);
88 box.appendChild(closeBtn);
89 }
90
91 /* Inner layout */
92 var inner = document.createElement('div');
93 inner.className = 'bkbg-pop-inner img-' + (o.imageUrl ? o.imagePosition : 'none');
94
95 if (o.imageUrl && o.imagePosition === 'top') {
96 inner.appendChild(makeImage(true));
97 }
98
99 var rowWrap = document.createElement('div');
100 rowWrap.style.display = 'flex';
101 rowWrap.style.flex = '1';
102
103 if (o.imageUrl && o.imagePosition === 'left') rowWrap.appendChild(makeImage(false));
104
105 var body = document.createElement('div');
106 body.className = 'bkbg-pop-body';
107
108 var h = document.createElement('p');
109 h.className = 'bkbg-pop-heading';
110 h.innerHTML = o.heading;
111 h.style.color = o.headingColor;
112 body.appendChild(h);
113
114 var txt = document.createElement('p');
115 txt.className = 'bkbg-pop-text';
116 txt.innerHTML = o.subtext;
117 txt.style.color = o.textColor;
118 body.appendChild(txt);
119
120 if (o.showCta) {
121 var cta = document.createElement('a');
122 cta.className = 'bkbg-pop-cta';
123 cta.href = o.ctaUrl || '#';
124 if (o.ctaNewTab) { cta.target = '_blank'; cta.rel = 'noopener noreferrer'; }
125 cta.textContent = o.ctaLabel;
126 cta.style.cssText = [
127 o.ctaStyle === 'filled' ? 'background:' + o.btnBg + ';color:' + o.btnColor + ';border:none' : 'background:transparent;color:' + o.btnBg + ';border:2px solid ' + o.btnBg
128 ].join(';');
129 body.appendChild(cta);
130 }
131
132 if (o.showDismiss) {
133 var dis = document.createElement('button');
134 dis.className = 'bkbg-pop-dismiss';
135 dis.textContent = o.dismissLabel;
136 dis.style.color = o.dismissColor;
137 dis.addEventListener('click', closePopup);
138 body.appendChild(dis);
139 }
140
141 rowWrap.appendChild(body);
142 if (o.imageUrl && o.imagePosition === 'right') rowWrap.appendChild(makeImage(false));
143
144 inner.appendChild(rowWrap);
145 box.appendChild(inner);
146 overlay.appendChild(box);
147
148 if (o.closeOnOverlay) {
149 overlay.addEventListener('click', function (e) {
150 if (e.target === overlay) closePopup();
151 });
152 }
153
154 document.body.appendChild(overlay);
155
156 /* Open / close */
157 function openPopup() {
158 if (!canShow()) return;
159 overlay.classList.add('is-open');
160 document.body.style.overflow = 'hidden';
161 markShown();
162 box.focus && box.focus();
163 }
164 function closePopup() {
165 overlay.classList.remove('is-open');
166 document.body.style.overflow = '';
167 }
168
169 /* ESC key */
170 document.addEventListener('keydown', function (e) {
171 if (e.key === 'Escape') closePopup();
172 });
173
174 /* Trigger wrapper */
175 var triggerWrap = document.createElement('div');
176 triggerWrap.className = 'bkbg-pop-trigger-wrap align-' + o.triggerAlign;
177 triggerWrap.style.cssText = 'padding-top:' + o.paddingTop + 'px;padding-bottom:' + o.paddingBottom + 'px';
178
179 /* Build trigger button for 'click' (or show it even for auto triggers so user can also click) */
180 if (o.triggerType === 'click') {
181 var btn = buildTriggerBtn();
182 btn.addEventListener('click', openPopup);
183 triggerWrap.appendChild(btn);
184 }
185
186 /* Auto triggers */
187 if (o.triggerType === 'scroll') {
188 /* show button + listen */
189 triggerWrap.appendChild(buildTriggerBtn()).addEventListener('click', openPopup);
190 window.addEventListener('scroll', function onScroll() {
191 var pct = (window.scrollY / (document.documentElement.scrollHeight - window.innerHeight)) * 100;
192 if (pct >= o.scrollDepth) { window.removeEventListener('scroll', onScroll); openPopup(); }
193 }, { passive: true });
194 }
195
196 if (o.triggerType === 'delay') {
197 triggerWrap.appendChild(buildTriggerBtn()).addEventListener('click', openPopup);
198 setTimeout(openPopup, o.timeDelay * 1000);
199 }
200
201 if (o.triggerType === 'exit') {
202 triggerWrap.appendChild(buildTriggerBtn()).addEventListener('click', openPopup);
203 document.addEventListener('mouseleave', function onExit(e) {
204 if (e.clientY < 5) { document.removeEventListener('mouseleave', onExit); openPopup(); }
205 });
206 }
207
208 appEl.parentNode.insertBefore(triggerWrap, appEl);
209
210 /* Helpers */
211 function buildTriggerBtn() {
212 var b = document.createElement('button');
213 b.className = 'bkbg-pop-btn size-' + o.triggerSize;
214 b.textContent = o.triggerLabel;
215 var s = [];
216 if (o.triggerStyle === 'filled') {
217 s.push('background:' + o.triggerBg, 'color:' + o.triggerColor, 'border:none');
218 } else if (o.triggerStyle === 'outline') {
219 s.push('background:transparent', 'color:' + o.triggerBg, 'border:2px solid ' + o.triggerBg);
220 } else {
221 s.push('background:transparent', 'color:' + o.triggerBg, 'border:none');
222 }
223 b.style.cssText = s.join(';');
224 return b;
225 }
226
227 function makeImage(isTop) {
228 var img = document.createElement('img');
229 img.className = 'bkbg-pop-img';
230 img.src = o.imageUrl;
231 img.alt = o.imageAlt || '';
232 if (isTop) {
233 img.style.cssText = 'width:100%;max-height:220px;object-fit:cover;display:block;border-radius:' + o.borderRadius + 'px ' + o.borderRadius + 'px 0 0';
234 } else {
235 img.style.cssText = 'width:42%;flex-shrink:0;object-fit:cover;display:block;min-height:200px';
236 }
237 return img;
238 }
239
240 function hexToRgba(hex, alpha) {
241 var r = parseInt(hex.slice(1, 3), 16);
242 var g = parseInt(hex.slice(3, 5), 16);
243 var b = parseInt(hex.slice(5, 7), 16);
244 return 'rgba(' + r + ',' + g + ',' + b + ',' + alpha + ')';
245 }
246 });
247 }
248
249 if (document.readyState !== 'loading') { init(); }
250 else { document.addEventListener('DOMContentLoaded', init); }
251 })();
252