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

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

299 lines 14.4 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 UPPER = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
26 var LOWER = 'abcdefghijklmnopqrstuvwxyz';
27 var NUMBERS = '0123456789';
28 var SYMBOLS = '!@#$%^&*()_+-=[]{}|;:,.<>?';
29
30 function generatePassword(opts) {
31 var pool = '';
32 if (opts.includeUppercase !== false) pool += UPPER;
33 if (opts.includeLowercase !== false) pool += LOWER;
34 if (opts.includeNumbers !== false) pool += NUMBERS;
35 if (opts.includeSymbols !== false) pool += SYMBOLS;
36 if (opts.excludeAmbiguous) pool = pool.replace(/[0Ol1I]/g, '');
37 if (!pool) pool = LOWER;
38
39 var len = opts.length || 16;
40 var result = '';
41 var arr = new Uint32Array(len);
42 if (window.crypto && window.crypto.getRandomValues) {
43 window.crypto.getRandomValues(arr);
44 for (var i = 0; i < len; i++) {
45 result += pool.charAt(arr[i] % pool.length);
46 }
47 } else {
48 for (var j = 0; j < len; j++) {
49 result += pool.charAt(Math.floor(Math.random() * pool.length));
50 }
51 }
52 return result;
53 }
54
55 function getStrength(pwd, opts) {
56 var score = 0;
57 if (pwd.length >= 12) score++;
58 if (pwd.length >= 16) score++;
59 if (/[A-Z]/.test(pwd) && opts.includeUppercase !== false) score++;
60 if (/[0-9]/.test(pwd) && opts.includeNumbers !== false) score++;
61 if (/[^A-Za-z0-9]/.test(pwd) && opts.includeSymbols !== false) score++;
62 if (score <= 1) return { level: 'weak', label: 'Weak', pct: 25 };
63 if (score === 2) return { level: 'fair', label: 'Fair', pct: 50 };
64 if (score === 3) return { level: 'good', label: 'Good', pct: 75 };
65 return { level: 'strong', label: 'Strong', pct: 100 };
66 }
67
68 function buildApp(app) {
69 var opts = {};
70 try { opts = JSON.parse(app.dataset.opts || '{}'); } catch (e) {}
71
72 /* Current state */
73 var length = opts.defaultLength || 16;
74 var upper = opts.includeUppercase !== false;
75 var lower = opts.includeLowercase !== false;
76 var numbers = opts.includeNumbers !== false;
77 var symbols = opts.includeSymbols !== false;
78 var excAmb = opts.excludeAmbiguous === true;
79 var visible = false;
80 var currentPwd = '';
81
82 /* Colors */
83 var accent = opts.accentColor || '#6c3fb5';
84 var cardBg = opts.cardBg || '#ffffff';
85 var pwdBg = opts.pwdBg || '#f5f3ff';
86 var pwdBdr = opts.pwdBorder || '#ede9fe';
87 var pwdColor = opts.pwdColor || '#1e1b4b';
88 var labelColor= opts.labelColor || '#374151';
89 var titleColor= opts.titleColor || '#1e1b4b';
90 var subColor = opts.subtitleColor || '#6b7280';
91 var copyBg = opts.copyBtnBg || accent;
92 var copyCol = opts.copyBtnColor || '#ffffff';
93 var genBg = opts.genBtnBg || '#f3f4f6';
94 var genCol = opts.genBtnColor || '#374151';
95 var strColors = {
96 weak: opts.strengthWeak || '#ef4444',
97 fair: opts.strengthFair || '#f59e0b',
98 good: opts.strengthGood || '#3b82f6',
99 strong: opts.strengthStrong || '#10b981',
100 };
101 var cRadius = (opts.cardRadius || 16) + 'px';
102 var btnR = (opts.btnRadius || 8) + 'px';
103 var maxW = (opts.maxWidth || 560) + 'px';
104 var ptop = (opts.paddingTop || 60) + 'px';
105 var pbot = (opts.paddingBottom || 60) + 'px';
106 var pwdSize = (opts.pwdFontSize || 20) + 'px';
107 var titleSize= (opts.titleSize || 26) + 'px';
108
109 /* Build card */
110 app.innerHTML = '';
111 var card = document.createElement('div');
112 card.className = 'bkbg-pg-card';
113 card.style.cssText = 'background:' + cardBg + ';border-radius:' + cRadius + ';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;';
114 app.appendChild(card);
115
116 typoCssVarsForEl(card, opts.titleTypo, '--bkbg-pg-tt-');
117 typoCssVarsForEl(card, opts.pwdTypo, '--bkbg-pg-pw-');
118
119 if (opts.showTitle !== false && opts.title) {
120 var titleEl = document.createElement('h2');
121 titleEl.className = 'bkbg-pg-title';
122 titleEl.textContent = opts.title;
123 titleEl.style.color = titleColor;
124 card.appendChild(titleEl);
125 }
126 if (opts.showSubtitle !== false && opts.subtitle) {
127 var subEl = document.createElement('p');
128 subEl.className = 'bkbg-pg-subtitle';
129 subEl.textContent = opts.subtitle;
130 subEl.style.color = subColor;
131 card.appendChild(subEl);
132 }
133
134 /* Password display */
135 var dispBox = document.createElement('div');
136 dispBox.className = 'bkbg-pg-display';
137 dispBox.style.cssText = 'background:' + pwdBg + ';border-color:' + pwdBdr + ';border-radius:' + cRadius + ';border:1.5px solid ' + pwdBdr + ';';
138 card.appendChild(dispBox);
139
140 var pwdEl = document.createElement('div');
141 pwdEl.className = 'bkbg-pg-password blurred';
142 pwdEl.style.color = pwdColor;
143 dispBox.appendChild(pwdEl);
144
145 if (opts.showToggleVisible !== false) {
146 var visBtn = document.createElement('button');
147 visBtn.className = 'bkbg-pg-icon-btn vis';
148 visBtn.title = 'Show/hide password';
149 visBtn.style.color = '#9ca3af';
150 visBtn.textContent = '👁';
151 dispBox.appendChild(visBtn);
152 visBtn.addEventListener('click', function() {
153 visible = !visible;
154 pwdEl.classList.toggle('blurred', !visible);
155 visBtn.textContent = visible ? '🙈' : '👁';
156 });
157 }
158
159 if (opts.showRefreshBtn !== false) {
160 var refBtn = document.createElement('button');
161 refBtn.className = 'bkbg-pg-icon-btn refresh';
162 refBtn.title = 'Generate new';
163 refBtn.style.color = accent;
164 refBtn.textContent = '';
165 dispBox.appendChild(refBtn);
166 refBtn.addEventListener('click', generate);
167 }
168
169 /* Strength bar */
170 var strWrap = null, strFill = null, strLabel = null;
171 if (opts.showStrength !== false) {
172 strWrap = document.createElement('div'); strWrap.className = 'bkbg-pg-strength';
173 var strHdr = document.createElement('div'); strHdr.className = 'bkbg-pg-strength-header';
174 var strLblLeft = document.createElement('span'); strLblLeft.textContent = 'Strength'; strLblLeft.style.color = labelColor;
175 strLabel = document.createElement('span'); strLabel.style.fontWeight = '700';
176 strHdr.appendChild(strLblLeft); strHdr.appendChild(strLabel);
177 var strTrack = document.createElement('div'); strTrack.className = 'bkbg-pg-strength-track';
178 strFill = document.createElement('div'); strFill.className = 'bkbg-pg-strength-fill';
179 strTrack.appendChild(strFill);
180 strWrap.appendChild(strHdr); strWrap.appendChild(strTrack);
181 card.appendChild(strWrap);
182 }
183
184 /* Length slider */
185 var rangeEl = null, lengthNumEl = null;
186 if (opts.showLength !== false) {
187 var lenWrap = document.createElement('div'); lenWrap.className = 'bkbg-pg-length';
188 var lenHdr = document.createElement('div'); lenHdr.className = 'bkbg-pg-length-header';
189 var lenLbl = document.createElement('span'); lenLbl.textContent = 'Length'; lenLbl.style.color = labelColor;
190 lengthNumEl = document.createElement('span'); lengthNumEl.className = 'bkbg-pg-length-num'; lengthNumEl.style.color = accent;
191 lenHdr.appendChild(lenLbl); lenHdr.appendChild(lengthNumEl);
192 rangeEl = document.createElement('input'); rangeEl.type = 'range'; rangeEl.className = 'bkbg-pg-range';
193 rangeEl.min = opts.minLength || 6; rangeEl.max = opts.maxLength || 64; rangeEl.value = length;
194 rangeEl.style.accentColor = accent; rangeEl.style.color = accent;
195 lenWrap.appendChild(lenHdr); lenWrap.appendChild(rangeEl);
196 card.appendChild(lenWrap);
197 rangeEl.addEventListener('input', function() { length = parseInt(this.value); lengthNumEl.textContent = length; generate(); });
198 }
199
200 /* Checkboxes */
201 var optsGrid = document.createElement('div'); optsGrid.className = 'bkbg-pg-options';
202 card.appendChild(optsGrid);
203
204 var chkUpper, chkLower, chkNum, chkSym, chkAmb;
205 function makeChk(id, labelText, checked, fullWidth) {
206 var lbl = document.createElement('label'); lbl.className = 'bkbg-pg-option' + (fullWidth ? ' full-width' : ''); lbl.style.color = labelColor;
207 var chk = document.createElement('input'); chk.type = 'checkbox'; chk.checked = checked; chk.style.accentColor = accent;
208 var txt = document.createTextNode(' ' + labelText);
209 lbl.appendChild(chk); lbl.appendChild(txt);
210 optsGrid.appendChild(lbl);
211 return chk;
212 }
213
214 chkUpper = makeChk('upper', 'Uppercase (A-Z)', upper, false);
215 chkLower = makeChk('lower', 'Lowercase (a-z)', lower, false);
216 chkNum = makeChk('num', 'Numbers (0-9)', numbers, false);
217 chkSym = makeChk('sym', 'Symbols (!@#…)', symbols, false);
218 chkAmb = makeChk('amb', 'Exclude ambiguous (0,O,l,1,I)',excAmb, true);
219
220 [chkUpper, chkLower, chkNum, chkSym, chkAmb].forEach(function(chk) {
221 chk.addEventListener('change', function() {
222 upper = chkUpper.checked;
223 lower = chkLower.checked;
224 numbers = chkNum.checked;
225 symbols = chkSym.checked;
226 excAmb = chkAmb.checked;
227 generate();
228 });
229 });
230
231 /* Action buttons */
232 var actionsRow = document.createElement('div'); actionsRow.className = 'bkbg-pg-actions';
233 card.appendChild(actionsRow);
234
235 var genBtn = document.createElement('button');
236 genBtn.className = 'bkbg-pg-btn generate';
237 genBtn.textContent = opts.generateLabel || 'Generate New';
238 genBtn.style.cssText = 'background:' + genBg + ';color:' + genCol + ';border-radius:' + btnR + ';';
239 actionsRow.appendChild(genBtn);
240 genBtn.addEventListener('click', generate);
241
242 var copyBtn = null;
243 if (opts.showCopyBtn !== false) {
244 copyBtn = document.createElement('button');
245 copyBtn.className = 'bkbg-pg-btn copy';
246 copyBtn.textContent = opts.copyLabel || 'Copy Password';
247 copyBtn.style.cssText = 'background:' + copyBg + ';color:' + copyCol + ';border-radius:' + btnR + ';';
248 actionsRow.appendChild(copyBtn);
249 copyBtn.addEventListener('click', function() {
250 if (!currentPwd) return;
251 if (navigator.clipboard && navigator.clipboard.writeText) {
252 navigator.clipboard.writeText(currentPwd).then(function() { showCopied(); });
253 } else {
254 var ta = document.createElement('textarea');
255 ta.value = currentPwd;
256 ta.style.position = 'fixed'; ta.style.opacity = '0';
257 document.body.appendChild(ta); ta.select();
258 document.execCommand('copy');
259 document.body.removeChild(ta);
260 showCopied();
261 }
262 });
263 }
264
265 function showCopied() {
266 if (!copyBtn) return;
267 copyBtn.textContent = opts.copiedLabel || 'Copied!';
268 copyBtn.style.background = '#10b981';
269 copyBtn.classList.add('success');
270 setTimeout(function() {
271 copyBtn.textContent = opts.copyLabel || 'Copy Password';
272 copyBtn.style.background = copyBg;
273 copyBtn.classList.remove('success');
274 }, 2000);
275 }
276
277 function generate() {
278 var pwd = generatePassword({ includeUppercase: upper, includeLowercase: lower, includeNumbers: numbers, includeSymbols: symbols, excludeAmbiguous: excAmb, length: length });
279 currentPwd = pwd;
280 pwdEl.textContent = pwd;
281
282 if (lengthNumEl) lengthNumEl.textContent = length;
283
284 if (strFill && strLabel) {
285 var s = getStrength(pwd, { includeUppercase: upper, includeNumbers: numbers, includeSymbols: symbols });
286 var col = strColors[s.level];
287 strFill.style.width = s.pct + '%';
288 strFill.style.background = col;
289 strLabel.textContent = s.label;
290 strLabel.style.color = col;
291 }
292 }
293
294 generate();
295 }
296
297 document.querySelectorAll('.bkbg-pg-app').forEach(buildApp);
298 })();
299