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 / number-base-converter / frontend.js

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

274 lines 11.2 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 var _typoKeys = {
5 family:'font-family', weight:'font-weight', style:'font-style',
6 decoration:'text-decoration', transform:'text-transform',
7 sizeDesktop:'font-size-d', sizeTablet:'font-size-t', sizeMobile:'font-size-m',
8 lineHeightDesktop:'line-height-d', lineHeightTablet:'line-height-t', lineHeightMobile:'line-height-m',
9 letterSpacingDesktop:'letter-spacing-d', letterSpacingTablet:'letter-spacing-t', letterSpacingMobile:'letter-spacing-m',
10 wordSpacingDesktop:'word-spacing-d', wordSpacingTablet:'word-spacing-t', wordSpacingMobile:'word-spacing-m'
11 };
12 function typoCssVarsForEl(el, obj, prefix) {
13 if (!obj || typeof obj !== 'object') return;
14 Object.keys(_typoKeys).forEach(function (k) {
15 var v = obj[k];
16 if (v === undefined || v === '' || v === null) return;
17 if (k === 'sizeDesktop' || k === 'sizeTablet' || k === 'sizeMobile') v = v + (obj.sizeUnit || 'px');
18 else if (k === 'lineHeightDesktop' || k === 'lineHeightTablet' || k === 'lineHeightMobile') v = v + (obj.lineHeightUnit || '');
19 else if (k === 'letterSpacingDesktop' || k === 'letterSpacingTablet' || k === 'letterSpacingMobile') v = v + (obj.letterSpacingUnit || 'px');
20 else if (k === 'wordSpacingDesktop' || k === 'wordSpacingTablet' || k === 'wordSpacingMobile') v = v + (obj.wordSpacingUnit || 'px');
21 el.style.setProperty(prefix + _typoKeys[k], String(v));
22 });
23 }
24
25 var BASES = [
26 {key:'binary', label:'Binary', base:2, hint:'0 – 1', validate:/^[01]*$/},
27 {key:'octal', label:'Octal', base:8, hint:'0 – 7', validate:/^[0-7]*$/},
28 {key:'decimal', label:'Decimal', base:10, hint:'0 – 9', validate:/^[0-9]*$/},
29 {key:'hex', label:'Hexadecimal', base:16, hint:'0 – F', validate:/^[0-9A-Fa-f]*$/}
30 ];
31
32 var ORDER = ['decimal','binary','octal','hex'];
33
34 function toDecimal(str, base) {
35 if (!str) return NaN;
36 return parseInt(str, base);
37 }
38
39 function fromDecimal(n, base) {
40 if (isNaN(n) || n < 0) return '';
41 return n.toString(base).toUpperCase();
42 }
43
44 function bitPattern(n, bits) {
45 if (isNaN(n) || n < 0) return '';
46 return (n >>> 0).toString(2).padStart(bits, '0');
47 }
48
49 function showToast(msg) {
50 var t = document.querySelector('.bkbg-nbc-toast');
51 if (!t) {
52 t = document.createElement('div');
53 t.className = 'bkbg-nbc-toast';
54 document.body.appendChild(t);
55 }
56 t.textContent = msg;
57 t.classList.add('show');
58 setTimeout(function () { t.classList.remove('show'); }, 1800);
59 }
60
61 function initBlock(app) {
62 var opts = {};
63 try { opts = JSON.parse(app.getAttribute('data-opts') || '{}'); } catch(e) {}
64
65 var defaultValue = opts.defaultValue || '255';
66 var showBinary = opts.showBinary !== false;
67 var showOctal = opts.showOctal !== false;
68 var showDecimal = opts.showDecimal !== false;
69 var showHex = opts.showHex !== false;
70 var showBitLength = opts.showBitLength !== false;
71 var showCopy = opts.showCopyButtons !== false;
72 var cardRadius = (opts.cardRadius !== undefined ? opts.cardRadius : 16) + 'px';
73 var inputRadius = (opts.inputRadius !== undefined ? opts.inputRadius : 8) + 'px';
74 var valueFontSize = (opts.valueFontSize || 18) + 'px';
75 var colors = {
76 binary: opts.binaryColor || '#3b82f6',
77 octal: opts.octalColor || '#f59e0b',
78 decimal: opts.decimalColor || '#6c3fb5',
79 hex: opts.hexColor || '#10b981'
80 };
81 var rowBg = opts.rowBg || '#f3f4f6';
82 var rowBorder = opts.rowBorder || '#e5e7eb';
83 var cardBg = opts.cardBg || '#fff';
84 var labelColor= opts.labelColor|| '#374151';
85
86 var wrap = document.createElement('div');
87 wrap.className = 'bkbg-nbc-wrap';
88 wrap.style.borderRadius = cardRadius;
89 wrap.style.background = cardBg;
90 app.appendChild(wrap);
91
92 /* Typography CSS vars */
93 typoCssVarsForEl(wrap, opts.titleTypo, '--bkbg-nbc-tt-');
94 typoCssVarsForEl(wrap, opts.subtitleTypo, '--bkbg-nbc-st-');
95
96 // Header
97 if (opts.showTitle || opts.showSubtitle) {
98 var hdr = document.createElement('div');
99 hdr.className = 'bkbg-nbc-header';
100 if (opts.showTitle && opts.title) {
101 var ti = document.createElement('div');
102 ti.className = 'bkbg-nbc-title';
103 if (opts.titleColor) ti.style.color = opts.titleColor;
104 ti.textContent = opts.title;
105 hdr.appendChild(ti);
106 }
107 if (opts.showSubtitle && opts.subtitle) {
108 var su = document.createElement('div');
109 su.className = 'bkbg-nbc-subtitle';
110 if (opts.subtitleColor) su.style.color = opts.subtitleColor;
111 su.textContent = opts.subtitle;
112 hdr.appendChild(su);
113 }
114 wrap.appendChild(hdr);
115 }
116
117 // Build rows
118 var inputs = {};
119 var visibility = {binary:showBinary, octal:showOctal, decimal:showDecimal, hex:showHex};
120 var order = ORDER.filter(function(k){ return visibility[k]; });
121
122 order.forEach(function(key) {
123 var binfo = BASES.find(function(b){ return b.key===key; });
124 var color = colors[key];
125
126 var row = document.createElement('div');
127 row.className = 'bkbg-nbc-row';
128 row.style.background = rowBg;
129 row.style.borderColor = rowBorder;
130 row.style.borderRadius = inputRadius;
131 row.style.overflow = 'hidden';
132
133 var badge = document.createElement('div');
134 badge.className = 'bkbg-nbc-badge';
135 badge.style.background = color;
136 badge.style.color = '#fff';
137
138 var hint = document.createElement('div');
139 hint.className = 'bkbg-nbc-badge-hint';
140 hint.textContent = binfo.hint;
141
142 var name = document.createElement('div');
143 name.className = 'bkbg-nbc-badge-name';
144 name.textContent = binfo.label;
145
146 badge.appendChild(hint); badge.appendChild(name);
147
148 var inp = document.createElement('input');
149 inp.type = 'text';
150 inp.className = 'bkbg-nbc-input';
151 inp.style.fontSize = valueFontSize;
152 inp.autocomplete = 'off';
153 inp.autocorrect = 'off';
154 inp.spellcheck = false;
155 inp.dataset.base = binfo.base;
156 inp.dataset.key = key;
157
158 row.appendChild(badge);
159 row.appendChild(inp);
160
161 if (showCopy) {
162 var copyBtn = document.createElement('button');
163 copyBtn.className = 'bkbg-nbc-copy';
164 copyBtn.type = 'button';
165 copyBtn.textContent = 'Copy';
166 copyBtn.style.color = color;
167 copyBtn.style.background = color + '18';
168 copyBtn.addEventListener('click', function () {
169 var val = inp.value;
170 if (!val) return;
171 if (navigator.clipboard) {
172 navigator.clipboard.writeText(val).then(function(){ showToast('Copied!'); });
173 } else {
174 inp.select();
175 document.execCommand('copy');
176 showToast('Copied!');
177 }
178 });
179 row.appendChild(copyBtn);
180 }
181
182 wrap.appendChild(row);
183 inputs[key] = inp;
184 });
185
186 // Bit length section
187 var bitSection, b8, b16, b32;
188 if (showBitLength) {
189 bitSection = document.createElement('div');
190 bitSection.className = 'bkbg-nbc-bits';
191 bitSection.style.background = rowBg;
192 bitSection.style.borderColor = rowBorder;
193
194 var bTitle = document.createElement('div');
195 bTitle.className = 'bkbg-nbc-bits-title';
196 bTitle.style.color = labelColor;
197 bTitle.textContent = 'Bit Lengths';
198 bitSection.appendChild(bTitle);
199
200 function makeBitRow(label) {
201 var r = document.createElement('div');
202 r.className = 'bkbg-nbc-bit-row';
203 var l = document.createElement('span');
204 l.className = 'bkbg-nbc-bit-lbl';
205 l.style.color = labelColor;
206 l.textContent = label;
207 var v = document.createElement('span');
208 v.className = 'bkbg-nbc-bit-val';
209 v.textContent = '';
210 r.appendChild(l); r.appendChild(v);
211 bitSection.appendChild(r);
212 return v;
213 }
214 b8 = makeBitRow('8-bit');
215 b16 = makeBitRow('16-bit');
216 b32 = makeBitRow('32-bit');
217 wrap.appendChild(bitSection);
218 }
219
220 // Compute initial values from defaultValue (decimal)
221 var initDec = parseInt(defaultValue, 10);
222 Object.keys(inputs).forEach(function(key) {
223 var binfo = BASES.find(function(b){ return b.key===key; });
224 inputs[key].value = fromDecimal(initDec, binfo.base);
225 });
226 if (showBitLength && !isNaN(initDec)) {
227 b8.textContent = bitPattern(initDec, 8);
228 b16.textContent = bitPattern(initDec, 16);
229 b32.textContent = bitPattern(initDec, 32);
230 }
231
232 // Attach listeners
233 Object.keys(inputs).forEach(function (key) {
234 var inp = inputs[key];
235 inp.addEventListener('input', function () {
236 var raw = inp.value.replace(/\s/g, '').toUpperCase();
237 var binfo = BASES.find(function(b){ return b.key===key; });
238 // Validate
239 if (raw && !binfo.validate.test(raw)) {
240 // revert to last valid value - strip invalid chars
241 var allowed = raw.split('').filter(function(c){ return binfo.validate.test(c); }).join('');
242 inp.value = allowed;
243 raw = allowed;
244 }
245 var n = toDecimal(raw, binfo.base);
246 Object.keys(inputs).forEach(function(k) {
247 if (k === key) { return; }
248 var tb = BASES.find(function(b){ return b.key===k; });
249 inputs[k].value = raw ? fromDecimal(n, tb.base) : '';
250 });
251 if (showBitLength) {
252 if (!raw || isNaN(n)) {
253 b8.textContent = ''; b16.textContent = ''; b32.textContent = '';
254 } else {
255 b8.textContent = bitPattern(n, 8);
256 b16.textContent = bitPattern(n, 16);
257 b32.textContent = bitPattern(n, 32);
258 }
259 }
260 });
261 });
262 }
263
264 function init() {
265 document.querySelectorAll('.bkbg-nbc-app').forEach(initBlock);
266 }
267
268 if (document.readyState === 'loading') {
269 document.addEventListener('DOMContentLoaded', init);
270 } else {
271 init();
272 }
273 })();
274