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 / product-roundup / frontend.js

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

279 lines 12.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 (function () {
2 function esc(str) {
3 return String(str || '').replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;').replace(/"/g,'&quot;');
4 }
5
6 function starsHTML(rating, color) {
7 var full = Math.floor(rating);
8 var half = (rating - full) >= 0.5;
9 var html = '<span class="bkbg-pru-stars" style="color:' + esc(color) + '">';
10 for (var i = 0; i < 5; i++) {
11 if (i < full) html += '�
12 ';
13 else if (i === full && half) html += '½';
14 else html += '';
15 }
16 html += '</span><span class="bkbg-pru-rating-num">(' + Number(rating).toFixed(1) + ')</span>';
17 return html;
18 }
19
20 var _typoKeys = {
21 family:'font-family', weight:'font-weight', style:'font-style',
22 decoration:'text-decoration', transform:'text-transform',
23 sizeDesktop:'font-size-d', sizeTablet:'font-size-t', sizeMobile:'font-size-m',
24 lineHeightDesktop:'line-height-d', lineHeightTablet:'line-height-t', lineHeightMobile:'line-height-m',
25 letterSpacingDesktop:'letter-spacing-d', letterSpacingTablet:'letter-spacing-t', letterSpacingMobile:'letter-spacing-m',
26 wordSpacingDesktop:'word-spacing-d', wordSpacingTablet:'word-spacing-t', wordSpacingMobile:'word-spacing-m'
27 };
28 function typoCssVarsForEl(el, obj, prefix) {
29 if (!obj || typeof obj !== 'object') return;
30 Object.keys(_typoKeys).forEach(function (k) {
31 var v = obj[k];
32 if (v === undefined || v === '' || v === null) return;
33 if (k === 'sizeDesktop' || k === 'sizeTablet' || k === 'sizeMobile') v = v + (obj.sizeUnit || 'px');
34 else if (k === 'lineHeightDesktop' || k === 'lineHeightTablet' || k === 'lineHeightMobile') v = v + (obj.lineHeightUnit || '');
35 else if (k === 'letterSpacingDesktop' || k === 'letterSpacingTablet' || k === 'letterSpacingMobile') v = v + (obj.letterSpacingUnit || 'px');
36 else if (k === 'wordSpacingDesktop' || k === 'wordSpacingTablet' || k === 'wordSpacingMobile') v = v + (obj.wordSpacingUnit || 'px');
37 el.style.setProperty(prefix + _typoKeys[k], String(v));
38 });
39 }
40
41 function init() {
42 document.querySelectorAll('.bkbg-pru-app').forEach(function (el) {
43 if (el.dataset.rendered) return;
44 el.dataset.rendered = '1';
45
46 var opts;
47 try { opts = JSON.parse(el.dataset.opts || '{}'); } catch (e) { opts = {}; }
48
49 var o = Object.assign({
50 sectionTitle: 'Our Top Picks',
51 sectionSubtitle: '',
52 showSubtitle: true,
53 products: [],
54 layout: 'list',
55 showRank: true,
56 showRating: true,
57 showPros: true,
58 showCons: true,
59 showPrice: true,
60 showImage: true,
61 openInNewTab: true,
62 bgColor: '#ffffff',
63 borderColor: '#e2e8f0',
64 headingColor: '#0f172a',
65 subtitleColor: '#64748b',
66 cardBg: '#ffffff',
67 cardBorder: '#e2e8f0',
68 rankBg: '#0f172a',
69 rankColor: '#ffffff',
70 badgeBg: '#f59e0b',
71 badgeColor: '#ffffff',
72 nameColor: '#0f172a',
73 ratingColor: '#f59e0b',
74 summaryColor: '#475569',
75 prosColor: '#16a34a',
76 consColor: '#dc2626',
77 priceColor: '#0f172a',
78 ctaBg: '#0f172a',
79 ctaColor: '#ffffff',
80 borderRadius: 10,
81 cardRadius: 8,
82 paddingTop: 0,
83 paddingBottom: 0
84 }, opts);
85
86 var wrap = document.createElement('div');
87 wrap.className = 'bkbg-pru-wrap';
88 wrap.style.cssText = [
89 'background:' + o.bgColor,
90 'border-radius:' + o.borderRadius + 'px',
91 'padding-top:' + o.paddingTop + 'px',
92 'padding-bottom:' + o.paddingBottom + 'px'
93 ].join(';');
94
95 typoCssVarsForEl(wrap, o.titleTypo, '--bkbg-pru-tt-');
96 typoCssVarsForEl(wrap, o.subtitleTypo, '--bkbg-pru-st-');
97 typoCssVarsForEl(wrap, o.nameTypo, '--bkbg-pru-nm-');
98 typoCssVarsForEl(wrap, o.summaryTypo, '--bkbg-pru-sm-');
99
100 /* header */
101 if (o.sectionTitle) {
102 var h2 = document.createElement('h2');
103 h2.className = 'bkbg-pru-title';
104 h2.style.color = o.headingColor;
105 h2.innerHTML = o.sectionTitle;
106 wrap.appendChild(h2);
107 }
108 if (o.showSubtitle && o.sectionSubtitle) {
109 var sub = document.createElement('p');
110 sub.className = 'bkbg-pru-subtitle';
111 sub.style.color = o.subtitleColor;
112 sub.innerHTML = o.sectionSubtitle;
113 wrap.appendChild(sub);
114 }
115
116 /* grid */
117 var grid = document.createElement('div');
118 grid.className = 'bkbg-pru-grid ' + (o.layout === 'grid' ? 'bkbg-pru-grid-2col' : 'bkbg-pru-list');
119
120 (o.products || []).forEach(function (prod, idx) {
121 var card = document.createElement('div');
122 card.className = 'bkbg-pru-card';
123 card.style.cssText = [
124 'background:' + o.cardBg,
125 'border:1px solid ' + o.cardBorder,
126 'border-radius:' + o.cardRadius + 'px'
127 ].join(';');
128 if (idx === 0 && o.showRank) {
129 card.style.borderTop = '3px solid ' + o.badgeBg;
130 }
131
132 /* header row */
133 var head = document.createElement('div');
134 head.className = 'bkbg-pru-card-header';
135
136 if (o.showRank) {
137 var rankEl = document.createElement('div');
138 rankEl.className = 'bkbg-pru-rank';
139 rankEl.style.cssText = 'background:' + o.rankBg + ';color:' + o.rankColor;
140 rankEl.textContent = '#' + (prod.rank || idx + 1);
141 head.appendChild(rankEl);
142 }
143
144 if (o.showImage && prod.image) {
145 var img = document.createElement('img');
146 img.className = 'bkbg-pru-image';
147 img.src = prod.image;
148 img.alt = esc(prod.name || '');
149 img.loading = 'lazy';
150 head.appendChild(img);
151 }
152
153 var meta = document.createElement('div');
154 meta.className = 'bkbg-pru-meta';
155
156 var nameRow = document.createElement('div');
157 nameRow.className = 'bkbg-pru-name-row';
158
159 var nameEl = document.createElement('span');
160 nameEl.className = 'bkbg-pru-name';
161 nameEl.style.color = o.nameColor;
162 nameEl.innerHTML = prod.name || '';
163 nameRow.appendChild(nameEl);
164
165 if (prod.showBadge && prod.badge) {
166 var badge = document.createElement('span');
167 badge.className = 'bkbg-pru-badge';
168 badge.style.cssText = 'background:' + o.badgeBg + ';color:' + o.badgeColor;
169 badge.textContent = prod.badge;
170 nameRow.appendChild(badge);
171 }
172 meta.appendChild(nameRow);
173
174 if (o.showRating) {
175 var ratingEl = document.createElement('div');
176 ratingEl.innerHTML = starsHTML(prod.rating || 0, o.ratingColor);
177 meta.appendChild(ratingEl);
178 }
179 head.appendChild(meta);
180 card.appendChild(head);
181
182 /* body */
183 var body = document.createElement('div');
184 body.className = 'bkbg-pru-card-body';
185
186 if (prod.summary) {
187 var sumEl = document.createElement('p');
188 sumEl.className = 'bkbg-pru-summary';
189 sumEl.style.color = o.summaryColor;
190 sumEl.innerHTML = prod.summary;
191 body.appendChild(sumEl);
192 }
193
194 if ((o.showPros && (prod.pros || []).some(Boolean)) || (o.showCons && (prod.cons || []).some(Boolean))) {
195 var pcGrid = document.createElement('div');
196 pcGrid.className = 'bkbg-pru-pros-cons';
197
198 if (o.showPros) {
199 var prosDiv = document.createElement('div');
200 prosDiv.className = 'bkbg-pru-pros';
201 var prosLabel = document.createElement('div');
202 prosLabel.className = 'bkbg-pru-pc-label';
203 prosLabel.style.color = o.prosColor;
204 prosLabel.textContent = '✓ Pros';
205 prosDiv.appendChild(prosLabel);
206 var prosList = document.createElement('ul');
207 prosList.className = 'bkbg-pru-pc-list';
208 (prod.pros || []).filter(Boolean).forEach(function (pro) {
209 var li = document.createElement('li');
210 li.className = 'bkbg-pru-pc-item';
211 li.style.color = o.summaryColor;
212 li.textContent = pro;
213 prosList.appendChild(li);
214 });
215 prosDiv.appendChild(prosList);
216 pcGrid.appendChild(prosDiv);
217 }
218
219 if (o.showCons) {
220 var consDiv = document.createElement('div');
221 consDiv.className = 'bkbg-pru-cons';
222 var consLabel = document.createElement('div');
223 consLabel.className = 'bkbg-pru-pc-label';
224 consLabel.style.color = o.consColor;
225 consLabel.textContent = '✗ Cons';
226 consDiv.appendChild(consLabel);
227 var consList = document.createElement('ul');
228 consList.className = 'bkbg-pru-pc-list';
229 (prod.cons || []).filter(Boolean).forEach(function (con) {
230 var li = document.createElement('li');
231 li.className = 'bkbg-pru-pc-item';
232 li.style.color = o.summaryColor;
233 li.textContent = con;
234 consList.appendChild(li);
235 });
236 consDiv.appendChild(consList);
237 pcGrid.appendChild(consDiv);
238 }
239
240 body.appendChild(pcGrid);
241 }
242 card.appendChild(body);
243
244 /* footer */
245 var footer = document.createElement('div');
246 footer.className = 'bkbg-pru-card-footer';
247 footer.style.borderTopColor = o.cardBorder;
248
249 var priceEl = document.createElement('span');
250 if (o.showPrice && prod.price) {
251 priceEl.className = 'bkbg-pru-price';
252 priceEl.style.color = o.priceColor;
253 priceEl.textContent = prod.price;
254 }
255 footer.appendChild(priceEl);
256
257 if (prod.ctaLabel && prod.ctaUrl) {
258 var cta = document.createElement('a');
259 cta.className = 'bkbg-pru-cta';
260 cta.href = prod.ctaUrl;
261 cta.textContent = prod.ctaLabel;
262 cta.style.cssText = 'background:' + o.ctaBg + ';color:' + o.ctaColor;
263 if (o.openInNewTab) { cta.target = '_blank'; cta.rel = 'noopener noreferrer'; }
264 footer.appendChild(cta);
265 }
266
267 card.appendChild(footer);
268 grid.appendChild(card);
269 });
270
271 wrap.appendChild(grid);
272 el.parentNode.insertBefore(wrap, el);
273 });
274 }
275
276 if (document.readyState !== 'loading') { init(); }
277 else { document.addEventListener('DOMContentLoaded', init); }
278 })();
279