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

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

194 lines 8.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 var _typoKeys = {
5 family: '-ff', sizeDesktop: '-fs', sizeTablet: '-fs-tab', sizeMobile: '-fs-mob',
6 weight: '-fw', style: '-fst', decoration: '-td', transform: '-tt',
7 letterSpacing: '-ls', lineHeight: '-lh'
8 };
9 function typoCssVarsForEl(el, obj, prefix) {
10 if (!obj) return;
11 Object.keys(_typoKeys).forEach(function (k) {
12 var v = obj[k]; if (v === undefined || v === '') return;
13 var u = (k === 'sizeDesktop' || k === 'sizeTablet' || k === 'sizeMobile')
14 ? (String(v).match(/[a-z%]/i) ? v : v + 'px')
15 : (k === 'lineHeight' ? String(v) : v);
16 el.style.setProperty(prefix + _typoKeys[k], u);
17 });
18 }
19
20 function scorePassword(pw, minLen) {
21 if (!pw) return 0;
22 var score = 0;
23 if (pw.length >= minLen) score++;
24 if (/[A-Z]/.test(pw)) score++;
25 if (/[a-z]/.test(pw)) score++;
26 if (/[0-9]/.test(pw)) score++;
27 if (/[^a-zA-Z0-9]/.test(pw)) score++;
28 return score; // 0-5
29 }
30
31 var LEVEL_COLORS = [null, '#ef4444', '#f59e0b', '#3b82f6', '#10b981'];
32
33 function init(app) {
34 var a;
35 try { a = JSON.parse(app.getAttribute('data-opts')); } catch(e) { return; }
36
37 var minLen = a.minLength || 8;
38 var strengthColors = [null, a.colorWeak||'#ef4444', a.colorFair||'#f59e0b', a.colorGood||'#3b82f6', a.colorStrong||'#10b981'];
39 var strengthLabels = [null, a.labelWeak||'Weak', a.labelFair||'Fair', a.labelGood||'Good', a.labelStrong||'Strong'];
40
41 // Section wrappers
42 app.style.paddingTop = (a.paddingTop || 60) + 'px';
43 app.style.paddingBottom = (a.paddingBottom || 60) + 'px';
44 if (a.sectionBg) app.style.background = a.sectionBg;
45 app.innerHTML = '';
46
47 var wrap = document.createElement('div');
48 wrap.className = 'bkbg-psm-wrap';
49 wrap.style.maxWidth = (a.maxWidth || 480) + 'px';
50 wrap.style.borderRadius = (a.cardRadius || 16) + 'px';
51 wrap.style.background = a.cardBg || '#fff';
52 app.appendChild(wrap);
53
54 // Header
55 if (a.showTitle || a.showSubtitle) {
56 var header = document.createElement('div');
57 header.className = 'bkbg-psm-header';
58 if (a.showTitle && a.title) {
59 var title = document.createElement('div');
60 title.className = 'bkbg-psm-title';
61 title.textContent = a.title;
62 if (a.titleColor) title.style.color = a.titleColor;
63 typoCssVarsForEl(title, a.titleTypo, '--bkbg-psm-title');
64 header.appendChild(title);
65 }
66 if (a.showSubtitle && a.subtitle) {
67 var sub = document.createElement('div');
68 sub.className = 'bkbg-psm-subtitle';
69 sub.textContent = a.subtitle;
70 if (a.subtitleColor) sub.style.color = a.subtitleColor;
71 typoCssVarsForEl(sub, a.subtitleTypo, '--bkbg-psm-subtitle');
72 header.appendChild(sub);
73 }
74 wrap.appendChild(header);
75 }
76
77 // Input row
78 var inputWrap = document.createElement('div');
79 inputWrap.className = 'bkbg-psm-input-wrap';
80
81 var input = document.createElement('input');
82 input.type = 'password';
83 input.className = 'bkbg-psm-input';
84 input.placeholder = a.placeholder || 'Enter a password…';
85 input.style.borderRadius = (a.inputRadius || 10) + 'px';
86 input.style.border = '1.5px solid ' + (a.inputBorder || '#e5e7eb');
87 input.style.background = a.inputBg || '#f9fafb';
88 if (!a.showToggleVisibility) input.style.paddingRight = '16px';
89 inputWrap.appendChild(input);
90
91 if (a.showToggleVisibility) {
92 var toggleBtn = document.createElement('button');
93 toggleBtn.type = 'button';
94 toggleBtn.className = 'bkbg-psm-toggle-vis';
95 toggleBtn.textContent = '👁️';
96 var visible = false;
97 toggleBtn.addEventListener('click', function() {
98 visible = !visible;
99 input.type = visible ? 'text' : 'password';
100 toggleBtn.textContent = visible ? '🙈' : '👁️';
101 });
102 inputWrap.appendChild(toggleBtn);
103 }
104 wrap.appendChild(inputWrap);
105
106 // Strength bar
107 var bar = document.createElement('div');
108 bar.className = 'bkbg-psm-bar';
109 var segments = [1,2,3,4].map(function(i) {
110 var seg = document.createElement('div');
111 seg.className = 'bkbg-psm-bar-seg';
112 seg.style.background = a.barBg || '#e5e7eb';
113 bar.appendChild(seg);
114 return seg;
115 });
116 wrap.appendChild(bar);
117
118 // Strength label row
119 var strengthRow = document.createElement('div');
120 strengthRow.className = 'bkbg-psm-strength-row';
121 var strengthHint = document.createElement('span');
122 strengthHint.className = 'bkbg-psm-strength-hint';
123 strengthHint.style.color = a.labelColor || '#6b7280';
124 strengthHint.textContent = '';
125 var strengthLabel = document.createElement('span');
126 strengthLabel.className = 'bkbg-psm-strength-label';
127 strengthRow.appendChild(strengthHint);
128 strengthRow.appendChild(strengthLabel);
129 wrap.appendChild(strengthRow);
130
131 // Requirements
132 var reqs = [
133 { key:'showLengthReq', test: function(pw){ return pw.length >= minLen; }, label: 'At least ' + minLen + ' characters' },
134 { key:'showUppercaseReq', test: function(pw){ return /[A-Z]/.test(pw); }, label: 'Uppercase letter (A-Z)' },
135 { key:'showLowercaseReq', test: function(pw){ return /[a-z]/.test(pw); }, label: 'Lowercase letter (a-z)' },
136 { key:'showNumberReq', test: function(pw){ return /[0-9]/.test(pw); }, label: 'Number (0-9)' },
137 { key:'showSymbolReq', test: function(pw){ return /[^a-zA-Z0-9]/.test(pw); }, label: 'Special character (!@#…)' }
138 ].filter(function(r){ return a[r.key]; });
139
140 var reqEls = [];
141 if (reqs.length) {
142 var reqContainer = document.createElement('div');
143 reqContainer.className = 'bkbg-psm-reqs';
144 reqs.forEach(function(r) {
145 var row = document.createElement('div');
146 row.className = 'bkbg-psm-req';
147 var icon = document.createElement('span');
148 icon.className = 'bkbg-psm-req-icon';
149 icon.textContent = '';
150 var txt = document.createElement('span');
151 txt.textContent = r.label;
152 row.appendChild(icon);
153 row.appendChild(txt);
154 reqContainer.appendChild(row);
155 reqEls.push({ el: row, icon: icon, test: r.test });
156 });
157 wrap.appendChild(reqContainer);
158 }
159
160 function update() {
161 var pw = input.value;
162 var score = scorePassword(pw, minLen);
163 var level = pw.length === 0 ? 0 : (score <= 2 ? score <= 1 ? 1 : 2 : score <= 3 ? 3 : 4);
164
165 segments.forEach(function(seg, i) {
166 seg.style.background = (pw.length > 0 && i < level)
167 ? (strengthColors[level] || '#10b981')
168 : (a.barBg || '#e5e7eb');
169 });
170
171 if (pw.length > 0) {
172 strengthHint.textContent = 'Password strength:';
173 strengthLabel.textContent = strengthLabels[level] || '';
174 strengthLabel.style.color = strengthColors[level] || '#10b981';
175 } else {
176 strengthHint.textContent = '';
177 strengthLabel.textContent = '';
178 }
179
180 reqEls.forEach(function(r) {
181 var met = pw.length > 0 && r.test(pw);
182 r.el.classList.toggle('met', met);
183 r.icon.textContent = met ? '' : '';
184 r.el.style.color = met ? (a.reqMetColor || '#10b981') : (a.reqUnmetColor || '#9ca3af');
185 });
186 }
187
188 input.addEventListener('input', update);
189 update();
190 }
191
192 document.querySelectorAll('.bkbg-psm-app').forEach(init);
193 })();
194