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

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

306 lines 14.5 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 /* ── Conversion data ────────────────────────────────────────────────────── */
5 var CATEGORIES = {
6 length: {
7 label: 'Length',
8 units: {
9 meter: { label: 'Meter (m)', toBase: 1 },
10 kilometer: { label: 'Kilometer (km)', toBase: 1000 },
11 centimeter: { label: 'Centimeter (cm)', toBase: 0.01 },
12 millimeter: { label: 'Millimeter (mm)', toBase: 0.001 },
13 mile: { label: 'Mile (mi)', toBase: 1609.344 },
14 yard: { label: 'Yard (yd)', toBase: 0.9144 },
15 foot: { label: 'Foot (ft)', toBase: 0.3048 },
16 inch: { label: 'Inch (in)', toBase: 0.0254 },
17 nautical_mile: { label: 'Nautical Mile', toBase: 1852 },
18 },
19 defaultFrom: 'meter', defaultTo: 'foot',
20 },
21 weight: {
22 label: 'Weight',
23 units: {
24 kilogram: { label: 'Kilogram (kg)', toBase: 1 },
25 gram: { label: 'Gram (g)', toBase: 0.001 },
26 milligram: { label: 'Milligram (mg)', toBase: 0.000001 },
27 pound: { label: 'Pound (lb)', toBase: 0.453592 },
28 ounce: { label: 'Ounce (oz)', toBase: 0.0283495 },
29 ton: { label: 'Metric Ton (t)', toBase: 1000 },
30 stone: { label: 'Stone (st)', toBase: 6.35029 },
31 },
32 defaultFrom: 'kilogram', defaultTo: 'pound',
33 },
34 temperature: {
35 label: 'Temperature',
36 units: {
37 celsius: { label: 'Celsius (°C)' },
38 fahrenheit: { label: 'Fahrenheit (°F)' },
39 kelvin: { label: 'Kelvin (K)' },
40 },
41 defaultFrom: 'celsius', defaultTo: 'fahrenheit',
42 },
43 volume: {
44 label: 'Volume',
45 units: {
46 liter: { label: 'Liter (L)', toBase: 1 },
47 milliliter: { label: 'Milliliter (mL)', toBase: 0.001 },
48 cubic_meter: { label: 'Cubic Meter (m³)', toBase: 1000 },
49 gallon_us: { label: 'Gallon (US)', toBase: 3.78541 },
50 gallon_uk: { label: 'Gallon (UK)', toBase: 4.54609 },
51 quart: { label: 'Quart (US)', toBase: 0.946353 },
52 pint: { label: 'Pint (US)', toBase: 0.473176 },
53 cup: { label: 'Cup (US)', toBase: 0.236588 },
54 fluid_oz: { label: 'Fluid Oz (US)', toBase: 0.0295735 },
55 tablespoon: { label: 'Tablespoon', toBase: 0.0147868 },
56 teaspoon: { label: 'Teaspoon', toBase: 0.00492892 },
57 },
58 defaultFrom: 'liter', defaultTo: 'gallon_us',
59 },
60 area: {
61 label: 'Area',
62 units: {
63 sqmeter: { label: 'Square Meter (m²)', toBase: 1 },
64 sqkilometer: { label: 'Square Km (km²)', toBase: 1000000 },
65 sqcentimeter: { label: 'Square Cm (cm²)', toBase: 0.0001 },
66 sqfoot: { label: 'Square Foot (ft²)', toBase: 0.092903 },
67 sqinch: { label: 'Square Inch (in²)', toBase: 0.00064516 },
68 sqyard: { label: 'Square Yard (yd²)', toBase: 0.836127 },
69 squaremile: { label: 'Square Mile (mi²)', toBase: 2589988 },
70 acre: { label: 'Acre', toBase: 4046.86 },
71 hectare: { label: 'Hectare (ha)', toBase: 10000 },
72 },
73 defaultFrom: 'sqmeter', defaultTo: 'sqfoot',
74 },
75 speed: {
76 label: 'Speed',
77 units: {
78 ms: { label: 'Meter/second (m/s)', toBase: 1 },
79 kmh: { label: 'Km/hour (km/h)', toBase: 0.277778 },
80 mph: { label: 'Mile/hour (mph)', toBase: 0.44704 },
81 knot: { label: 'Knot (kn)', toBase: 0.514444 },
82 fts: { label: 'Foot/second (ft/s)', toBase: 0.3048 },
83 mach: { label: 'Mach', toBase: 343 },
84 },
85 defaultFrom: 'kmh', defaultTo: 'mph',
86 },
87 };
88
89 function convertValue(catKey, fromKey, toKey, value) {
90 var num = parseFloat(value);
91 if (isNaN(num)) return null;
92 if (catKey === 'temperature') {
93 var c;
94 if (fromKey === 'celsius') c = num;
95 else if (fromKey === 'fahrenheit') c = (num - 32) * 5 / 9;
96 else c = num - 273.15;
97 if (toKey === 'celsius') return c;
98 if (toKey === 'fahrenheit') return c * 9 / 5 + 32;
99 return c + 273.15;
100 }
101 var units = CATEGORIES[catKey].units;
102 var base = num * (units[fromKey].toBase || 1);
103 return base / (units[toKey].toBase || 1);
104 }
105
106 function fmtResult(val, dp) {
107 if (val === null || isNaN(val)) return '';
108 if (Math.abs(val) < 1e-10 && val !== 0) return val.toExponential(4);
109 return parseFloat(val.toFixed(dp)).toLocaleString('en-US', { maximumFractionDigits: dp });
110 }
111
112 function buildApp(app) {
113 var opts = {};
114 try { opts = JSON.parse(app.dataset.opts || '{}'); } catch (e) {}
115
116 var enabled = opts.enabledCategories && opts.enabledCategories.length ? opts.enabledCategories : Object.keys(CATEGORIES);
117 var activeCat = (opts.defaultCategory && CATEGORIES[opts.defaultCategory]) ? opts.defaultCategory : enabled[0] || 'length';
118 var fromKey, toKey;
119 var inputValue = '1';
120 var dp = parseInt(opts.decimalPlaces) || 4;
121
122 /* -- colors -- */
123 var accent = opts.accentColor || '#6c3fb5';
124 var tabActBg = opts.tabActiveBg || accent;
125 var tabActCol = opts.tabActiveColor|| '#ffffff';
126 var tabInBg = opts.tabInactiveBg || '#f3f4f6';
127 var tabInCol = opts.tabInactiveColor || '#374151';
128 var cardBg = opts.cardBg || '#ffffff';
129 var resultBg = opts.resultBg || '#f5f3ff';
130 var resultBdr = opts.resultBorder || '#ede9fe';
131 var resultCol = opts.resultColor || accent;
132 var labelColor = opts.labelColor || '#374151';
133 var titleColor = opts.titleColor || '#1e1b4b';
134 var subColor = opts.subtitleColor || '#6b7280';
135 var radius = (opts.cardRadius || 16) + 'px';
136 var btnR = '8px';
137 var maxW = (opts.maxWidth || 640) + 'px';
138 var ptop = (opts.paddingTop || 60) + 'px';
139 var pbot = (opts.paddingBottom|| 60) + 'px';
140 var resSize = (opts.resultSize || 40) + 'px';\n\n /* -- build card -- */
141 app.innerHTML = '';
142 var card = document.createElement('div');
143 card.className = 'bkbg-uc-card';
144 card.style.cssText = 'background:' + cardBg + ';border-radius:' + radius + ';padding:32px;box-shadow:0 4px 24px rgba(0,0,0,0.08);max-width:' + maxW + ';margin:0 auto;padding-top:' + ptop + ';padding-bottom:' + pbot + ';box-sizing:border-box;';
145 app.appendChild(card);
146
147 /* title */
148 if (opts.showTitle !== false && opts.title) {
149 var titleEl = document.createElement('h2');
150 titleEl.className = 'bkbg-uc-title';
151 titleEl.textContent = opts.title;
152 titleEl.style.color = titleColor;
153 card.appendChild(titleEl);
154 }
155 if (opts.showSubtitle !== false && opts.subtitle) {
156 var subEl = document.createElement('p');
157 subEl.className = 'bkbg-uc-subtitle';
158 subEl.textContent = opts.subtitle;
159 subEl.style.color = subColor;
160 card.appendChild(subEl);
161 }
162
163 /* tabs */
164 var tabsEl = null;
165 if (opts.showCategoryTabs !== false && enabled.length > 1) {
166 tabsEl = document.createElement('div');
167 tabsEl.className = 'bkbg-uc-tabs';
168 card.appendChild(tabsEl);
169 }
170
171 /* from/to row */
172 var row = document.createElement('div');
173 row.className = 'bkbg-uc-row';
174 card.appendChild(row);
175
176 var fromWrap = document.createElement('div');
177 var swapWrap = document.createElement('div');
178 swapWrap.className = 'bkbg-uc-swap-wrap';
179 var toWrap = document.createElement('div');
180 row.appendChild(fromWrap);
181 row.appendChild(swapWrap);
182 row.appendChild(toWrap);
183
184 var lblFrom = document.createElement('label'); lblFrom.textContent = 'From'; lblFrom.className = 'bkbg-uc-label'; lblFrom.style.color = labelColor;
185 var selFrom = document.createElement('select'); selFrom.className = 'bkbg-uc-select'; selFrom.style.accentColor = accent;
186 fromWrap.appendChild(lblFrom); fromWrap.appendChild(selFrom);
187
188 if (opts.showSwapButton !== false) {
189 var swapBtn = document.createElement('button');
190 swapBtn.className = 'bkbg-uc-swap';
191 swapBtn.textContent = '';
192 swapBtn.style.cssText = 'color:' + accent + ';border-color:' + accent + ';';
193 swapWrap.appendChild(swapBtn);
194 }
195
196 var lblTo = document.createElement('label'); lblTo.textContent = 'To'; lblTo.className = 'bkbg-uc-label'; lblTo.style.color = labelColor;
197 var selTo = document.createElement('select'); selTo.className = 'bkbg-uc-select'; selTo.style.accentColor = accent;
198 toWrap.appendChild(lblTo); toWrap.appendChild(selTo);
199
200 /* value input */
201 var valWrap = document.createElement('div'); valWrap.className = 'bkbg-uc-value-wrap';
202 var valLabel = document.createElement('label'); valLabel.textContent = 'Value'; valLabel.className = 'bkbg-uc-label'; valLabel.style.color = labelColor;
203 var valInp = document.createElement('input'); valInp.type = 'number'; valInp.className = 'bkbg-uc-value'; valInp.value = inputValue; valInp.style.accentColor = accent;
204 valWrap.appendChild(valLabel); valWrap.appendChild(valInp);
205 card.appendChild(valWrap);
206
207 /* result */
208 var resBox = document.createElement('div'); resBox.className = 'bkbg-uc-result';
209 resBox.style.cssText = 'background:' + resultBg + ';border:1.5px solid ' + resultBdr + ';border-radius:' + radius + ';';
210 var resFrom = document.createElement('div'); resFrom.className = 'bkbg-uc-result-from';
211 var resNum = document.createElement('div'); resNum.className = 'bkbg-uc-result-num'; resNum.style.cssText = 'font-size:' + resSize + ';color:' + resultCol + ';';
212 var resUnit = document.createElement('div'); resUnit.className = 'bkbg-uc-result-unit';
213 resBox.appendChild(resFrom); resBox.appendChild(resNum); resBox.appendChild(resUnit);
214 card.appendChild(resBox);
215
216 /* -- helpers -- */
217 function populateSelects() {
218 var cat = CATEGORIES[activeCat];
219 var keys = Object.keys(cat.units);
220 var opts2 = keys.map(function(k) { return { value: k, label: cat.units[k].label }; });
221
222 function fill(sel, current, defaultKey) {
223 sel.innerHTML = '';
224 opts2.forEach(function(o) {
225 var opt = document.createElement('option');
226 opt.value = o.value;
227 opt.textContent = o.label;
228 sel.appendChild(opt);
229 });
230 sel.value = current || defaultKey;
231 }
232 fill(selFrom, fromKey, cat.defaultFrom);
233 fill(selTo, toKey, cat.defaultTo);
234 fromKey = selFrom.value;
235 toKey = selTo.value;
236 }
237
238 function updateResult() {
239 var cat = CATEGORIES[activeCat];
240 var fromL = cat.units[fromKey] ? cat.units[fromKey].label : fromKey;
241 var toL = cat.units[toKey] ? cat.units[toKey].label : toKey;
242 var res = convertValue(activeCat, fromKey, toKey, valInp.value);
243 resFrom.textContent = fromL + '' + toL;
244 resNum.textContent = fmtResult(res, dp);
245 resUnit.textContent = toL;
246 }
247
248 function buildTabs() {
249 if (!tabsEl) return;
250 tabsEl.innerHTML = '';
251 enabled.forEach(function(k) {
252 if (!CATEGORIES[k]) return;
253 var btn = document.createElement('button');
254 btn.className = 'bkbg-uc-tab' + (k === activeCat ? ' active' : '');
255 btn.textContent = CATEGORIES[k].label;
256 btn.dataset.cat = k;
257 btn.style.background = k === activeCat ? tabActBg : tabInBg;
258 btn.style.color = k === activeCat ? tabActCol : tabInCol;
259 tabsEl.appendChild(btn);
260 });
261 }
262
263 function init() {
264 buildTabs();
265 populateSelects();
266 updateResult();
267 }
268 init();
269
270 /* -- events -- */
271 if (tabsEl) {
272 tabsEl.addEventListener('click', function(e) {
273 var btn = e.target.closest('.bkbg-uc-tab');
274 if (!btn) return;
275 activeCat = btn.dataset.cat;
276 fromKey = null; toKey = null;
277 tabsEl.querySelectorAll('.bkbg-uc-tab').forEach(function(b) {
278 var active = b.dataset.cat === activeCat;
279 b.classList.toggle('active', active);
280 b.style.background = active ? tabActBg : tabInBg;
281 b.style.color = active ? tabActCol : tabInCol;
282 });
283 populateSelects();
284 updateResult();
285 });
286 }
287
288 selFrom.addEventListener('change', function() { fromKey = selFrom.value; updateResult(); });
289 selTo.addEventListener('change', function() { toKey = selTo.value; updateResult(); });
290 valInp.addEventListener('input', function() { updateResult(); });
291
292 if (swapWrap.querySelector('.bkbg-uc-swap')) {
293 swapWrap.querySelector('.bkbg-uc-swap').addEventListener('click', function() {
294 var tmp = selFrom.value;
295 selFrom.value = selTo.value;
296 selTo.value = tmp;
297 fromKey = selFrom.value;
298 toKey = selTo.value;
299 updateResult();
300 });
301 }
302 }
303
304 document.querySelectorAll('.bkbg-uc-app').forEach(buildApp);
305 })();
306