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

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

232 lines 13.1 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) return;
6 if (typo.family) el.style.setProperty(prefix + 'font-family', "'" + typo.family + "', sans-serif");
7 if (typo.weight) el.style.setProperty(prefix + 'font-weight', typo.weight);
8 if (typo.transform) el.style.setProperty(prefix + 'text-transform', typo.transform);
9 if (typo.style) el.style.setProperty(prefix + 'font-style', typo.style);
10 if (typo.decoration) el.style.setProperty(prefix + 'text-decoration', typo.decoration);
11 var su = typo.sizeUnit || 'px';
12 if (typo.sizeDesktop !== '' && typo.sizeDesktop != null) el.style.setProperty(prefix + 'font-size-d', typo.sizeDesktop + su);
13 if (typo.sizeTablet !== '' && typo.sizeTablet != null) el.style.setProperty(prefix + 'font-size-t', typo.sizeTablet + su);
14 if (typo.sizeMobile !== '' && typo.sizeMobile != null) el.style.setProperty(prefix + 'font-size-m', typo.sizeMobile + su);
15 var lhu = typo.lineHeightUnit || 'px';
16 if (typo.lineHeightDesktop !== '' && typo.lineHeightDesktop != null) el.style.setProperty(prefix + 'line-height-d', typo.lineHeightDesktop + lhu);
17 if (typo.lineHeightTablet !== '' && typo.lineHeightTablet != null) el.style.setProperty(prefix + 'line-height-t', typo.lineHeightTablet + lhu);
18 if (typo.lineHeightMobile !== '' && typo.lineHeightMobile != null) el.style.setProperty(prefix + 'line-height-m', typo.lineHeightMobile + lhu);
19 var lsu = typo.letterSpacingUnit || 'px';
20 if (typo.letterSpacingDesktop !== '' && typo.letterSpacingDesktop != null) { el.style.setProperty(prefix + 'letter-spacing-d', typo.letterSpacingDesktop + lsu); el.style.setProperty(prefix + 'letter-spacing', typo.letterSpacingDesktop + lsu); }
21 if (typo.letterSpacingTablet !== '' && typo.letterSpacingTablet != null) el.style.setProperty(prefix + 'letter-spacing-t', typo.letterSpacingTablet + lsu);
22 if (typo.letterSpacingMobile !== '' && typo.letterSpacingMobile != null) el.style.setProperty(prefix + 'letter-spacing-m', typo.letterSpacingMobile + lsu);
23 var wsu = typo.wordSpacingUnit || 'px';
24 if (typo.wordSpacingDesktop !== '' && typo.wordSpacingDesktop != null) { el.style.setProperty(prefix + 'word-spacing-d', typo.wordSpacingDesktop + wsu); el.style.setProperty(prefix + 'word-spacing', typo.wordSpacingDesktop + wsu); }
25 if (typo.wordSpacingTablet !== '' && typo.wordSpacingTablet != null) el.style.setProperty(prefix + 'word-spacing-t', typo.wordSpacingTablet + wsu);
26 if (typo.wordSpacingMobile !== '' && typo.wordSpacingMobile != null) el.style.setProperty(prefix + 'word-spacing-m', typo.wordSpacingMobile + wsu);
27 }
28
29 // ── Base64 helpers with Unicode support ──────────────────────────────
30 function toBase64(str, urlSafe, lineBreaks) {
31 var b64;
32 try {
33 // TextEncoder → Uint8Array → binary string → btoa handles Unicode cleanly
34 var bytes = new TextEncoder().encode(str);
35 var bin = '';
36 bytes.forEach(function(b) { bin += String.fromCharCode(b); });
37 b64 = btoa(bin);
38 } catch(e) {
39 return { error: 'Encoding error: ' + e.message };
40 }
41 if (urlSafe) { b64 = b64.replace(/\+/g,'-').replace(/\//g,'_'); }
42 if (lineBreaks) {
43 var lines = [];
44 for (var i = 0; i < b64.length; i += 76) { lines.push(b64.slice(i, i+76)); }
45 b64 = lines.join('\n');
46 }
47 return { result: b64 };
48 }
49
50 function fromBase64(str, urlSafe) {
51 try {
52 var s = str.trim();
53 if (urlSafe) { s = s.replace(/-/g,'+').replace(/_/g,'/'); }
54 s = s.replace(/\s/g, '');
55 var bin = atob(s);
56 var bytes = new Uint8Array(bin.length);
57 for (var i=0; i<bin.length; i++) { bytes[i] = bin.charCodeAt(i); }
58 return { result: new TextDecoder().decode(bytes) };
59 } catch(e) {
60 return { error: 'Invalid Base64 string. Please check the input.' };
61 }
62 }
63
64 // ── Bootstrap ────────────────────────────────────────────────────────
65 document.querySelectorAll('.bkbg-b64-app').forEach(function(root) {
66 var opts;
67 try { opts = JSON.parse(root.getAttribute('data-opts') || '{}'); }
68 catch(e) { return; }
69
70 var o = {
71 title: opts.title || 'Base64 Encoder / Decoder',
72 subtitle: opts.subtitle || '',
73 defaultMode: opts.defaultMode || 'encode',
74 defaultInput: opts.defaultInput || '',
75 showUrlSafe: opts.showUrlSafe !== false,
76 showLineBreaks: opts.showLineBreaks !== false,
77 showStats: opts.showStats !== false,
78 accentColor: opts.accentColor || '#0ea5e9',
79 sectionBg: opts.sectionBg || '#f0f9ff',
80 cardBg: opts.cardBg || '#ffffff',
81 inputBg: opts.inputBg || '#f8fafc',
82 outputBg: opts.outputBg || '#0f172a',
83 outputColor: opts.outputColor || '#7dd3fc',
84 titleColor: opts.titleColor || '#0c4a6e',
85 subtitleColor: opts.subtitleColor || '#6b7280',
86 labelColor: opts.labelColor || '#374151',
87 titleFontSize: parseInt(opts.titleFontSize) || 26,
88 contentMaxWidth: parseInt(opts.contentMaxWidth) || 720
89 };
90
91 var mode = o.defaultMode;
92
93 // ── Build HTML ─────────────────────────────────────────────────
94 root.innerHTML =
95 '<div class="bkbg-b64-wrap" style="background:' + o.sectionBg + ';max-width:' + o.contentMaxWidth + 'px;--b64-accent:' + o.accentColor + '">' +
96 (o.title ? '<h3 class="bkbg-b64-title" style="color:' + o.titleColor + '">' + o.title + '</h3>' : '') +
97 (o.subtitle ? '<p class="bkbg-b64-subtitle" style="color:' + o.subtitleColor + '">' + o.subtitle + '</p>' : '') +
98
99 '<div class="bkbg-b64-tabs">' +
100 '<button class="bkbg-b64-tab" data-mode="encode">⬆ Encode</button>' +
101 '<button class="bkbg-b64-tab" data-mode="decode">⬇ Decode</button>' +
102 '</div>' +
103
104 '<label class="bkbg-b64-field-label" id="b64-in-label" style="color:' + o.labelColor + '">Plain Text</label>' +
105 '<textarea id="b64-input" class="bkbg-b64-textarea" style="background:' + o.inputBg + ';color:' + o.labelColor + '" placeholder="Enter text to encode…"></textarea>' +
106
107 '<div class="bkbg-b64-options">' +
108 (o.showUrlSafe ? '<label class="bkbg-b64-option-label" style="color:' + o.labelColor + '"><input type="checkbox" id="b64-urlsafe" style="accent-color:' + o.accentColor + '"> URL-safe Base64</label>' : '') +
109 (o.showLineBreaks ? '<label class="bkbg-b64-option-label" style="color:' + o.labelColor + '"><input type="checkbox" id="b64-linebreaks" style="accent-color:' + o.accentColor + '"> Line breaks (76 chars)</label>' : '') +
110 '</div>' +
111
112 '<div class="bkbg-b64-output-header">' +
113 '<span class="bkbg-b64-output-label" id="b64-out-label" style="color:' + o.labelColor + '">Base64 Output</span>' +
114 '<button class="bkbg-b64-copy-btn" id="b64-copy">⧉ Copy</button>' +
115 '</div>' +
116 '<div class="bkbg-b64-output-box" id="b64-output" style="background:' + o.outputBg + ';color:' + o.outputColor + '">' +
117 '<span class="bkbg-b64-output-placeholder">Output will appear here…</span>' +
118 '<span class="bkbg-b64-toast" id="b64-toast">Copied!</span>' +
119 '</div>' +
120
121 (o.showStats ?
122 '<div class="bkbg-b64-stats" id="b64-stats">' +
123 '<span class="bkbg-b64-stat" id="b64-stat-in" style="color:' + o.labelColor + '">Input: 0 chars</span>' +
124 '<span class="bkbg-b64-stat" id="b64-stat-out" style="color:' + o.labelColor + '">Output: 0 chars</span>' +
125 '<span class="bkbg-b64-stat" id="b64-stat-ratio" style="color:' + o.labelColor + '">Ratio: —</span>' +
126 '</div>'
127 : '') +
128 '</div>';
129
130 var wrapEl = root.querySelector('.bkbg-b64-wrap');
131 if (wrapEl) {
132 typoCssVarsForEl(opts.titleTypo, '--bkbg-b64-title-', wrapEl);
133 typoCssVarsForEl(opts.subtitleTypo, '--bkbg-b64-sub-', wrapEl);
134 }
135
136 var inEl = root.querySelector('#b64-input');
137 var inLabel = root.querySelector('#b64-in-label');
138 var outLabel = root.querySelector('#b64-out-label');
139 var outEl = root.querySelector('#b64-output');
140 var copyBtn = root.querySelector('#b64-copy');
141 var toast = root.querySelector('#b64-toast');
142 var urlsafeEl = root.querySelector('#b64-urlsafe');
143 var lbEl = root.querySelector('#b64-linebreaks');
144 var statIn = root.querySelector('#b64-stat-in');
145 var statOut = root.querySelector('#b64-stat-out');
146 var statRatio = root.querySelector('#b64-stat-ratio');
147 var tabs = root.querySelectorAll('.bkbg-b64-tab');
148
149 var currentOutput = '';
150
151 function setMode(m) {
152 mode = m;
153 tabs.forEach(function(t) {
154 var act = t.getAttribute('data-mode') === mode;
155 t.classList.toggle('active', act);
156 t.style.background = act ? o.accentColor : '';
157 t.style.borderColor = act ? o.accentColor : '';
158 t.style.color = act ? '#fff' : o.labelColor;
159 });
160 inLabel.textContent = mode === 'encode' ? 'Plain Text' : 'Base64 String';
161 outLabel.textContent = mode === 'encode' ? 'Base64 Output' : 'Decoded Text';
162 inEl.placeholder = mode === 'encode' ? 'Enter text to encode…' : 'Enter Base64 to decode…';
163 inEl.value = '';
164 outEl.innerHTML = '<span class="bkbg-b64-output-placeholder">Output will appear here…</span>';
165 currentOutput = '';
166 if (statIn) statIn.textContent = 'Input: 0 chars';
167 if (statOut) statOut.textContent = 'Output: 0 chars';
168 if (statRatio) statRatio.textContent = 'Ratio: —';
169 }
170
171 function convert() {
172 var text = inEl.value;
173 var urlSafe = urlsafeEl ? urlsafeEl.checked : false;
174 var lb = lbEl ? lbEl.checked : false;
175 var res;
176
177 if (!text) {
178 outEl.innerHTML = '<span class="bkbg-b64-output-placeholder">Output will appear here…</span><span class="bkbg-b64-toast" id="b64-toast">Copied!</span>';
179 currentOutput = '';
180 return;
181 }
182
183 if (mode === 'encode') {
184 res = toBase64(text, urlSafe, lb);
185 } else {
186 res = fromBase64(text, urlSafe);
187 }
188
189 if (res.error) {
190 outEl.innerHTML = '<span class="bkbg-b64-toast" id="b64-toast">Copied!</span>' +
191 '<span style="color:#f87171;font-style:italic">' + res.error + '</span>';
192 currentOutput = '';
193 } else {
194 var esc = res.result.replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;');
195 outEl.innerHTML = '<span class="bkbg-b64-toast" id="b64-toast">Copied!</span>' + esc;
196 currentOutput = res.result;
197 toast = root.querySelector('#b64-toast');
198
199 if (o.showStats) {
200 var inLen = text.length;
201 var outLen = res.result.replace(/\n/g,'').length;
202 var ratio = inLen > 0 ? (outLen / inLen).toFixed(2) + 'x' : '';
203 if (statIn) statIn.textContent = 'Input: ' + inLen + ' chars';
204 if (statOut) statOut.textContent = 'Output: ' + outLen + ' chars';
205 if (statRatio) statRatio.textContent = 'Ratio: ' + ratio;
206 }
207 }
208 }
209
210 // bind tab clicks
211 tabs.forEach(function(t) { t.addEventListener('click', function(){ setMode(t.getAttribute('data-mode')); }); });
212
213 // live conversion on input
214 inEl.addEventListener('input', convert);
215 if (urlsafeEl) urlsafeEl.addEventListener('change', convert);
216 if (lbEl) lbEl.addEventListener('change', convert);
217
218 // copy button
219 copyBtn.addEventListener('click', function() {
220 if (!currentOutput) return;
221 navigator.clipboard.writeText(currentOutput).then(function() {
222 var t2 = root.querySelector('#b64-toast');
223 if (t2) { t2.classList.add('show'); setTimeout(function(){ t2.classList.remove('show'); }, 1800); }
224 }).catch(function(){});
225 });
226
227 // initial
228 setMode(mode);
229 if (o.defaultInput) { inEl.value = o.defaultInput; convert(); }
230 });
231 })();
232