Siteβ―Builder
Editing:
promptifyok.js
writable 0666
// ββ promptify.js ββ your lightweight token parser & popup ββ export default class Promptify { static init({template, mount}) { const RX = /\[(?:([A-DI]?)-)?([^~|\-\]]+)(?:-([^~\]]+))?(?:~([^~]+)~)?\]/ig; const state = {}, meta = []; // 1) render tokens const html = template.replace(RX, (_,cmd='', lab, ops='', def='') => { meta.push({cmd, lab, ops: ops.split('|').filter(Boolean), def}); state[lab] = def || lab; return `<span class="token" data-i="${meta.length-1}">[${state[lab]}]</span>`; }); mount.innerHTML = `<p>${html.replace(/\n/g,'<br>')}</p>`; // 2) click on tokens β popup mount.addEventListener('click', e => { if (!e.target.matches('.token')) return; const idx = +e.target.dataset.i; const info = meta[idx]; Promptify._popup(info, state[info.lab], v => { state[info.lab] = v; e.target.textContent = '['+v+']'; }); }); } static _popup(meta, cur, done) { // singleton dialog let dlg = document.getElementById('promptify-dlg'); if (!dlg) { dlg = document.createElement('dialog'); dlg.id = 'promptify-dlg'; document.body.append(dlg); dlg.addEventListener('click', e => e.target===dlg && dlg.close()); dlg.addEventListener('cancel', e => { e.preventDefault(); dlg.close(); }); } // prettify label const pretty = meta.lab .replace(/[-_]/g,' ') .replace(/\b\w/g, c=>c.toUpperCase()); // build inner let inner = ''; switch(meta.cmd) { case 'A': inner = `<label>${pretty}<textarea rows="4">${cur}</textarea></label>`; break; case 'B': inner = `<fieldset><legend>${pretty}</legend>` + meta.ops.map(o=>` <label><input type="radio" name="r" value="${o}" ${o===cur?'checked':''}> ${o}</label> `).join('') + `</fieldset>`; break; case 'C': inner = `<fieldset><legend>${pretty}</legend>` + meta.ops.map(o=>` <label><input type="checkbox" value="${o}" ${cur.split(', ').includes(o)?'checked':''}> ${o}</label> `).join('') + `</fieldset><button>Done</button>`; break; case 'D': let opts = meta.ops; if (opts.length===1 && /^\d+$/.test(opts[0])) opts = Array.from({length:+opts[0]},(_,i)=>''+(i+1)); inner = `<label>${pretty}<select>` + opts.map(o=>`<option${o==cur?' selected':''}>${o}</option>`).join('') + `</select></label>`; break; case 'I': inner = `<label>${pretty}<select><option disabled selected>${cur}</option>`+ meta.ops.map(u=>`<option>${u}</option>`).join('')+ `</select></label><iframe hidden></iframe><button>Use site</button>`; break; default: inner = `<label>${pretty}<input value="${cur}"></label>`; } dlg.innerHTML = `<div class="popup-body">${inner}</div>`; document.body.append(dlg); dlg.showModal(); // commit helper const commit = v => { done(v); dlg.close(); }; const pb = dlg.querySelector('.popup-body'); // wire each type if (meta.cmd==='A') { const ta = pb.querySelector('textarea'); ta.focus(); ta.onkeydown = e => { if (e.key==='Enter' && !e.shiftKey) { e.preventDefault(); commit(ta.value); } }; ta.onblur = () => dlg.close(); } if (meta.cmd==='B') { pb.onclick = e => e.target.name==='r' && commit(e.target.value); } if (meta.cmd==='C') { pb.querySelector('button').onclick = () => { const vals = [...pb.querySelectorAll('input:checked')] .map(i => i.value); commit(vals.join(', ') || cur); }; } if (meta.cmd==='D') { pb.querySelector('select').onchange = e => commit(e.target.value); } if (meta.cmd==='I') { const sel = pb.querySelector('select'), fr = pb.querySelector('iframe'); sel.onchange = () => { fr.hidden = false; fr.src = sel.value; }; pb.querySelector('button').onclick = () => commit(sel.value || cur); } if (!/[A-DI]/.test(meta.cmd)) { const inp = pb.querySelector('input'); inp.focus(); inp.onkeydown = e => e.key==='Enter' && commit(inp.value); inp.onblur = () => dlg.close(); } } }
Save changes
Create folder
writable 0777
Create
Cancel