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

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

193 lines 8.8 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) {
18 v = v + (typo.sizeUnit || 'px');
19 } else if (['lineHeightDesktop','lineHeightTablet','lineHeightMobile'].indexOf(k) !== -1) {
20 v = v + (typo.lineHeightUnit || '');
21 } else if (['letterSpacingDesktop','letterSpacingTablet','letterSpacingMobile'].indexOf(k) !== -1) {
22 v = v + (typo.letterSpacingUnit || 'px');
23 } else if (['wordSpacingDesktop','wordSpacingTablet','wordSpacingMobile'].indexOf(k) !== -1) {
24 v = v + (typo.wordSpacingUnit || 'px');
25 }
26 el.style.setProperty(prefix + map[k], String(v));
27 }
28 });
29 }
30
31 var SYMBOLS = ['*', '', '', '§', '', '', '#', '**', '††', '‡‡'];
32
33 function getMarker(style, i) {
34 if (style === 'letter') return String.fromCharCode(97 + i);
35 if (style === 'roman') {
36 var nums = [1,4,5,9,10,40,50,90,100,400,500,900,1000];
37 var syms = ['i','iv','v','ix','x','xl','l','xc','c','cd','d','cm','m'];
38 var n = i + 1, out = '';
39 for (var k = nums.length - 1; k >= 0; k--) {
40 while (n >= nums[k]) { out += syms[k]; n -= nums[k]; }
41 }
42 return out;
43 }
44 if (style === 'symbol') return SYMBOLS[i % SYMBOLS.length];
45 return String(i + 1);
46 }
47
48 function init() {
49 document.querySelectorAll('.bkbg-fn-app').forEach(function (appEl) {
50 if (appEl.dataset.rendered) return;
51 appEl.dataset.rendered = '1';
52
53 var opts;
54 try { opts = JSON.parse(appEl.dataset.opts || '{}'); } catch (e) { opts = {}; }
55 var o = Object.assign({
56 notes: [],
57 title: 'Notes',
58 showTitle: true,
59 markerStyle: 'number',
60 showTooltip: true,
61 listStyle: 'default',
62 dividerEnabled: true,
63 fontSize: 14,
64 titleSize: 16,
65 borderRadius: 6,
66 bgColor: '#f8fafc',
67 borderColor: '#e2e8f0',
68 titleColor: '#0f172a',
69 textColor: '#475569',
70 markerColor: '#3b82f6',
71 markerBg: '#eff6ff',
72 dividerColor: '#e2e8f0',
73 tooltipBg: '#1e293b',
74 tooltipColor: '#f1f5f9'
75 }, opts);
76
77 // ── build block ──────────────────────────────────────────────────────
78 var block = document.createElement('div');
79 block.className = 'bkbg-fn-block';
80 block.style.background = o.bgColor;
81 block.style.borderRadius = o.borderRadius + 'px';
82 block.style.padding = '20px 24px';
83 block.style.boxSizing = 'border-box';
84
85 typoCssVarsForEl(o.typoTitle, '--bkbg-fn-tt-', block);
86 typoCssVarsForEl(o.typoNote, '--bkbg-fn-nt-', block);
87
88 if (o.dividerEnabled) {
89 var div = document.createElement('div');
90 div.className = 'bkbg-fn-divider';
91 div.style.borderTopColor = o.dividerColor;
92 block.appendChild(div);
93 }
94
95 if (o.showTitle && o.title) {
96 var titleEl = document.createElement('div');
97 titleEl.className = 'bkbg-fn-title';
98 titleEl.textContent = o.title;
99 titleEl.style.color = o.titleColor;
100 block.appendChild(titleEl);
101 }
102
103 var list = document.createElement('ol');
104 list.className = 'bkbg-fn-list bkbg-fn-list-' + o.listStyle;
105 list.style.listStyle = 'none';
106 list.style.margin = '0';
107 list.style.padding = '0';
108
109 o.notes.forEach(function (note, i) {
110 var li = document.createElement('li');
111 li.className = 'bkbg-fn-item';
112 li.id = 'fn-' + note.id;
113 li.style.color = o.textColor;
114 if (o.listStyle === 'card') li.style.borderColor = o.borderColor;
115
116 var marker = document.createElement('span');
117 marker.className = 'bkbg-fn-marker';
118 marker.textContent = getMarker(o.markerStyle, i);
119 marker.style.background = o.markerBg;
120 marker.style.color = o.markerColor;
121
122 var textSpan = document.createElement('span');
123 textSpan.className = 'bkbg-fn-text';
124 textSpan.textContent = note.text;
125
126 li.appendChild(marker);
127 li.appendChild(textSpan);
128 list.appendChild(li);
129 });
130
131 block.appendChild(list);
132
133 appEl.parentNode.insertBefore(block, appEl);
134 appEl.style.display = 'none';
135
136 // ── inject inline markers into page (if showTooltip) ──────────────────
137 // Looks for [fn:1] [fn:2] shortcodes already in the page content
138 // and replaces them with superscript markers with tooltips
139 if (o.showTooltip && o.notes.length) {
140 var body = document.body;
141 var walker = document.createTreeWalker(body, NodeFilter.SHOW_TEXT, null, false);
142 var nodesToReplace = [];
143 var node;
144 while ((node = walker.nextNode())) {
145 if (/\[fn:\d+\]/.test(node.textContent)) {
146 nodesToReplace.push(node);
147 }
148 }
149 nodesToReplace.forEach(function (textNode) {
150 var parent = textNode.parentNode;
151 if (!parent) return;
152 var frag = document.createDocumentFragment();
153 var parts = textNode.textContent.split(/(\[fn:\d+\])/);
154 parts.forEach(function (part) {
155 var match = part.match(/^\[fn:(\d+)\]$/);
156 if (match) {
157 var noteId = parseInt(match[1], 10);
158 var noteObj = o.notes.filter(function (n) { return n.id === noteId; })[0];
159 if (noteObj) {
160 var ref = document.createElement('span');
161 ref.className = 'bkbg-fn-ref';
162 ref.style.color = o.markerColor;
163 ref.style.background = o.markerBg;
164 ref.setAttribute('tabindex', '0');
165 var idx = o.notes.indexOf(noteObj);
166 ref.textContent = getMarker(o.markerStyle, idx);
167 ref.setAttribute('href', '#fn-' + noteId);
168
169 var tooltip = document.createElement('span');
170 tooltip.className = 'bkbg-fn-tooltip';
171 tooltip.textContent = noteObj.text;
172 tooltip.style.background = o.tooltipBg;
173 tooltip.style.color = o.tooltipColor;
174 tooltip.style.setProperty('border-top-color', o.tooltipBg);
175 ref.appendChild(tooltip);
176 frag.appendChild(ref);
177 } else {
178 frag.appendChild(document.createTextNode(part));
179 }
180 } else {
181 frag.appendChild(document.createTextNode(part));
182 }
183 });
184 parent.replaceChild(frag, textNode);
185 });
186 }
187 });
188 }
189
190 if (document.readyState !== 'loading') { init(); }
191 else { document.addEventListener('DOMContentLoaded', init); }
192 })();
193