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

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

314 lines 15.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:'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 LOREM_WORDS = [
26 'lorem','ipsum','dolor','sit','amet','consectetur','adipiscing','elit',
27 'sed','do','eiusmod','tempor','incididunt','ut','labore','et','dolore',
28 'magna','aliqua','enim','ad','minim','veniam','quis','nostrud','exercitation',
29 'ullamco','laboris','nisi','aliquip','ex','ea','commodo','consequat',
30 'duis','aute','irure','in','reprehenderit','voluptate','velit','esse',
31 'cillum','eu','fugiat','nulla','pariatur','excepteur','sint','occaecat',
32 'cupidatat','non','proident','sunt','culpa','qui','officia','deserunt',
33 'mollit','anim','id','est','laborum','perspiciatis','unde','omnis','iste',
34 'natus','error','accusantium','doloremque','laudantium','totam','rem',
35 'aperiam','eaque','ipsa','quae','ab','illo','inventore','veritatis',
36 'architecto','beatae','vitae','dicta','explicabo','nemo','ipsam','quia',
37 'voluptas','aspernatur','odit','fugit','accusamus','iusto','odio','dignissimos',
38 'blanditiis','praesentium','voluptatum','deleniti','atque','corrupti',
39 'quos','dolores','quas','molestias','excepturi','occaecati','cupiditate',
40 'provident','similique','mollitia','animi','dolorem','porro','quisquam','eum',
41 'nihil','quo','maxime','placeat','facere','possimus','omnis','voluptatem',
42 'suscipit','eligendi','optio','cumque','impedit','quo','minus','illum','vero'
43 ];
44
45 var LOREM_CLASSIC_START = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.';
46
47 function rand(min, max) {
48 return Math.floor(Math.random() * (max - min + 1)) + min;
49 }
50
51 function randomWord() {
52 return LOREM_WORDS[Math.floor(Math.random() * LOREM_WORDS.length)];
53 }
54
55 function generateSentence(wordsMin, wordsMax) {
56 var n = rand(wordsMin || 8, wordsMax || 18);
57 var words = [];
58 for (var i = 0; i < n; i++) words.push(randomWord());
59 var sentence = words.join(' ');
60 sentence = sentence.charAt(0).toUpperCase() + sentence.slice(1);
61 var endings = ['.', '.', '.', '!', '?'];
62 return sentence + endings[Math.floor(Math.random() * endings.length)];
63 }
64
65 function generateParagraph(sentenceCountMin, sentenceCountMax) {
66 var n = rand(sentenceCountMin || 4, sentenceCountMax || 7);
67 var sents = [];
68 for (var i = 0; i < n; i++) sents.push(generateSentence());
69 return sents.join(' ');
70 }
71
72 function buildOutput(opts, mode, count, useLorem, useHtml) {
73 var html = useHtml;
74 if (mode === 'paragraphs') {
75 var paras = [];
76 for (var i = 0; i < count; i++) {
77 var p = (i === 0 && useLorem) ? LOREM_CLASSIC_START + ' ' + generateParagraph(3, 6) : generateParagraph();
78 paras.push(html ? '<p>' + p + '</p>' : p);
79 }
80 return html ? paras.join('\n') : paras.join('\n\n');
81 }
82 if (mode === 'sentences') {
83 var sents = [];
84 for (var i = 0; i < count; i++) {
85 var s = (i === 0 && useLorem) ? LOREM_CLASSIC_START : generateSentence();
86 sents.push(s);
87 }
88 return sents.join(html ? '\n' : '\n');
89 }
90 if (mode === 'words') {
91 var first = useLorem ? 'Lorem ipsum dolor sit amet consectetur adipiscing elit'.split(' ') : [];
92 var words = first.slice(0, Math.min(first.length, count));
93 while (words.length < count) words.push(randomWord());
94 return words.slice(0, count).join(' ');
95 }
96 if (mode === 'list') {
97 var items = [];
98 var startWords = useLorem ? ['Lorem','Ipsum','Dolor','Sit','Amet','Consectetur','Adipiscing','Elit'] : [];
99 for (var i = 0; i < count; i++) {
100 var itemWords = [];
101 var len = rand(3, 7);
102 if (i < startWords.length && useLorem) itemWords.push(startWords[i]);
103 while (itemWords.length < len) itemWords.push(randomWord());
104 var item = itemWords.join(' ');
105 item = item.charAt(0).toUpperCase() + item.slice(1);
106 items.push(item);
107 }
108 if (html) {
109 return '<ul>\n' + items.map(function(it){ return ' <li>' + it + '</li>'; }).join('\n') + '\n</ul>';
110 }
111 return items.map(function(it, idx){ return (idx + 1) + '. ' + it; }).join('\n');
112 }
113 return '';
114 }
115
116 function plainText(mode, count, useLorem) {
117 return buildOutput(null, mode, count, useLorem, false);
118 }
119
120 function htmlText(mode, count, useLorem) {
121 return buildOutput(null, mode, count, useLorem, true);
122 }
123
124 function countWords(text) {
125 var plain = text.replace(/<[^>]+>/g, ' ');
126 var cleaned = plain.trim().replace(/\s+/g, ' ');
127 return cleaned ? cleaned.split(' ').length : 0;
128 }
129
130 function countChars(text) {
131 return text.replace(/<[^>]+>/g, '').length;
132 }
133
134 document.querySelectorAll('.bkbg-lig-app').forEach(function (root) {
135 var opts = {};
136 try { opts = JSON.parse(root.getAttribute('data-opts') || '{}'); } catch(e) {}
137
138 /* Apply typography CSS vars */
139 typoCssVarsForEl(root, opts.titleTypo, '--bkbg-lig-tt-');
140 typoCssVarsForEl(root, opts.subtitleTypo, '--bkbg-lig-st-');
141 typoCssVarsForEl(root, opts.outputTypo, '--bkbg-lig-out-');
142
143 var mode = opts.defaultMode || 'paragraphs';
144 var count = parseInt(opts.defaultCount) || 3;
145 var showHtmlToggle = opts.showHtmlToggle !== false;
146 var showStats = opts.showStats !== false;
147 var startWithLorem = opts.startWithLorem !== false;
148 var outputHeight = parseInt(opts.outputHeight) || 260;
149
150 var accentColor = opts.accentColor || '#6c3fb5';
151 var sectionBg = opts.sectionBg || '#f5f3ff';
152 var cardBg = opts.cardBg || '#ffffff';
153 var outputBg = opts.outputBg || '#fafafa';
154 var outputBorder = opts.outputBorder || '#e5e7eb';
155 var outputTextColor= opts.outputTextColor|| '#374151';
156 var titleColor = opts.titleColor || '#111827';
157 var subtitleColor = opts.subtitleColor || '#6b7280';
158 var labelColor = opts.labelColor || '#374151';
159 var tabBg = opts.tabBg || '#f3f4f6';
160
161 var useHtml = false;
162 var generatedPlain = '';
163 var generatedHtml = '';
164
165 // Build HTML
166 root.innerHTML =
167 '<div class="bkbg-lig-card" style="background:' + cardBg + ';border-radius:16px;">' +
168 '<h2 class="bkbg-lig-title" style="color:' + titleColor + ';">' + (opts.title || 'Lorem Ipsum Generator') + '</h2>' +
169 '<p class="bkbg-lig-subtitle" style="color:' + subtitleColor + ';">' + (opts.subtitle || 'Generate placeholder text for your designs and documents') + '</p>' +
170 '<div class="bkbg-lig-tabs" style="background:' + tabBg + ';" id="lig-tabs"></div>' +
171 '<div class="bkbg-lig-controls">' +
172 '<div class="bkbg-lig-count-wrap" style="background:' + sectionBg + ';color:' + labelColor + ';">' +
173 '<span style="font-size:13px;font-weight:600;margin-right:4px;">Count:</span>' +
174 '<button class="bkbg-lig-count-btn" id="lig-dec">−</button>' +
175 '<span class="bkbg-lig-count-val" id="lig-count-val">' + count + '</span>' +
176 '<button class="bkbg-lig-count-btn" id="lig-inc">+</button>' +
177 '</div>' +
178 '<button class="bkbg-lig-btn" id="lig-generate" style="background:' + accentColor + ';color:#fff;">Generate</button>' +
179 '<button class="bkbg-lig-btn bkbg-lig-btn-sec" id="lig-copy">📋 Copy</button>' +
180 '<span class="bkbg-lig-copied" id="lig-copied">Copied!</span>' +
181 '</div>' +
182 (showHtmlToggle ?
183 '<div class="bkbg-lig-opts">' +
184 '<label class="bkbg-lig-check-lbl" style="color:' + labelColor + ';">' +
185 '<input type="checkbox" id="lig-lorem-chk"' + (startWithLorem ? ' checked' : '') + '> Start with "Lorem ipsum…"' +
186 '</label>' +
187 '<label class="bkbg-lig-check-lbl" style="color:' + labelColor + ';">' +
188 '<input type="checkbox" id="lig-html-chk"> HTML output' +
189 '</label>' +
190 '</div>'
191 : '') +
192 '<div class="bkbg-lig-output" id="lig-output" style="background:' + outputBg + ';color:' + outputTextColor + ';border-color:' + outputBorder + ';min-height:' + outputHeight + 'px;" tabindex="0"></div>' +
193 (showStats ? '<div class="bkbg-lig-stats" id="lig-stats"></div>' : '') +
194 '</div>';
195
196 var MODES = [
197 { key: 'paragraphs', label: 'Paragraphs' },
198 { key: 'sentences', label: 'Sentences' },
199 { key: 'words', label: 'Words' },
200 { key: 'list', label: 'List' }
201 ];
202
203 var tabsEl = root.querySelector('#lig-tabs');
204 var countVal = root.querySelector('#lig-count-val');
205 var decBtn = root.querySelector('#lig-dec');
206 var incBtn = root.querySelector('#lig-inc');
207 var genBtn = root.querySelector('#lig-generate');
208 var copyBtn = root.querySelector('#lig-copy');
209 var copiedEl = root.querySelector('#lig-copied');
210 var outputEl = root.querySelector('#lig-output');
211 var statsEl = root.querySelector('#lig-stats');
212 var loremChk = root.querySelector('#lig-lorem-chk');
213 var htmlChk = root.querySelector('#lig-html-chk');
214
215 function renderTabs() {
216 tabsEl.innerHTML = '';
217 MODES.forEach(function(m) {
218 var btn = document.createElement('button');
219 btn.className = 'bkbg-lig-tab';
220 btn.textContent = m.label;
221 var active = m.key === mode;
222 btn.style.background = active ? accentColor : 'transparent';
223 btn.style.color = active ? '#fff' : labelColor;
224 btn.setAttribute('data-mode', m.key);
225 tabsEl.appendChild(btn);
226 });
227 }
228
229 function generate() {
230 var useLorem = loremChk ? loremChk.checked : startWithLorem;
231 generatedPlain = plainText(mode, count, useLorem);
232 generatedHtml = htmlText(mode, count, useLorem);
233 useHtml = htmlChk ? htmlChk.checked : false;
234 renderOutput();
235 }
236
237 function renderOutput() {
238 if (useHtml) {
239 outputEl.innerHTML = generatedHtml;
240 } else {
241 // Use innerHTML with <br> for newlines so it looks right
242 var escaped = generatedPlain.replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;');
243 outputEl.innerHTML = escaped.replace(/\n\n/g,'</p><p>').replace(/\n/g,'<br>');
244 var d = document.createElement('div');
245 d.innerHTML = '<p>' + escaped.replace(/\n\n/g,'</p><p>').replace(/\n/g,'<br>') + '</p>';
246 outputEl.innerHTML = '<p>' + escaped.replace(/\n\n/g,'</p><p>').replace(/\n/g,'<br>') + '</p>';
247 }
248 if (statsEl) {
249 var raw = useHtml ? generatedHtml : generatedPlain;
250 var wc = countWords(raw);
251 var cc = countChars(raw);
252 statsEl.innerHTML =
253 '<span>Words: <strong>' + wc + '</strong></span>' +
254 '<span>Characters: <strong>' + cc + '</strong></span>';
255 }
256 }
257
258 tabsEl.addEventListener('click', function(e) {
259 var btn = e.target.closest('[data-mode]');
260 if (!btn) return;
261 mode = btn.getAttribute('data-mode');
262 renderTabs();
263 generate();
264 });
265
266 decBtn.addEventListener('click', function() {
267 if (count > 1) { count--; countVal.textContent = count; }
268 });
269 incBtn.addEventListener('click', function() {
270 if (count < 50) { count++; countVal.textContent = count; }
271 });
272 genBtn.addEventListener('click', generate);
273
274 if (loremChk) loremChk.addEventListener('change', generate);
275 if (htmlChk) htmlChk.addEventListener('change', function() { useHtml = htmlChk.checked; renderOutput(); });
276
277 copyBtn.addEventListener('click', function() {
278 var text = useHtml ? generatedHtml : generatedPlain;
279 if (navigator.clipboard) {
280 navigator.clipboard.writeText(text).then(showCopied).catch(fallbackCopy.bind(null, text));
281 } else {
282 fallbackCopy(text);
283 }
284 });
285
286 function fallbackCopy(text) {
287 var ta = document.createElement('textarea');
288 ta.value = text;
289 ta.style.position = 'fixed'; ta.style.top = '-9999px';
290 document.body.appendChild(ta);
291 ta.select();
292 try { document.execCommand('copy'); showCopied(); } catch(e) {}
293 document.body.removeChild(ta);
294 }
295
296 function showCopied() {
297 if (!copiedEl) return;
298 copiedEl.style.display = 'inline-block';
299 setTimeout(function() { copiedEl.style.display = 'none'; }, 2000);
300 }
301
302 root.addEventListener('keydown', function(e) {
303 if ((e.ctrlKey || e.metaKey) && e.key === 'Enter') {
304 e.preventDefault();
305 generate();
306 }
307 });
308
309 renderTabs();
310 generate();
311 });
312
313 })();
314