PluginProbe
Blockenberg — 600+ Advanced Gutenberg Blocks & AI Agent for WordPress Block Editor / 2.0.11
Blockenberg — 600+ Advanced Gutenberg Blocks & AI Agent for WordPress Block Editor v2.0.11
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 / chapter-navigation / frontend.js

frontend.js in Blockenberg — 600+ Advanced Gutenberg Blocks & AI Agent for WordPress Block Editor 2.0.11, at blocks/chapter-navigation/frontend.js

236 lines 13.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 (function () {
2 function init() {
3 document.querySelectorAll('.bkbg-cnv-app').forEach(function (el) {
4 if (el.dataset.rendered) return;
5 el.dataset.rendered = '1';
6 var opts;
7 try { opts = JSON.parse(el.dataset.opts || '{}'); } catch (e) { opts = {}; }
8 var o = Object.assign({
9 seriesTitle: 'Series',
10 currentPart: 1,
11 totalParts: 1,
12 currentTitle: 'Current Chapter',
13 prevTitle: '',
14 prevUrl: '',
15 nextTitle: '',
16 nextUrl: '',
17 chapters: [],
18 showChapterList: true,
19 chapterListOpen: false,
20 showProgress: true,
21 style: 'card',
22 openInNewTab: false,
23 partLabel: 'Part',
24 bgColor: '#ffffff',
25 borderColor: '#e2e8f0',
26 accentColor: '#6366f1',
27 seriesTitleColor: '#374151',
28 currentTitleColor: '#111827',
29 progressBg: '#e2e8f0',
30 progressFill: '#6366f1',
31 btnBg: '#f1f5f9',
32 btnColor: '#374151',
33 pillBg: '#eef2ff',
34 pillColor: '#4f46e5',
35 chapterListBg: '#f8fafc',
36 activeChapterBg: '#eef2ff',
37 activeChapterColor: '#4f46e5',
38 borderRadius: 10,
39 paddingTop: 0,
40 paddingBottom: 0
41 }, opts);
42
43 function typoCssVarsForEl(typo, prefix, el) {
44 if (!typo) return;
45 if (typo.family) el.style.setProperty(prefix + 'font-family', "'" + typo.family + "', sans-serif");
46 if (typo.weight) el.style.setProperty(prefix + 'font-weight', typo.weight);
47 if (typo.transform) el.style.setProperty(prefix + 'text-transform', typo.transform);
48 if (typo.style) el.style.setProperty(prefix + 'font-style', typo.style);
49 if (typo.decoration) el.style.setProperty(prefix + 'text-decoration', typo.decoration);
50 var su = typo.sizeUnit || 'px';
51 if (typo.sizeDesktop !== '' && typo.sizeDesktop != null) el.style.setProperty(prefix + 'font-size-d', typo.sizeDesktop + su);
52 if (typo.sizeTablet !== '' && typo.sizeTablet != null) el.style.setProperty(prefix + 'font-size-t', typo.sizeTablet + su);
53 if (typo.sizeMobile !== '' && typo.sizeMobile != null) el.style.setProperty(prefix + 'font-size-m', typo.sizeMobile + su);
54 var lhu = typo.lineHeightUnit || '';
55 if (typo.lineHeightDesktop !== '' && typo.lineHeightDesktop != null) el.style.setProperty(prefix + 'line-height-d', typo.lineHeightDesktop + lhu);
56 if (typo.lineHeightTablet !== '' && typo.lineHeightTablet != null) el.style.setProperty(prefix + 'line-height-t', typo.lineHeightTablet + lhu);
57 if (typo.lineHeightMobile !== '' && typo.lineHeightMobile != null) el.style.setProperty(prefix + 'line-height-m', typo.lineHeightMobile + lhu);
58 var lsu = typo.letterSpacingUnit || 'px';
59 if (typo.letterSpacingDesktop !== '' && typo.letterSpacingDesktop != null) el.style.setProperty(prefix + 'letter-spacing-d', typo.letterSpacingDesktop + lsu);
60 if (typo.letterSpacingTablet !== '' && typo.letterSpacingTablet != null) el.style.setProperty(prefix + 'letter-spacing-t', typo.letterSpacingTablet + lsu);
61 if (typo.letterSpacingMobile !== '' && typo.letterSpacingMobile != null) el.style.setProperty(prefix + 'letter-spacing-m', typo.letterSpacingMobile + lsu);
62 var wsu = typo.wordSpacingUnit || 'px';
63 if (typo.wordSpacingDesktop !== '' && typo.wordSpacingDesktop != null) el.style.setProperty(prefix + 'word-spacing-d', typo.wordSpacingDesktop + wsu);
64 if (typo.wordSpacingTablet !== '' && typo.wordSpacingTablet != null) el.style.setProperty(prefix + 'word-spacing-t', typo.wordSpacingTablet + wsu);
65 if (typo.wordSpacingMobile !== '' && typo.wordSpacingMobile != null) el.style.setProperty(prefix + 'word-spacing-m', typo.wordSpacingMobile + wsu);
66 }
67
68 var target = o.openInNewTab ? '_blank' : '_self';
69 var progress = Math.round((o.currentPart / o.totalParts) * 100);
70
71 var wrap = document.createElement('div');
72 wrap.className = 'bkbg-cnv-wrap bkbg-cnv-' + o.style;
73 wrap.style.cssText = 'background:' + o.bgColor + ';padding-top:' + o.paddingTop + 'px;padding-bottom:' + o.paddingBottom + 'px;';
74
75 if (o.style === 'card') {
76 wrap.style.cssText += 'border:1px solid ' + o.borderColor + ';border-radius:' + o.borderRadius + 'px;box-shadow:0 2px 8px rgba(0,0,0,.06);overflow:hidden;';
77 } else if (o.style === 'banner') {
78 wrap.style.cssText += 'border-left:4px solid ' + o.accentColor + ';border:1px solid ' + o.borderColor + ';border-left-width:4px;border-radius:' + o.borderRadius + 'px;overflow:hidden;';
79 } else {
80 wrap.style.cssText += 'border-top:2px solid ' + o.accentColor + ';padding-top:16px;';
81 }
82
83 /* Header */
84 var hdr = document.createElement('div');
85 hdr.className = 'bkbg-cnv-header';
86 hdr.style.cssText = 'padding:16px 20px;' + (o.style !== 'minimal' ? 'border-bottom:1px solid ' + o.borderColor + ';' : '');
87
88 var meta = document.createElement('div');
89 meta.className = 'bkbg-cnv-meta';
90 meta.style.cssText = 'display:flex;align-items:center;gap:10px;margin-bottom:6px;flex-wrap:wrap;';
91
92 var pill = document.createElement('span');
93 pill.className = 'bkbg-cnv-pill';
94 pill.style.cssText = 'background:' + o.pillBg + ';color:' + o.pillColor + ';padding:3px 10px;border-radius:20px;font-size:12px;font-weight:600;';
95 pill.textContent = o.partLabel + ' ' + o.currentPart + ' of ' + o.totalParts;
96
97 var series = document.createElement('span');
98 series.className = 'bkbg-cnv-series';
99 series.style.cssText = 'font-size:13px;color:' + o.seriesTitleColor + ';';
100 series.textContent = o.seriesTitle;
101
102 meta.appendChild(pill);
103 meta.appendChild(series);
104 hdr.appendChild(meta);
105
106 var cTitle = document.createElement('h3');
107 cTitle.className = 'bkbg-cnv-current-title';
108 cTitle.style.cssText = 'margin:0;color:' + o.currentTitleColor + ';';
109 cTitle.textContent = o.currentTitle;
110 hdr.appendChild(cTitle);
111
112 if (o.showProgress) {
113 var pWrap = document.createElement('div');
114 pWrap.className = 'bkbg-cnv-progress-wrap';
115 pWrap.style.marginTop = '10px';
116
117 var pBar = document.createElement('div');
118 pBar.className = 'bkbg-cnv-progress-bar';
119 pBar.style.cssText = 'background:' + o.progressBg + ';border-radius:4px;height:6px;overflow:hidden;';
120
121 var pFill = document.createElement('div');
122 pFill.className = 'bkbg-cnv-progress-fill';
123 pFill.style.cssText = 'background:' + o.progressFill + ';width:' + progress + '%;height:100%;border-radius:4px;';
124
125 var pLbl = document.createElement('div');
126 pLbl.className = 'bkbg-cnv-progress-label';
127 pLbl.style.cssText = 'font-size:11px;margin-top:4px;opacity:.8;color:' + o.seriesTitleColor + ';';
128 pLbl.textContent = progress + '% through the series';
129
130 pBar.appendChild(pFill);
131 pWrap.appendChild(pBar);
132 pWrap.appendChild(pLbl);
133 hdr.appendChild(pWrap);
134 }
135
136 wrap.appendChild(hdr);
137
138 /* Nav row */
139 var nav = document.createElement('div');
140 nav.className = 'bkbg-cnv-nav';
141 nav.style.cssText = 'display:flex;gap:10px;padding:14px 20px;flex-wrap:wrap;';
142
143 if (o.prevTitle) {
144 var prevBtn = document.createElement('a');
145 prevBtn.className = 'bkbg-cnv-btn';
146 prevBtn.href = o.prevUrl || '#';
147 prevBtn.target = target;
148 if (o.openInNewTab) prevBtn.rel = 'noopener noreferrer';
149 prevBtn.style.cssText = 'flex:1;min-width:160px;background:' + o.btnBg + ';color:' + o.btnColor + ';padding:10px 14px;border-radius:6px;font-size:13px;text-decoration:none;display:flex;flex-direction:column;gap:2px;';
150 prevBtn.innerHTML = '<span style="font-size:11px;opacity:.7;">← Previous</span><span style="font-weight:600;">' + esc(o.prevTitle) + '</span>';
151 nav.appendChild(prevBtn);
152 }
153 if (o.nextTitle) {
154 var nextBtn = document.createElement('a');
155 nextBtn.className = 'bkbg-cnv-btn bkbg-cnv-btn-next';
156 nextBtn.href = o.nextUrl || '#';
157 nextBtn.target = target;
158 if (o.openInNewTab) nextBtn.rel = 'noopener noreferrer';
159 nextBtn.style.cssText = 'flex:1;min-width:160px;background:' + o.accentColor + ';color:#fff;padding:10px 14px;border-radius:6px;font-size:13px;text-decoration:none;display:flex;flex-direction:column;gap:2px;text-align:right;';
160 nextBtn.innerHTML = '<span style="font-size:11px;opacity:.8;">Next →</span><span style="font-weight:600;">' + esc(o.nextTitle) + '</span>';
161 nav.appendChild(nextBtn);
162 }
163 wrap.appendChild(nav);
164
165 /* Chapter list */
166 if (o.showChapterList && o.chapters && o.chapters.length) {
167 var details = document.createElement('details');
168 if (o.chapterListOpen) details.open = true;
169 details.style.cssText = 'border-top:1px solid ' + o.borderColor + ';';
170
171 var summary = document.createElement('summary');
172 summary.className = 'bkbg-cnv-summary';
173 summary.style.cssText = 'padding:12px 20px;cursor:pointer;font-size:13px;font-weight:600;list-style:none;display:flex;align-items:center;justify-content:space-between;background:' + o.chapterListBg + ';color:' + o.seriesTitleColor + ';';
174 summary.innerHTML = '<span>All ' + o.totalParts + ' chapters</span><span class="bkbg-cnv-arrow" style="transition:transform .25s;font-style:normal;display:inline-block;">▾</span>';
175
176 var ul = document.createElement('ol');
177 ul.className = 'bkbg-cnv-list';
178 ul.style.cssText = 'margin:0;padding:8px 0;list-style:none;background:' + o.chapterListBg + ';';
179
180 o.chapters.forEach(function (ch, i) {
181 var isActive = (i + 1) === o.currentPart;
182 var li = document.createElement('li');
183 li.className = 'bkbg-cnv-list-item';
184 li.style.cssText = 'padding:8px 20px 8px 44px;position:relative;font-size:13px;' + (isActive ? 'background:' + o.activeChapterBg + ';' : '');
185
186 var num = document.createElement('span');
187 num.className = 'bkbg-cnv-item-num';
188 num.style.cssText = 'position:absolute;left:20px;font-weight:700;color:' + (isActive ? o.activeChapterColor : o.seriesTitleColor) + ';';
189 num.textContent = (i + 1) + '.';
190 li.appendChild(num);
191
192 if (ch.url && !isActive) {
193 var link = document.createElement('a');
194 link.className = 'bkbg-cnv-item-link';
195 link.href = ch.url;
196 link.target = target;
197 if (o.openInNewTab) link.rel = 'noopener noreferrer';
198 link.style.cssText = 'color:' + o.seriesTitleColor + ';text-decoration:none;';
199 link.textContent = ch.title;
200 li.appendChild(link);
201 } else {
202 var span = document.createElement('span');
203 span.style.cssText = 'color:' + (isActive ? o.activeChapterColor : o.seriesTitleColor) + ';font-weight:' + (isActive ? '600' : '400') + ';';
204 span.textContent = ch.title;
205 li.appendChild(span);
206 }
207
208 if (isActive) {
209 var badge = document.createElement('span');
210 badge.className = 'bkbg-cnv-current-badge';
211 badge.style.cssText = 'margin-left:8px;font-size:11px;padding:1px 7px;background:' + o.accentColor + ';color:#fff;border-radius:10px;font-weight:600;';
212 badge.textContent = 'Current';
213 li.appendChild(badge);
214 }
215 ul.appendChild(li);
216 });
217
218 details.appendChild(summary);
219 details.appendChild(ul);
220 wrap.appendChild(details);
221 }
222
223 typoCssVarsForEl(o.typoTitle, '--bkbg-cnv-tt-', wrap);
224
225 el.parentNode.insertBefore(wrap, el);
226 });
227 }
228
229 function esc(str) {
230 return String(str || '').replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;');
231 }
232
233 if (document.readyState !== 'loading') { init(); }
234 else { document.addEventListener('DOMContentLoaded', init); }
235 })();
236