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 / rotating-banner / frontend.js

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

268 lines 11.3 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 lineHeightDesktop:'line-height-d', lineHeightTablet:'line-height-t', lineHeightMobile:'line-height-m',
9 letterSpacingDesktop:'letter-spacing-d', letterSpacingTablet:'letter-spacing-t', letterSpacingMobile:'letter-spacing-m',
10 wordSpacingDesktop:'word-spacing-d', wordSpacingTablet:'word-spacing-t', wordSpacingMobile:'word-spacing-m'
11 };
12 function typoCssVarsForEl(el, obj, prefix) {
13 if (!obj || typeof obj !== 'object') return;
14 Object.keys(_typoKeys).forEach(function (k) {
15 var v = obj[k];
16 if (v === undefined || v === '' || v === null) return;
17 if (k === 'sizeDesktop' || k === 'sizeTablet' || k === 'sizeMobile') v = v + (obj.sizeUnit || 'px');
18 else if (k === 'lineHeightDesktop' || k === 'lineHeightTablet' || k === 'lineHeightMobile') v = v + (obj.lineHeightUnit || '');
19 else if (k === 'letterSpacingDesktop' || k === 'letterSpacingTablet' || k === 'letterSpacingMobile') v = v + (obj.letterSpacingUnit || 'px');
20 else if (k === 'wordSpacingDesktop' || k === 'wordSpacingTablet' || k === 'wordSpacingMobile') v = v + (obj.wordSpacingUnit || 'px');
21 el.style.setProperty(prefix + _typoKeys[k], String(v));
22 });
23 }
24
25 function setCookie(name, val, days) {
26 var d = new Date();
27 d.setTime(d.getTime() + days * 24 * 60 * 60 * 1000);
28 document.cookie = name + '=' + val + ';expires=' + d.toUTCString() + ';path=/';
29 }
30
31 function getCookie(name) {
32 var n = name + '=', ca = document.cookie.split(';');
33 for (var i = 0; i < ca.length; i++) {
34 var c = ca[i].trim();
35 if (c.indexOf(n) === 0) return c.substring(n.length);
36 }
37 return '';
38 }
39
40 function applyCSS(el, styles) {
41 Object.keys(styles).forEach(function (k) { el.style[k] = styles[k]; });
42 }
43
44 function formatCountdown(ms) {
45 if (ms <= 0) return '00:00:00';
46 var s = Math.floor(ms / 1000);
47 var d = Math.floor(s / 86400);
48 s %= 86400;
49 var h = Math.floor(s / 3600);
50 s %= 3600;
51 var m = Math.floor(s / 60);
52 s %= 60;
53 if (d > 0) return d + 'd ' + pad(h) + ':' + pad(m) + ':' + pad(s);
54 return pad(h) + ':' + pad(m) + ':' + pad(s);
55 }
56
57 function pad(n) { return (n < 10 ? '0' : '') + n; }
58
59 function init() {
60 document.querySelectorAll('.bkbg-rbnr-app').forEach(function (appEl) {
61 if (appEl.dataset.rendered) return;
62 appEl.dataset.rendered = '1';
63
64 var opts;
65 try { opts = JSON.parse(appEl.dataset.opts || '{}'); } catch (e) { opts = {}; }
66
67 var o = Object.assign({
68 messages: [],
69 autoPlay: true,
70 interval: 5000,
71 animationType: 'slide',
72 showArrows: true,
73 showDots: true,
74 showClose: true,
75 cookieDays: 7,
76 height: 44,
77 fontSize: 14,
78 fontWeight: '500',
79 linkStyle: 'inline',
80 arrowBg: 'rgba(0,0,0,0.15)',
81 arrowColor: '#ffffff',
82 dotColor: 'rgba(255,255,255,0.4)',
83 dotActiveColor: '#ffffff',
84 closeBg: 'rgba(0,0,0,0.15)',
85 closeColor: '#ffffff'
86 }, opts);
87
88 var msgs = o.messages;
89 if (!msgs || msgs.length === 0) return;
90
91 /* Check cookie dismiss */
92 var cookieName = 'bkbg_rbnr_' + (appEl.dataset.uid || btoa(JSON.stringify(msgs)).slice(0, 12));
93 if (o.showClose && o.cookieDays > 0 && getCookie(cookieName) === 'dismissed') return;
94
95 var activeIdx = 0;
96 var autoTimer = null;
97
98 /* ── Outer wrap ── */
99 var wrap = document.createElement('div');
100 wrap.className = 'bkbg-rbnr-wrap' + (o.showClose ? ' has-close' : '');
101 wrap.dataset.anim = o.animationType;
102 typoCssVarsForEl(wrap, o.messageTypo, '--bkrbnr-mt-');
103
104 /* ── Viewport ── */
105 var viewport = document.createElement('div');
106 viewport.className = 'bkbg-rbnr-viewport';
107 viewport.style.height = o.height + 'px';
108
109 /* ── Track (slides) ── */
110 var track = document.createElement('div');
111 track.className = 'bkbg-rbnr-track';
112 if (o.animationType !== 'fade') {
113 track.style.height = o.height + 'px';
114 }
115
116 var slides = [];
117 var cdTimers = []; /* countdown interval refs per slide */
118
119 msgs.forEach(function (msg, idx) {
120 var slide = document.createElement('div');
121 slide.className = 'bkbg-rbnr-slide' + (idx === 0 && o.animationType === 'fade' ? ' is-active' : '');
122 applyCSS(slide, {
123 background: msg.bgColor || '#6366f1',
124 color: msg.textColor || '#ffffff',
125 height: o.height + 'px',
126 padding: o.showArrows ? '0 ' + (o.showClose ? '76px' : '48px') : (o.showClose ? '0 32px' : '0 16px'),
127 boxSizing: 'border-box'
128 });
129
130 /* Content */
131 var content = document.createElement('div');
132 content.className = 'bkbg-rbnr-content';
133
134 var textEl = document.createElement('span');
135 textEl.className = 'bkbg-rbnr-text';
136 textEl.textContent = msg.text || '';
137 content.appendChild(textEl);
138
139 /* Link */
140 if (msg.linkLabel && msg.linkUrl && o.linkStyle !== 'none') {
141 var link = document.createElement('a');
142 link.textContent = msg.linkLabel;
143 link.href = msg.linkUrl || '#';
144 link.target = msg.linkTarget || '_self';
145 if (o.linkStyle === 'button') {
146 link.className = 'bkbg-rbnr-link-btn';
147 link.style.background = msg.textColor || '#ffffff';
148 link.style.color = msg.bgColor || '#6366f1';
149 } else {
150 link.className = 'bkbg-rbnr-link-inline';
151 }
152 content.appendChild(link);
153 }
154
155 /* Countdown */
156 if (msg.countdownTo) {
157 var target = new Date(msg.countdownTo).getTime();
158 if (!isNaN(target)) {
159 var cdEl = document.createElement('span');
160 cdEl.className = 'bkbg-rbnr-countdown';
161 cdEl.textContent = formatCountdown(target - Date.now());
162 content.appendChild(cdEl);
163 cdTimers[idx] = setInterval(function () {
164 cdEl.textContent = formatCountdown(target - Date.now());
165 }, 1000);
166 }
167 }
168
169 slide.appendChild(content);
170 track.appendChild(slide);
171 slides.push(slide);
172 });
173
174 viewport.appendChild(track);
175 wrap.appendChild(viewport);
176
177 /* ── Navigate ── */
178 function goTo(idx, suppressAuto) {
179 var next = (idx + msgs.length) % msgs.length;
180 if (o.animationType === 'fade') {
181 slides[activeIdx].classList.remove('is-active');
182 slides[next].classList.add('is-active');
183 } else {
184 track.style.transform = 'translateX(-' + (next * 100) + '%)';
185 }
186 /* Update dots */
187 if (dotBtns.length) {
188 dotBtns[activeIdx].style.background = o.dotColor;
189 dotBtns[next].style.background = o.dotActiveColor;
190 }
191 activeIdx = next;
192 if (!suppressAuto) resetAuto();
193 }
194
195 /* ── Auto-play ── */
196 function resetAuto() {
197 if (autoTimer) clearInterval(autoTimer);
198 if (o.autoPlay && msgs.length > 1) {
199 autoTimer = setInterval(function () { goTo(activeIdx + 1, true); }, o.interval);
200 }
201 }
202
203 resetAuto();
204
205 /* ── Arrows ── */
206 if (o.showArrows && msgs.length > 1) {
207 var prevBtn = document.createElement('button');
208 prevBtn.className = 'bkbg-rbnr-arrow is-prev';
209 prevBtn.innerHTML = '&#8249;';
210 applyCSS(prevBtn, { background: o.arrowBg, color: o.arrowColor });
211 prevBtn.addEventListener('click', function () { goTo(activeIdx - 1); });
212 wrap.appendChild(prevBtn);
213
214 var nextBtn = document.createElement('button');
215 nextBtn.className = 'bkbg-rbnr-arrow is-next';
216 nextBtn.innerHTML = '&#8250;';
217 applyCSS(nextBtn, { background: o.arrowBg, color: o.arrowColor });
218 nextBtn.addEventListener('click', function () { goTo(activeIdx + 1); });
219 wrap.appendChild(nextBtn);
220 }
221
222 /* ── Dots ── */
223 var dotBtns = [];
224 if (o.showDots && msgs.length > 1) {
225 var dotsEl = document.createElement('div');
226 dotsEl.className = 'bkbg-rbnr-dots';
227 msgs.forEach(function (_, di) {
228 var dot = document.createElement('button');
229 dot.className = 'bkbg-rbnr-dot';
230 dot.style.background = di === 0 ? o.dotActiveColor : o.dotColor;
231 dot.addEventListener('click', function () { goTo(di); });
232 dotsEl.appendChild(dot);
233 dotBtns.push(dot);
234 });
235 wrap.appendChild(dotsEl);
236 }
237
238 /* ── Close button ── */
239 if (o.showClose) {
240 var closeBtn = document.createElement('button');
241 closeBtn.className = 'bkbg-rbnr-close';
242 closeBtn.innerHTML = '&times;';
243 applyCSS(closeBtn, { background: o.closeBg, color: o.closeColor });
244 closeBtn.addEventListener('click', function () {
245 wrap.classList.add('is-dismissed');
246 if (autoTimer) clearInterval(autoTimer);
247 cdTimers.forEach(function (t) { if (t) clearInterval(t); });
248 if (o.cookieDays > 0) setCookie(cookieName, 'dismissed', o.cookieDays);
249 });
250 wrap.appendChild(closeBtn);
251 }
252
253 /* ── Keyboard ── */
254 wrap.setAttribute('tabindex', '0');
255 wrap.addEventListener('keydown', function (e) {
256 if (e.key === 'ArrowLeft') goTo(activeIdx - 1);
257 if (e.key === 'ArrowRight') goTo(activeIdx + 1);
258 });
259
260 appEl.parentNode.insertBefore(wrap, appEl);
261 appEl.style.display = 'none';
262 });
263 }
264
265 if (document.readyState !== 'loading') { init(); }
266 else { document.addEventListener('DOMContentLoaded', init); }
267 })();
268