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 / article-series / frontend.js

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

209 lines 9.4 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 map = {
7 family:'font-family', weight:'font-weight', style:'font-style',
8 decoration:'text-decoration', transform:'text-transform',
9 sizeDesktop:'font-size-d', sizeTablet:'font-size-t', sizeMobile:'font-size-m',
10 lineHeightDesktop:'line-height-d', lineHeightTablet:'line-height-t', lineHeightMobile:'line-height-m',
11 letterSpacingDesktop:'letter-spacing-d', letterSpacingTablet:'letter-spacing-t', letterSpacingMobile:'letter-spacing-m',
12 wordSpacingDesktop:'word-spacing-d', wordSpacingTablet:'word-spacing-t', wordSpacingMobile:'word-spacing-m'
13 };
14 Object.keys(map).forEach(function(k) {
15 if (typo[k] !== undefined && typo[k] !== '') {
16 var v = typo[k];
17 if (['sizeDesktop','sizeTablet','sizeMobile'].indexOf(k) !== -1) v = v + (typo.sizeUnit || 'px');
18 else if (['lineHeightDesktop','lineHeightTablet','lineHeightMobile'].indexOf(k) !== -1) v = v + (typo.lineHeightUnit || '');
19 else if (['letterSpacingDesktop','letterSpacingTablet','letterSpacingMobile'].indexOf(k) !== -1) v = v + (typo.letterSpacingUnit || 'px');
20 else if (['wordSpacingDesktop','wordSpacingTablet','wordSpacingMobile'].indexOf(k) !== -1) v = v + (typo.wordSpacingUnit || 'px');
21 el.style.setProperty(prefix + map[k], String(v));
22 }
23 });
24 }
25
26 function init() {
27 document.querySelectorAll('.bkbg-aser-app').forEach(function (appEl) {
28 if (appEl.dataset.rendered) return;
29 appEl.dataset.rendered = '1';
30
31 var opts;
32 try { opts = JSON.parse(appEl.dataset.opts || '{}'); } catch (e) { opts = {}; }
33 var o = Object.assign({
34 seriesTitle: 'Article Series',
35 seriesDescription: '',
36 currentPart: 1,
37 parts: [],
38 showProgress: true,
39 showExcerpt: true,
40 showNumbers: true,
41 showSeriesDescription: true,
42 layout: 'list',
43 borderRadius: 12,
44 bgColor: '#f8fafc',
45 borderColor: '#e2e8f0',
46 titleColor: '#0f172a',
47 descColor: '#64748b',
48 itemBg: '#ffffff',
49 itemColor: '#334155',
50 itemBorderColor: '#e2e8f0',
51 excerptColor: '#94a3b8',
52 currentBg: '#eff6ff',
53 currentColor: '#1d4ed8',
54 currentBorderColor: '#3b82f6',
55 accentColor: '#3b82f6',
56 progressBg: '#e2e8f0',
57 progressColor: '#3b82f6',
58 numberBg: '#e2e8f0',
59 numberColor: '#64748b',
60 currentNumberBg: '#3b82f6',
61 currentNumberColor: '#ffffff'
62 }, opts);
63
64 var total = o.parts.length;
65 var pct = total > 0 ? Math.round((o.currentPart / total) * 100) : 0;
66
67 // ── build block ──────────────────────────────────────────────────────
68 var block = document.createElement('div');
69 block.className = 'bkbg-aser-block';
70 block.style.background = o.bgColor;
71 block.style.borderColor = o.borderColor;
72 block.style.borderRadius = o.borderRadius + 'px';
73 block.style.setProperty('--bkbg-aser-title-sz', (o.titleFontSize || 20) + 'px');
74 block.style.setProperty('--bkbg-aser-desc-sz', (o.descFontSize || 14) + 'px');
75 block.style.setProperty('--bkbg-aser-pt-sz', (o.partTitleFontSize || 14) + 'px');
76 block.style.setProperty('--bkbg-aser-exc-sz', (o.excerptFontSize || 12) + 'px');
77 typoCssVarsForEl(o.titleTypo, '--bkbg-aser-title-', block);
78 typoCssVarsForEl(o.descTypo, '--bkbg-aser-desc-', block);
79 typoCssVarsForEl(o.partTitleTypo, '--bkbg-aser-pt-', block);
80 typoCssVarsForEl(o.excerptTypo, '--bkbg-aser-exc-', block);
81
82 // Header
83 var header = document.createElement('div');
84 header.className = 'bkbg-aser-header';
85
86 var label = document.createElement('div');
87 label.className = 'bkbg-aser-series-label';
88 label.textContent = 'Article Series';
89 label.style.color = o.accentColor;
90 header.appendChild(label);
91
92 var titleEl = document.createElement('h3');
93 titleEl.className = 'bkbg-aser-title';
94 titleEl.textContent = o.seriesTitle;
95 titleEl.style.color = o.titleColor;
96 header.appendChild(titleEl);
97
98 if (o.showSeriesDescription && o.seriesDescription) {
99 var descEl = document.createElement('p');
100 descEl.className = 'bkbg-aser-desc';
101 descEl.textContent = o.seriesDescription;
102 descEl.style.color = o.descColor;
103 header.appendChild(descEl);
104 }
105 block.appendChild(header);
106
107 // Progress
108 if (o.showProgress && total > 0) {
109 var progressWrap = document.createElement('div');
110 progressWrap.className = 'bkbg-aser-progress-wrap';
111
112 var bar = document.createElement('div');
113 bar.className = 'bkbg-aser-progress-bar';
114 bar.style.background = o.progressBg;
115
116 var fill = document.createElement('div');
117 fill.className = 'bkbg-aser-progress-fill';
118 fill.style.background = o.progressColor;
119 fill.style.width = pct + '%';
120 bar.appendChild(fill);
121
122 var progLabel = document.createElement('span');
123 progLabel.className = 'bkbg-aser-progress-label';
124 progLabel.textContent = 'Part ' + o.currentPart + ' of ' + total;
125 progLabel.style.color = o.descColor;
126
127 progressWrap.appendChild(bar);
128 progressWrap.appendChild(progLabel);
129 block.appendChild(progressWrap);
130 }
131
132 // Parts list
133 var list = document.createElement('ol');
134 list.className = 'bkbg-aser-list bkbg-aser-layout-' + o.layout;
135 list.style.listStyle = 'none';
136 list.style.margin = '0';
137 list.style.padding = '0';
138
139 o.parts.forEach(function (part, i) {
140 var isCurrent = i + 1 === o.currentPart;
141
142 var li = document.createElement('li');
143 li.className = 'bkbg-aser-item' + (isCurrent ? ' is-current' : '');
144
145 if (!isCurrent && part.url && part.url !== '#') {
146 // Make non-current items clickable (wrap inner content in link)
147 li.style.cursor = 'pointer';
148 li.addEventListener('click', function () { window.location.href = part.url; });
149 }
150
151 li.style.background = isCurrent ? o.currentBg : o.itemBg;
152 li.style.color = isCurrent ? o.currentColor : o.itemColor;
153 li.style.borderColor = isCurrent ? o.currentBorderColor : o.itemBorderColor;
154 li.style.borderRadius = Math.max(0, o.borderRadius - 4) + 'px';
155 if (isCurrent) {
156 li.style.borderLeftWidth = '3px';
157 li.style.paddingLeft = '12px';
158 }
159
160 if (o.showNumbers) {
161 var num = document.createElement('span');
162 num.className = 'bkbg-aser-num';
163 num.textContent = String(i + 1);
164 num.style.background = isCurrent ? o.currentNumberBg : o.numberBg;
165 num.style.color = isCurrent ? o.currentNumberColor : o.numberColor;
166 li.appendChild(num);
167 }
168
169 var body = document.createElement('div');
170 body.className = 'bkbg-aser-item-body';
171
172 var partTitle = document.createElement('span');
173 partTitle.className = 'bkbg-aser-part-title';
174 partTitle.textContent = part.title;
175 partTitle.style.color = isCurrent ? o.currentColor : o.itemColor;
176 body.appendChild(partTitle);
177
178 if (o.showExcerpt && part.excerpt) {
179 var excerpt = document.createElement('span');
180 excerpt.className = 'bkbg-aser-excerpt';
181 excerpt.textContent = part.excerpt;
182 excerpt.style.color = isCurrent ? o.currentColor : o.excerptColor;
183 body.appendChild(excerpt);
184 }
185
186 li.appendChild(body);
187
188 if (isCurrent) {
189 var badge = document.createElement('span');
190 badge.className = 'bkbg-aser-current-badge';
191 badge.textContent = 'Current';
192 badge.style.background = o.accentColor;
193 li.appendChild(badge);
194 }
195
196 list.appendChild(li);
197 });
198
199 block.appendChild(list);
200
201 appEl.parentNode.insertBefore(block, appEl);
202 appEl.style.display = 'none';
203 });
204 }
205
206 if (document.readyState !== 'loading') { init(); }
207 else { document.addEventListener('DOMContentLoaded', init); }
208 })();
209