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 / content-lock / frontend.js

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

410 lines 19.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 (function () {
2 function typoCssVarsForEl(typo, prefix, el) {
3 if (!typo || typeof typo !== 'object') return;
4
5 // Non-responsive
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
12 // Responsive
13 var su = typo.sizeUnit || 'px';
14 if (typo.sizeDesktop !== '' && typo.sizeDesktop !== undefined && typo.sizeDesktop !== null) el.style.setProperty(prefix + 'font-size-d', typo.sizeDesktop + su);
15 if (typo.sizeTablet !== '' && typo.sizeTablet !== undefined && typo.sizeTablet !== null) el.style.setProperty(prefix + 'font-size-t', typo.sizeTablet + su);
16 if (typo.sizeMobile !== '' && typo.sizeMobile !== undefined && typo.sizeMobile !== null) el.style.setProperty(prefix + 'font-size-m', typo.sizeMobile + su);
17
18 var lhu = typo.lineHeightUnit || 'px';
19 if (typo.lineHeightDesktop !== '' && typo.lineHeightDesktop !== undefined && typo.lineHeightDesktop !== null) el.style.setProperty(prefix + 'line-height-d', typo.lineHeightDesktop + lhu);
20 if (typo.lineHeightTablet !== '' && typo.lineHeightTablet !== undefined && typo.lineHeightTablet !== null) el.style.setProperty(prefix + 'line-height-t', typo.lineHeightTablet + lhu);
21 if (typo.lineHeightMobile !== '' && typo.lineHeightMobile !== undefined && typo.lineHeightMobile !== null) el.style.setProperty(prefix + 'line-height-m', typo.lineHeightMobile + lhu);
22
23 var lsu = typo.letterSpacingUnit || 'px';
24 if (typo.letterSpacingDesktop !== '' && typo.letterSpacingDesktop !== undefined && typo.letterSpacingDesktop !== null) {
25 el.style.setProperty(prefix + 'letter-spacing-d', typo.letterSpacingDesktop + lsu);
26 el.style.setProperty(prefix + 'letter-spacing', typo.letterSpacingDesktop + lsu);
27 }
28 if (typo.letterSpacingTablet !== '' && typo.letterSpacingTablet !== undefined && typo.letterSpacingTablet !== null) el.style.setProperty(prefix + 'letter-spacing-t', typo.letterSpacingTablet + lsu);
29 if (typo.letterSpacingMobile !== '' && typo.letterSpacingMobile !== undefined && typo.letterSpacingMobile !== null) el.style.setProperty(prefix + 'letter-spacing-m', typo.letterSpacingMobile + lsu);
30
31 var wsu = typo.wordSpacingUnit || 'px';
32 if (typo.wordSpacingDesktop !== '' && typo.wordSpacingDesktop !== undefined && typo.wordSpacingDesktop !== null) {
33 el.style.setProperty(prefix + 'word-spacing-d', typo.wordSpacingDesktop + wsu);
34 el.style.setProperty(prefix + 'word-spacing', typo.wordSpacingDesktop + wsu);
35 }
36 if (typo.wordSpacingTablet !== '' && typo.wordSpacingTablet !== undefined && typo.wordSpacingTablet !== null) el.style.setProperty(prefix + 'word-spacing-t', typo.wordSpacingTablet + wsu);
37 if (typo.wordSpacingMobile !== '' && typo.wordSpacingMobile !== undefined && typo.wordSpacingMobile !== null) el.style.setProperty(prefix + 'word-spacing-m', typo.wordSpacingMobile + wsu);
38 }
39
40 function isValidEmail(email) {
41 return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email.trim());
42 }
43
44 function getStorageKey(o) {
45 return 'bkbg-cl-' + (o.storageKey || window.location.pathname);
46 }
47
48 function init() {
49 document.querySelectorAll('.bkbg-cl-app').forEach(function (appEl) {
50 if (appEl.dataset.rendered) return;
51 appEl.dataset.rendered = '1';
52
53 var opts;
54 try { opts = JSON.parse(appEl.dataset.opts || '{}'); } catch (e) { opts = {}; }
55
56 var o = Object.assign({
57 lockType: 'email',
58 lockedContent: '',
59 lockStyle: 'blur',
60 blurAmount: 6,
61 teaserLines: 3,
62 icon: '🔒',
63 showIcon: true,
64 eyebrow: 'Members Only',
65 showEyebrow: true,
66 heading: 'Unlock this content',
67 subText: 'Enter your email to get instant access.',
68 emailPlaceholder: 'Enter your email address',
69 submitLabel: 'Unlock Now',
70 privacyNote: 'We respect your privacy. No spam, ever.',
71 showPrivacy: true,
72 successHeading: 'You\'re in! 🎉',
73 successText: 'Enjoy your exclusive content below.',
74 rememberUnlock: true,
75 storageKey: '',
76 password: '',
77 passwordPlaceholder: 'Enter password',
78 passwordSubmitLabel: 'Unlock',
79 passwordErrorMsg: 'Incorrect password. Please try again.',
80 clickButtonLabel: 'Reveal Content',
81 clickButtonIcon: '👁',
82 webhookUrl: '',
83 borderRadius: 16,
84 padding: 40,
85 maxWidth: 560,
86 inputRadius: 8,
87 gateBg: '#ffffff',
88 eyebrowColor: '#6366f1',
89 headingColor: '#111827',
90 textColor: '#6b7280',
91 inputBg: '#f9fafb',
92 inputBorder: '#e5e7eb',
93 inputFocusBorder: '#6366f1',
94 inputColor: '#111827',
95 btnBg: '#6366f1',
96 btnColor: '#ffffff',
97 privacyColor: '#9ca3af',
98 }, opts);
99
100 var storageKey = getStorageKey(o);
101 var alreadyUnlocked = o.rememberUnlock && localStorage.getItem(storageKey) === '1';
102
103 // Outer wrap
104 var wrap = document.createElement('div');
105 wrap.className = 'bkbg-cl-wrap';
106 wrap.style.position = 'relative';
107
108 // Success banner (above content)
109 var successBanner = document.createElement('div');
110 successBanner.className = 'bkbg-cl-success' + (alreadyUnlocked ? ' is-visible' : '');
111 successBanner.style.background = '#f0fdf4';
112 successBanner.style.border = '1px solid #86efac';
113 successBanner.style.borderRadius = '8px';
114 successBanner.style.padding = '10px 16px';
115 successBanner.style.marginBottom = '16px';
116 var sh = document.createElement('p');
117 sh.className = 'bkbg-cl-success-heading';
118 sh.textContent = o.successHeading;
119 sh.style.fontWeight = '700';
120 sh.style.color = '#166534';
121 sh.style.margin = '0 0 2px';
122 sh.style.fontSize = '15px';
123 var st = document.createElement('p');
124 st.className = 'bkbg-cl-success-text';
125 st.textContent = o.successText;
126 st.style.color = '#15803d';
127 st.style.margin = '0';
128 st.style.fontSize = '13px';
129 successBanner.appendChild(sh);
130 successBanner.appendChild(st);
131 wrap.appendChild(successBanner);
132
133 // Unlocked content container
134 var unlockedDiv = document.createElement('div');
135 unlockedDiv.className = 'bkbg-cl-unlocked-content' + (alreadyUnlocked ? ' is-revealed' : '');
136 unlockedDiv.style.lineHeight = '1.7';
137 if (alreadyUnlocked) { unlockedDiv.style.display = 'block'; }
138 else { unlockedDiv.style.display = 'none'; }
139 unlockedDiv.innerHTML = o.lockedContent;
140 wrap.appendChild(unlockedDiv);
141
142 // Gate section (hidden when unlocked)
143 var gateWrap = document.createElement('div');
144 gateWrap.style.display = alreadyUnlocked ? 'none' : 'block';
145
146 // Content preview (blurred)
147 if (o.lockStyle !== 'hide' && o.lockedContent && !alreadyUnlocked) {
148 var contentPreview = document.createElement('div');
149 contentPreview.className = 'bkbg-cl-content';
150 contentPreview.innerHTML = o.lockedContent;
151 if (o.lockStyle === 'blur') {
152 var lineH = 1.7;
153 var fSize = 16; // approx
154 contentPreview.style.maxHeight = (o.teaserLines * lineH * fSize) + 'px';
155 contentPreview.style.overflow = 'hidden';
156 contentPreview.style.filter = 'blur(' + o.blurAmount + 'px)';
157 } else if (o.lockStyle === 'fade') {
158 contentPreview.style.maxHeight = '120px';
159 contentPreview.style.overflow = 'hidden';
160 }
161 contentPreview.style.pointerEvents = 'none';
162 contentPreview.style.userSelect = 'none';
163 gateWrap.appendChild(contentPreview);
164
165 // Fade overlay
166 if (o.lockStyle === 'blur' || o.lockStyle === 'fade') {
167 var fadeOverlay = document.createElement('div');
168 fadeOverlay.className = 'bkbg-cl-fade-overlay';
169 fadeOverlay.style.position = 'absolute';
170 fadeOverlay.style.bottom = 'auto';
171 fadeOverlay.style.left = '0';
172 fadeOverlay.style.right = '0';
173 fadeOverlay.style.height = '80px';
174 fadeOverlay.style.background = 'linear-gradient(transparent 0%, rgba(255,255,255,0.97) 100%)';
175 fadeOverlay.style.pointerEvents = 'none';
176 fadeOverlay.style.marginTop = '-80px';
177 fadeOverlay.style.position = 'relative';
178 gateWrap.appendChild(fadeOverlay);
179 }
180 }
181
182 // Gate card
183 var gate = document.createElement('div');
184 gate.className = 'bkbg-cl-gate';
185 gate.style.background = o.gateBg;
186 gate.style.borderRadius = o.borderRadius + 'px';
187 gate.style.padding = o.padding + 'px';
188 gate.style.maxWidth = o.maxWidth + 'px';
189 gate.style.margin = '24px auto 0';
190 gate.style.display = 'flex';
191 gate.style.flexDirection = 'column';
192 gate.style.alignItems = 'center';
193 gate.style.gap = '16px';
194 gate.style.textAlign = 'center';
195 gate.style.boxShadow = '0 4px 24px rgba(0,0,0,0.10)';
196
197 // Icon
198 if (o.showIcon && o.icon) {
199 var iconEl = document.createElement('div');
200 iconEl.className = 'bkbg-cl-icon';
201 iconEl.textContent = o.icon;
202 iconEl.style.fontSize = '40px';
203 iconEl.style.lineHeight = '1';
204 gate.appendChild(iconEl);
205 }
206
207 // Eyebrow
208 if (o.showEyebrow && o.eyebrow) {
209 var eyebrowEl = document.createElement('div');
210 eyebrowEl.className = 'bkbg-cl-eyebrow';
211 eyebrowEl.textContent = o.eyebrow;
212 eyebrowEl.style.fontSize = '11px';
213 eyebrowEl.style.fontWeight = '700';
214 eyebrowEl.style.letterSpacing = '0.08em';
215 eyebrowEl.style.textTransform = 'uppercase';
216 eyebrowEl.style.color = o.eyebrowColor;
217 gate.appendChild(eyebrowEl);
218 }
219
220 // Heading
221 var headingEl = document.createElement('h3');
222 headingEl.className = 'bkbg-cl-heading';
223 headingEl.textContent = o.heading;
224 headingEl.style.margin = '0';
225 headingEl.style.color = o.headingColor;
226 gate.appendChild(headingEl);
227
228 // Sub-text
229 if (o.subText) {
230 var subEl = document.createElement('p');
231 subEl.className = 'bkbg-cl-subtext';
232 subEl.textContent = o.subText;
233 subEl.style.margin = '0';
234 subEl.style.fontSize = '14px';
235 subEl.style.color = o.textColor;
236 subEl.style.lineHeight = '1.6';
237 gate.appendChild(subEl);
238 }
239
240 var errorEl = document.createElement('div');
241 errorEl.className = 'bkbg-cl-error';
242 errorEl.style.fontSize = '13px';
243 errorEl.style.color = '#dc2626';
244 errorEl.style.display = 'none';
245 errorEl.style.fontWeight = '500';
246 errorEl.style.width = '100%';
247 errorEl.style.textAlign = 'left';
248 gate.appendChild(errorEl);
249
250 function unlockContent() {
251 gateWrap.style.display = 'none';
252 unlockedDiv.style.display = 'block';
253 successBanner.style.display = 'block';
254 if (o.rememberUnlock) {
255 try { localStorage.setItem(storageKey, '1'); } catch (e) {}
256 }
257 }
258
259 function showError(msg) {
260 errorEl.textContent = msg;
261 errorEl.style.display = 'block';
262 setTimeout(function () { errorEl.style.display = 'none'; }, 4000);
263 }
264
265 // Form
266 var formEl = document.createElement('div');
267 formEl.className = 'bkbg-cl-form';
268 formEl.style.width = '100%';
269 formEl.style.display = 'flex';
270 formEl.style.flexDirection = 'column';
271 formEl.style.gap = '10px';
272
273 if (o.lockType === 'email') {
274 var emailInput = document.createElement('input');
275 emailInput.type = 'email';
276 emailInput.placeholder = o.emailPlaceholder;
277 emailInput.className = 'bkbg-cl-input';
278 emailInput.style.width = '100%';
279 emailInput.style.padding = '12px 16px';
280 emailInput.style.borderRadius = o.inputRadius + 'px';
281 emailInput.style.border = '1px solid ' + o.inputBorder;
282 emailInput.style.background = o.inputBg;
283 emailInput.style.color = o.inputColor;
284 emailInput.style.fontSize = '15px';
285 emailInput.style.boxSizing = 'border-box';
286 emailInput.style.outline = 'none';
287 emailInput.style.transition = 'border-color 0.2s';
288 emailInput.addEventListener('focus', function () {
289 emailInput.style.borderColor = o.inputFocusBorder;
290 });
291 emailInput.addEventListener('blur', function () {
292 emailInput.style.borderColor = o.inputBorder;
293 });
294 formEl.appendChild(emailInput);
295
296 var submitBtn = document.createElement('button');
297 submitBtn.className = 'bkbg-cl-btn';
298 submitBtn.textContent = o.submitLabel;
299 submitBtn.style.padding = '12px 24px';
300 submitBtn.style.borderRadius = o.inputRadius + 'px';
301 submitBtn.style.background = o.btnBg;
302 submitBtn.style.color = o.btnColor;
303 submitBtn.style.border = 'none';
304 submitBtn.style.cursor = 'pointer';
305 submitBtn.style.transition = 'opacity 0.2s, transform 0.15s';
306 submitBtn.addEventListener('click', function () {
307 var email = emailInput.value.trim();
308 if (!isValidEmail(email)) {
309 showError('Please enter a valid email address.');
310 emailInput.focus();
311 return;
312 }
313 // Webhook POST (optional)
314 if (o.webhookUrl) {
315 fetch(o.webhookUrl, {
316 method: 'POST',
317 headers: { 'Content-Type': 'application/json' },
318 body: JSON.stringify({ email: email, source: window.location.href }),
319 }).catch(function () {});
320 }
321 unlockContent();
322 });
323 formEl.appendChild(submitBtn);
324
325 if (o.showPrivacy && o.privacyNote) {
326 var privEl = document.createElement('p');
327 privEl.className = 'bkbg-cl-privacy';
328 privEl.textContent = o.privacyNote;
329 privEl.style.margin = '0';
330 privEl.style.fontSize = '12px';
331 privEl.style.color = o.privacyColor;
332 formEl.appendChild(privEl);
333 }
334
335 } else if (o.lockType === 'password') {
336 var pwInput = document.createElement('input');
337 pwInput.type = 'password';
338 pwInput.placeholder = o.passwordPlaceholder;
339 pwInput.className = 'bkbg-cl-input';
340 pwInput.style.width = '100%';
341 pwInput.style.padding = '12px 16px';
342 pwInput.style.borderRadius = o.inputRadius + 'px';
343 pwInput.style.border = '1px solid ' + o.inputBorder;
344 pwInput.style.background = o.inputBg;
345 pwInput.style.color = o.inputColor;
346 pwInput.style.fontSize = '15px';
347 pwInput.style.boxSizing = 'border-box';
348 pwInput.style.outline = 'none';
349 pwInput.style.transition = 'border-color 0.2s';
350 pwInput.addEventListener('focus', function () { pwInput.style.borderColor = o.inputFocusBorder; });
351 pwInput.addEventListener('blur', function () { pwInput.style.borderColor = o.inputBorder; });
352 pwInput.addEventListener('keydown', function (e) { if (e.key === 'Enter') { pwBtn.click(); } });
353 formEl.appendChild(pwInput);
354
355 var pwBtn = document.createElement('button');
356 pwBtn.className = 'bkbg-cl-btn';
357 pwBtn.textContent = o.passwordSubmitLabel;
358 pwBtn.style.padding = '12px 24px';
359 pwBtn.style.borderRadius = o.inputRadius + 'px';
360 pwBtn.style.background = o.btnBg;
361 pwBtn.style.color = o.btnColor;
362 pwBtn.style.border = 'none';
363 pwBtn.style.cursor = 'pointer';
364 pwBtn.addEventListener('click', function () {
365 if (pwInput.value === o.password) {
366 unlockContent();
367 } else {
368 showError(o.passwordErrorMsg);
369 pwInput.value = '';
370 pwInput.focus();
371 }
372 });
373 formEl.appendChild(pwBtn);
374
375 } else if (o.lockType === 'click') {
376 var revealBtn = document.createElement('button');
377 revealBtn.className = 'bkbg-cl-btn';
378 revealBtn.style.padding = '14px 28px';
379 revealBtn.style.borderRadius = o.inputRadius + 'px';
380 revealBtn.style.background = o.btnBg;
381 revealBtn.style.color = o.btnColor;
382 revealBtn.style.border = 'none';
383 revealBtn.style.cursor = 'pointer';
384 revealBtn.style.display = 'flex';
385 revealBtn.style.alignItems = 'center';
386 revealBtn.style.gap = '8px';
387 revealBtn.style.margin = '0 auto';
388 revealBtn.textContent = (o.clickButtonIcon ? o.clickButtonIcon + ' ' : '') + o.clickButtonLabel;
389 revealBtn.addEventListener('click', unlockContent);
390 formEl.appendChild(revealBtn);
391 }
392
393 gate.appendChild(formEl);
394 typoCssVarsForEl(o.typoHeading, '--bkcl-head-', gate);
395 typoCssVarsForEl(o.typoButton, '--bkcl-btn-', gate);
396 gateWrap.appendChild(gate);
397 wrap.appendChild(gateWrap);
398
399 appEl.parentNode.insertBefore(wrap, appEl);
400 appEl.style.display = 'none';
401 });
402 }
403
404 if (document.readyState !== 'loading') {
405 init();
406 } else {
407 document.addEventListener('DOMContentLoaded', init);
408 }
409 })();
410