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 / feature-announcement / frontend.js

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

228 lines 9.9 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 function typoCssVarsForEl(typo, prefix, el) {
5 if (!typo || typeof typo !== 'object') return;
6 var m = {
7 family: 'font-family', weight: 'font-weight',
8 transform: 'text-transform', style: 'font-style', decoration: 'text-decoration'
9 };
10 Object.keys(m).forEach(function (k) {
11 if (typo[k]) el.style.setProperty(prefix + m[k], typo[k]);
12 });
13 var r = {
14 size: 'font-size', lineHeight: 'line-height',
15 letterSpacing: 'letter-spacing', wordSpacing: 'word-spacing'
16 };
17 Object.keys(r).forEach(function (k) {
18 ['Desktop', 'Tablet', 'Mobile'].forEach(function (d, i) {
19 var v = typo[k + d];
20 if (v === undefined || v === '') return;
21 var suffix = ['-d', '-t', '-m'][i];
22 var unit = typo[k + 'Unit'] || ('size' === k ? 'px' : (k === 'lineHeight' ? '' : 'px'));
23 el.style.setProperty(prefix + r[k] + suffix, v + unit);
24 });
25 });
26 }
27
28 function mk(tag, cls, styles) {
29 var d = document.createElement(tag);
30 if (cls) d.className = cls;
31 if (styles) Object.keys(styles).forEach(function (k) { d.style[k] = styles[k]; });
32 return d;
33 }
34 function tx(tag, cls, text, styles) {
35 var d = mk(tag, cls, styles);
36 d.textContent = text;
37 return d;
38 }
39 function ap(parent) {
40 Array.prototype.slice.call(arguments, 1).forEach(function (c) { if (c) parent.appendChild(c); });
41 return parent;
42 }
43
44 var categoryLabels = {
45 'new-feature': '🆕 New Feature',
46 'improvement': '⚡ Improvement',
47 'bugfix': '🐛 Bug Fix',
48 'deprecation': '⚠️ Deprecation',
49 'security': '🔒 Security',
50 'integration': '📦 Integration'
51 };
52 var statusLabels = {
53 'available': '�
54 Available Now',
55 'beta': '🧪 Beta',
56 'coming-soon': '🚀 Coming Soon',
57 'deprecated': '⚠️ Deprecated'
58 };
59
60 function init() {
61 document.querySelectorAll('.bkbg-feature-announcement-app').forEach(function (appEl) {
62 if (appEl.dataset.rendered) return;
63 appEl.dataset.rendered = '1';
64
65 var opts;
66 try { opts = JSON.parse(appEl.dataset.opts || '{}'); } catch (e) { opts = {}; }
67
68 var o = Object.assign({
69 featureName: 'Feature Name', version: 'v1.0', showVersion: true,
70 releaseDate: '', showDate: false,
71 category: 'new-feature', status: 'available',
72 featureIcon: '', showIcon: true,
73 tagline: '', description: '', showDescription: true,
74 highlights: [], showHighlights: true, highlightsLabel: "What's new",
75 availablePlans: [], showPlans: true, plansLabel: 'Available on',
76 ctaText: '', ctaUrl: '#', showCta: true,
77 ctaSecondaryText: '', ctaSecondaryUrl: '#', showSecondaryCta: false,
78 accentPosition: 'top',
79 fontSize: 15, featureNameSize: 26, taglineSize: 16,
80 lineHeight: 170, borderRadius: 12,
81 bgColor: '#ffffff', borderColor: '#e2e8f0',
82 accentColor: '#7c3aed', accentStripe: '#7c3aed',
83 featureNameColor: '#0f172a', taglineColor: '#374151', textColor: '#4b5563',
84 versionBg: '#ede9fe', versionColor: '#5b21b6',
85 categoryBg: '#f0fdf4', categoryColor: '#14532d',
86 statusBg: '#dcfce7', statusColor: '#14532d',
87 highlightIconColor: '#7c3aed',
88 planBg: '#f5f3ff', planColor: '#5b21b6',
89 ctaBg: '#7c3aed', ctaColor: '#ffffff',
90 ctaSecondaryColor: '#7c3aed'
91 }, opts);
92
93 // ── Block container ───────────────────────────────────
94 var block = mk('div', 'bkbg-fan-block' + (o.accentPosition === 'left' ? ' has-accent-left' : ''), {
95 background: o.bgColor,
96 border: '1px solid ' + o.borderColor,
97 borderRadius: o.borderRadius + 'px',
98 overflow: 'hidden',
99 position: 'relative'
100 });
101 typoCssVarsForEl(o.typoName, '--bkbg-fan-nm-', block);
102 typoCssVarsForEl(o.typoTagline, '--bkbg-fan-tl-', block);
103 typoCssVarsForEl(o.typoBody, '--bkbg-fan-bd-', block);
104
105 // ── Accent stripes ────────────────────────────────────
106 if (o.accentPosition === 'top') {
107 ap(block, mk('div', 'bkbg-fan-accent-top', { background: o.accentStripe }));
108 } else if (o.accentPosition === 'left') {
109 ap(block, mk('div', 'bkbg-fan-accent-left', { background: o.accentStripe }));
110 }
111
112 // ── Inner ─────────────────────────────────────────────
113 var inner = mk('div', 'bkbg-fan-inner');
114
115 // Meta badges row
116 var meta = mk('div', 'bkbg-fan-meta');
117 if (o.showIcon && o.featureIcon) {
118 var fanIconType = o.featureIconType || 'custom-char';
119 var fanIconSpan = mk('span', 'bkbg-fan-icon');
120 if (fanIconType !== 'custom-char' && window.bkbgIconPicker) {
121 fanIconSpan.appendChild(window.bkbgIconPicker.buildFrontendIcon(fanIconType, o.featureIcon, o.featureIconDashicon, o.featureIconImageUrl, o.featureIconDashiconColor));
122 } else {
123 fanIconSpan.textContent = o.featureIcon;
124 }
125 ap(meta, fanIconSpan);
126 }
127 // Category badge
128 var catLabel = categoryLabels[o.category] || o.category;
129 var catBadge = tx('span', 'bkbg-fan-badge', catLabel, { background: o.categoryBg, color: o.categoryColor });
130 ap(meta, catBadge);
131 // Version badge
132 if (o.showVersion && o.version) {
133 ap(meta, tx('span', 'bkbg-fan-badge', o.version, { background: o.versionBg, color: o.versionColor }));
134 }
135 // Status badge
136 var stLabel = statusLabels[o.status] || o.status;
137 ap(meta, tx('span', 'bkbg-fan-badge', stLabel, { background: o.statusBg, color: o.statusColor }));
138 // Date
139 if (o.showDate && o.releaseDate) {
140 ap(meta, tx('span', 'bkbg-fan-date', o.releaseDate));
141 }
142 ap(inner, meta);
143
144 // Feature name
145 ap(inner, tx('h2', 'bkbg-fan-name', o.featureName, {
146 color: o.featureNameColor
147 }));
148
149 // Tagline
150 if (o.tagline) {
151 ap(inner, tx('p', 'bkbg-fan-tagline', o.tagline, {
152 color: o.taglineColor
153 }));
154 }
155
156 // Description
157 if (o.showDescription && o.description) {
158 ap(inner, tx('p', 'bkbg-fan-description', o.description, {
159 color: o.textColor
160 }));
161 }
162
163 // Highlights
164 if (o.showHighlights && o.highlights && o.highlights.length > 0) {
165 var hlWrap = mk('div');
166 var hlLabel = tx('div', 'bkbg-fan-highlights-label', o.highlightsLabel || "What's new", { color: o.accentColor });
167 var hlList = mk('ul', 'bkbg-fan-highlights');
168 o.highlights.forEach(function (h) {
169 if (!h) return;
170 var li = mk('li', 'bkbg-fan-highlight');
171 var icon = tx('span', 'bkbg-fan-highlight-icon', '', { color: o.highlightIconColor });
172 var text = tx('span', '', h, { color: o.textColor });
173 ap(li, icon, text);
174 ap(hlList, li);
175 });
176 ap(hlWrap, hlLabel, hlList);
177 ap(inner, hlWrap);
178 }
179
180 // Plans
181 if (o.showPlans && o.availablePlans && o.availablePlans.length > 0) {
182 var plansRow = mk('div', 'bkbg-fan-plans');
183 ap(plansRow, tx('span', 'bkbg-fan-plans-label', (o.plansLabel || 'Available on') + ':'));
184 o.availablePlans.forEach(function (plan) {
185 if (!plan) return;
186 ap(plansRow, tx('span', 'bkbg-fan-plan-badge', plan, { background: o.planBg, color: o.planColor }));
187 });
188 ap(inner, plansRow);
189 }
190
191 // CTAs
192 var ctas = mk('div', 'bkbg-fan-ctas');
193 if (o.showCta && o.ctaText) {
194 var primaryCta = mk('a', 'bkbg-fan-cta', {
195 background: o.ctaBg,
196 color: o.ctaColor,
197 padding: '11px 22px',
198 borderRadius: o.borderRadius + 'px'
199 });
200 primaryCta.textContent = o.ctaText;
201 primaryCta.href = o.ctaUrl || '#';
202 ap(ctas, primaryCta);
203 }
204 if (o.showSecondaryCta && o.ctaSecondaryText) {
205 var secondaryCta = mk('a', 'bkbg-fan-cta is-secondary', {
206 borderColor: o.ctaSecondaryColor,
207 color: o.ctaSecondaryColor,
208 padding: '9px 22px',
209 borderRadius: o.borderRadius + 'px'
210 });
211 secondaryCta.textContent = o.ctaSecondaryText;
212 secondaryCta.href = o.ctaSecondaryUrl || '#';
213 ap(ctas, secondaryCta);
214 }
215 if (ctas.children.length > 0) {
216 ap(inner, ctas);
217 }
218
219 ap(block, inner);
220 appEl.parentNode.insertBefore(block, appEl);
221 appEl.style.display = 'none';
222 });
223 }
224
225 if (document.readyState !== 'loading') { init(); }
226 else { document.addEventListener('DOMContentLoaded', init); }
227 })();
228