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 / testimonial-marquee / frontend.js

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

206 lines 7.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 (function () {
2 var AVATAR_COLORS = ['#6366f1', '#8b5cf6', '#ec4899', '#14b8a6', '#f59e0b', '#ef4444'];
3
4 function strHash(s) {
5 var h = 0;
6 for (var i = 0; i < s.length; i++) { h = (h + s.charCodeAt(i)) | 0; }
7 return Math.abs(h);
8 }
9
10 function buildCard(item, o) {
11 var shadow = o.cardShadow === 'sm' ? '0 1px 6px rgba(0,0,0,0.07)'
12 : o.cardShadow === 'md' ? '0 4px 16px rgba(0,0,0,0.10)'
13 : o.cardShadow === 'lg' ? '0 8px 32px rgba(0,0,0,0.13)' : 'none';
14
15 var card = document.createElement('div');
16 card.className = 'bkbg-tm-card';
17 card.style.cssText = [
18 'width:' + o.cardWidth + 'px',
19 'background:' + (o.cardBg || '#fff'),
20 'border:1px solid ' + (o.cardBorder || '#e5e7eb'),
21 'border-radius:' + o.cardRadius + 'px',
22 'padding:' + o.cardPadding + 'px',
23 'box-shadow:' + shadow,
24 'gap:12px',
25 ].join(';');
26
27 // Big quote icon in background
28 var qIcon = document.createElement('div');
29 qIcon.className = 'bkbg-tm-quote-bg';
30 qIcon.textContent = '\u201C';
31 qIcon.style.color = o.quoteIconColor || '#e0e7ff';
32 card.appendChild(qIcon);
33
34 // Stars
35 if (o.showStars) {
36 var starsDiv = document.createElement('div');
37 starsDiv.className = 'bkbg-tm-stars';
38 for (var s = 1; s <= 5; s++) {
39 var star = document.createElement('span');
40 star.textContent = '\u2605';
41 star.style.color = s <= item.rating ? (o.starColor || '#f59e0b') : '#e5e7eb';
42 star.style.fontSize = '14px';
43 star.style.lineHeight = '1';
44 starsDiv.appendChild(star);
45 }
46 card.appendChild(starsDiv);
47 }
48
49 // Quote text
50 var quoteEl = document.createElement('p');
51 quoteEl.className = 'bkbg-tm-quote';
52 quoteEl.textContent = item.quote;
53 quoteEl.style.color = o.quoteColor || '#374151';
54 card.appendChild(quoteEl);
55
56 // Author row
57 var authorRow = document.createElement('div');
58 authorRow.className = 'bkbg-tm-author-row';
59 authorRow.style.gap = '10px';
60
61 if (o.showAvatar) {
62 if (item.avatarUrl) {
63 var img = document.createElement('img');
64 img.className = 'bkbg-tm-avatar';
65 img.src = item.avatarUrl;
66 img.alt = item.author;
67 img.style.width = o.avatarSize + 'px';
68 img.style.height = o.avatarSize + 'px';
69 authorRow.appendChild(img);
70 } else {
71 var initials = (item.author || 'A').split(' ').map(function (w) { return w[0]; }).slice(0, 2).join('').toUpperCase();
72 var fallback = document.createElement('div');
73 fallback.className = 'bkbg-tm-avatar-fallback';
74 fallback.textContent = initials;
75 fallback.style.width = o.avatarSize + 'px';
76 fallback.style.height = o.avatarSize + 'px';
77 fallback.style.fontSize = Math.round(o.avatarSize * 0.38) + 'px';
78 fallback.style.background = AVATAR_COLORS[strHash(item.author || '') % AVATAR_COLORS.length];
79 authorRow.appendChild(fallback);
80 }
81 }
82
83 var info = document.createElement('div');
84 info.className = 'bkbg-tm-author-info';
85
86 var nameEl = document.createElement('div');
87 nameEl.className = 'bkbg-tm-author-name';
88 nameEl.textContent = item.author;
89 nameEl.style.color = o.authorColor || '#111827';
90 info.appendChild(nameEl);
91
92 var metaParts = [];
93 if (o.showRole && item.role) metaParts.push(item.role);
94 if (o.showCompany && item.company) metaParts.push(item.company);
95 if (metaParts.length) {
96 var metaEl = document.createElement('div');
97 metaEl.className = 'bkbg-tm-author-meta';
98 metaEl.textContent = metaParts.join(', ');
99 metaEl.style.color = o.roleColor || '#6b7280';
100 info.appendChild(metaEl);
101 }
102
103 authorRow.appendChild(info);
104 card.appendChild(authorRow);
105 return card;
106 }
107
108 function buildTrack(items, o, direction) {
109 // Duplicate items for seamless loop
110 var allItems = items.concat(items);
111 var track = document.createElement('div');
112 track.className = 'bkbg-tm-track dir-' + direction;
113 track.style.gap = o.cardGap + 'px';
114 track.style.animationDuration = o.speed + 's';
115
116 allItems.forEach(function (item) {
117 track.appendChild(buildCard(item, o));
118 });
119 return track;
120 }
121
122 function buildRow(items, o, direction) {
123 var row = document.createElement('div');
124 row.className = 'bkbg-tm-row';
125 var viewport = document.createElement('div');
126 viewport.className = 'bkbg-tm-viewport' + (o.fadeEdges ? ' fade-edges' : '');
127 var track = buildTrack(items, o, direction);
128 viewport.appendChild(track);
129 row.appendChild(viewport);
130 return row;
131 }
132
133 function init() {
134 document.querySelectorAll('.bkbg-tm-app').forEach(function (appEl) {
135 if (appEl.dataset.rendered) return;
136 appEl.dataset.rendered = '1';
137
138 var opts;
139 try { opts = JSON.parse(appEl.dataset.opts || '{}'); } catch (e) { opts = {}; }
140 var o = Object.assign({
141 items: [],
142 rows: 1,
143 speed: 60,
144 direction: 'left',
145 pauseOnHover: true,
146 fadeEdges: true,
147 showStars: true,
148 showAvatar: true,
149 showRole: true,
150 showCompany: true,
151 cardWidth: 340,
152 cardGap: 20,
153 cardRadius: 14,
154 cardPadding: 24,
155 quoteSize: 15,
156 avatarSize: 44,
157 paddingY: 40,
158 cardShadow: 'sm',
159 wrapperBg: '',
160 cardBg: '#ffffff',
161 cardBorder: '#e5e7eb',
162 quoteColor: '#374151',
163 starColor: '#f59e0b',
164 authorColor: '#111827',
165 roleColor: '#6b7280',
166 quoteIconColor: '#e0e7ff',
167 }, opts);
168
169 if (!o.items || !o.items.length) return;
170
171 var outer = document.createElement('div');
172 outer.className = 'bkbg-tm-outer';
173 if (o.wrapperBg) outer.style.background = o.wrapperBg;
174 outer.style.padding = o.paddingY + 'px 0';
175
176 var rowGap = o.cardGap;
177 if (o.rows === 2) {
178 outer.style.display = 'flex';
179 outer.style.flexDirection = 'column';
180 outer.style.gap = rowGap + 'px';
181 }
182
183 // Row 1
184 outer.appendChild(buildRow(o.items, o, o.direction));
185
186 // Row 2 — opposite direction
187 if (o.rows === 2) {
188 var dir2 = o.direction === 'left' ? 'right' : 'left';
189 outer.appendChild(buildRow(o.items, o, dir2));
190 }
191
192 // Pause on hover
193 if (o.pauseOnHover) {
194 outer.addEventListener('mouseenter', function () { outer.classList.add('paused'); });
195 outer.addEventListener('mouseleave', function () { outer.classList.remove('paused'); });
196 }
197
198 appEl.parentNode.insertBefore(outer, appEl);
199 appEl.style.display = 'none';
200 });
201 }
202
203 if (document.readyState !== 'loading') { init(); }
204 else { document.addEventListener('DOMContentLoaded', init); }
205 })();
206