Site Builder
Editing:
promptinatossssssssssssr.js
writable 0666
/* Promptinator.js – v2025‑07‑15‑pH * unified core + pencil toolbar + hidden‑token + helper banner * now includes placeholder logic from socialPromptinator.js * ------------------------------------------------------------------ */ const __ = (window?.wp?.i18n?.__) || (s => s); // i18n helper class Promptinator { /* static helpers / flags ---------------------------------------- */ static _lastMeta = []; static _lastState = []; static _hasE = false; static _escAttr = s => String(s) .replace(/&/g,'&').replace(/"/g,'"') .replace(/</g,'<').replace(/>/g,'>'); /* ------------------------------------------------ init */ static init({ mount, defaultPrompt }) { const prompt = mount.dataset.prompt || defaultPrompt || mount.textContent.trim(); let template = prompt; /* recognise H‑token as well */ const RX = /\[(?:([A-DEIH]?)-)?([^~|\-\]]*)(?:-([^~\]]*))?(?:~([^~]+)~)?\]/ig; const state = {}, meta = []; const allowEdit = mount.dataset.edit !== "0" && mount.dataset.edit !== "false"; const allowThink = !("think" in mount.dataset) || (mount.dataset.think !== "0" && mount.dataset.think !== "false"); /* -------------- render ------------------------- */ function render() { meta.length = 0; let idx = 0; template.replace(RX, (_, cmd='', lab='', ops='', def='') => { lab = lab.trim(); const opts = ops.split('|').filter(Boolean); if (!(idx in state)) { state[idx] = cmd === 'C' ? (def ? def.split(',').map(v=>v.trim()) : opts.slice(0,1)) : (def || opts[0] || lab); } meta.push({ cmd: cmd || 'A', lab, opts, def }); idx++; return ''; }); idx = 0; const htmlBody = template.replace(RX, (_, cmd='', lab='') => { lab = lab.trim(); const val = state[idx]; let out; if (cmd === 'C') { const list = (Array.isArray(val)?val:[val]).filter(Boolean); out = list.map(v => `<span class="token" data-i="${idx}" data-label="${lab}">[${v}]</span>`).join(', '); } else if (cmd === 'E') { const isEmail = /^\S+@\S+\.\S+$/.test(val); out = `<button class="token e-btn" data-i="${idx}" data-label="${lab}">` + (isEmail ? __( 'Send', 'promptinator' ) : __( 'Submit', 'promptinator' )) + `</button>`; } else if (cmd === 'H') { out = `<span class="token h-dot" data-i="${idx}" data-label="${lab}" title="${__( 'Hidden instruction', 'promptinator' )}">•</span>`; } else { out = `<span class="token" data-i="${idx}" data-label="${lab}">[${val}]</span>`; } idx++; return out; }); Promptinator._hasE = meta.some(m => m.cmd === 'E'); /* ----- helper banner & AI buttons (unchanged) --------------- */ const noPrompt = template.trim().length === 0; const showAI = allowThink && !Promptinator._hasE && !noPrompt; const aiButtons = showAI ? ` <div class="ai-buttons" style="margin-top:1em;display:flex;gap:.6em;"> <a class="ai-btn chatgpt" target="_blank" style="display:inline-flex;align-items:center;gap:.3em;background:#5c3bff;color:#fff;font-weight:600;border-radius:7px;padding:.4em 1.2em;text-decoration:none;"> 🧠 ${__( 'ChatGPT', 'promptinator' )} </a> <a class="ai-btn perplexity" target="_blank" style="display:inline-flex;align-items:center;gap:.3em;background:#22a8e5;color:#fff;font-weight:600;border-radius:7px;padding:.4em 1.2em;text-decoration:none;"> 🔎 ${__( 'Perplexity', 'promptinator' )} </a> <a class="ai-btn copilot" target="_blank" style="display:inline-flex;align-items:center;gap:.3em;background:#10c775;color:#fff;font-weight:600;border-radius:7px;padding:.4em 1.2em;text-decoration:none;"> 🤖 ${__( 'Copilot', 'promptinator' )} </a> </div>` : ''; const helperMsg = noPrompt && allowEdit ? `<div class="promptinator-helper" style="margin-top:1em;font-size:.9em;color:#555;text-align:center;background:#fff9c4;padding:.5em .8em;border-radius:5px;"> 💡 ${__('Click the pencil (✏️) to add a prompt.', 'promptinator')} </div>` : ''; promptText.innerHTML = (noPrompt ? '' : htmlBody.replace(/\n/g,'<br>')) + helperMsg + aiButtons; if (showAI) { let i = 0; const full = template.replace(RX, () => { const v = state[i++]; return Array.isArray(v)?v.join(', '):v; }); promptText.querySelector('.chatgpt') .href = 'https://chat.openai.com/?prompt=' + encodeURIComponent(full); promptText.querySelector('.perplexity').href = 'https://www.perplexity.ai/search?q=' + encodeURIComponent(full); promptText.querySelector('.copilot') .href = 'https://copilot.microsoft.com/?q=' + encodeURIComponent(full); } } /* render */ /* -------------- mount editor ------------------ */ const editor = document.createElement('div'); editor.className = 'Promptinator'; editor.innerHTML = ` <div style="display:flex;align-items:baseline;gap:.5em;"> ${allowEdit ? `<span id="edit-link" title="${__( 'Edit prompt', 'promptinator' )}" style="cursor:pointer;font-size:1em;color:#5c3bff;display:inline-flex;align-items:center;margin-right:.25em;">✏️</span>` : ''} <div class="prompt-text" style="flex:1 1 auto;"></div> </div> ${allowEdit ? `<form id="edit-form" style="display:none;margin-top:.6em;"> <textarea style="width:100%;font-family:monospace;min-height:90px;"></textarea> <div style="text-align:right;margin-top:.7em;"><button type="submit">${__( 'Save & Update', 'promptinator' )}</button></div> </form>` : ''}`; mount.innerHTML = ''; mount.append(editor); const promptText = editor.querySelector('.prompt-text'); if (allowEdit) { const link = editor.querySelector('#edit-link'), form = editor.querySelector('#edit-form'), ta = form.querySelector('textarea'); link.onclick = () => { if (form.style.display === 'block') { template = ta.value.trim(); Object.keys(state).forEach(k=>delete state[k]); form.style.display='none'; render(); } else { form.style.display = 'block'; ta.value = template; ta.focus(); Promptinator.enhanceTextarea?.(ta); } }; form.onsubmit = e => { e.preventDefault(); template = ta.value.trim(); Object.keys(state).forEach(k=>delete state[k]); form.style.display='none'; render(); }; } render(); mount.addEventListener('click', e => { if (!e.target.classList.contains('token')) return; const i = +e.target.dataset.i; const info = meta[i]; const value = state[i]; if (info.cmd === 'E') { Promptinator._lastMeta = meta.slice(); Promptinator._lastState = Object.assign([], state); } Promptinator._popup( info, Array.isArray(value)?value.join(', '):value, v => { state[i] = info.cmd==='C' ? v.split(',').map(s=>s.trim()).filter(Boolean) : v; render(); } ); }); } /* init */ /* ------------------------------------------------ popup */ static _popup(meta, cur, done) { let dlg = document.getElementById('promptinator-dlg'); if (!dlg) { dlg = document.createElement('dialog'); dlg.id='promptinator-dlg'; document.body.append(dlg); dlg.addEventListener('click',e=>{ if(e.target===dlg) dlg.close(); }); dlg.addEventListener('cancel',e=>{ e.preventDefault(); dlg.close(); }); } const prettify = s => s.replace(/[-_]/g,' ').replace(/\b\w/g,c=>c.toUpperCase()); const nice = meta.lab && meta.lab.trim() ? prettify(meta.lab) : (cur || {A:'Text Input',B:'Choice',C:'Options',D:'Dropdown',I:'URL Picker',E:'Send',H:'Hidden note'}[meta.cmd] || 'Input'); /* placeholder logic copied from socialPromptinator ------------- */ const showPH = Promptinator._hasE && cur === meta.def; const phAttr = showPH ? ` placeholder="${Promptinator._escAttr(cur)}"` : ''; const valAttr = showPH ? '' : Promptinator._escAttr(cur); let inner=''; switch(meta.cmd){ case 'A': case 'H': /* H uses textarea editor too */ inner=`<label>${nice}<textarea style="width:100%;font-size:1rem;" rows="4"${phAttr}>${valAttr}</textarea></label> <div style="text-align:right;margin-top:.7em;"><button type="button">${__( 'Done', 'promptinator' )}</button></div>`; break; case 'B': inner=`<fieldset><legend>${nice}</legend>`+ meta.opts.map(o=>`<label><input type="radio" name="r" value="${o}" ${o===cur?'checked':''}> ${o}</label>`).join('')+ `</fieldset>`; break; case 'C': inner=`<fieldset><legend>${nice}</legend>`+ meta.opts.map(o=>`<label><input type="checkbox" value="${o}" ${cur.split(', ').includes(o)?'checked':''}> ${o}</label>`).join('')+ `</fieldset><div style="text-align:right;margin-top:.7em;"><button type="button">${__( 'Done', 'promptinator' )}</button></div>`; break; case 'D':{ let opts=meta.opts; if(opts.length===1&&/^\d+$/.test(opts[0])) opts=Array.from({length:+opts[0]},(_,i)=>String(i+1)); inner=`<label>${nice}<select>`+opts.map(o=>`<option${o===cur?' selected':''}>${o}</option>`).join('')+`</select></label>`; break; } case 'I': inner=`<label>${nice}<select>`+ (showPH?`<option disabled selected>${Promptinator._escAttr(cur)}</option>`:'')+ meta.opts.map(u=>`<option${u===cur?' selected':''}>${u}</option>`).join('')+ `</select></label> <iframe hidden style="width:100%;height:300px;border:1px solid #ccc;margin-top:.6em;"></iframe> <div style="text-align:right;margin-top:.7em;"><button type="button">${__( 'Use site', 'promptinator' )}</button></div>`; break; case 'E':{ const isEmail=/^\S+@\S+\.\S+$/.test(cur); inner=`<div style="padding:1em 0;text-align:center;font-size:1.1rem;font-weight:600;">${nice}</div> <div style="text-align:right;margin-top:.7em;"><button type="button">${isEmail?__( 'Send', 'promptinator' ):__( 'Submit', 'promptinator' )}</button></div>`; break; } default: inner=`<label>${nice}<input type="text" style="width:100%;font-size:1rem;"${phAttr} value="${valAttr}"></label> <div style="text-align:right;margin-top:.7em;"><button type="button">${__( 'Done', 'promptinator' )}</button></div>`; } dlg.innerHTML=`<div class="popup-body">${inner}</div>`; dlg.showModal(); const pb=dlg.querySelector('.popup-body'); /* ---------- handlers per cmd ---------- */ if(meta.cmd==='E'){ const btn=pb.querySelector('button'); const isEmail=/^\S+@\S+\.\S+$/.test(cur); if(isEmail){ const body=Promptinator._lastMeta.map((m,i)=>`${prettify(m.lab)}: ${Promptinator._lastState[i]}`).join('\n'); btn.onclick=()=>{ window.location.href=`mailto:${cur}?subject=${encodeURIComponent(nice)}&body=${encodeURIComponent(body)}`; dlg.close(); }; }else{ const form=document.createElement('form'); form.method='post'; form.action=cur; const t=document.createElement('input'); t.type='hidden'; t.name='_formTitle'; t.value=nice; form.append(t); Promptinator._lastMeta.forEach((m,i)=>{ const inp=document.createElement('input'); inp.type='hidden'; inp.name=prettify(m.lab).replace(/\s+/g,'-').toLowerCase(); inp.value=Promptinator._lastState[i]; form.append(inp); }); pb.append(form); btn.onclick=()=>{ form.submit(); dlg.close(); }; } return; } const commit=v=>{ done(v); dlg.close(); }; if(meta.cmd==='A'||meta.cmd==='H'){ const ta=pb.querySelector('textarea'); ta.focus(); pb.querySelector('button').onclick=()=>commit(ta.value); return; } if(meta.cmd==='B'){ pb.onclick=e=>{ if(e.target.name==='r') commit(e.target.value); }; return; } if(meta.cmd==='C'){ pb.querySelector('button').onclick=()=>commit([...pb.querySelectorAll('input:checked')].map(i=>i.value).join(', ')||cur); return; } if(meta.cmd==='D'){ pb.querySelector('select').onchange=e=>commit(e.target.value); return; } 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); return; } /* default input */ const inp=pb.querySelector('input'); inp.focus(); pb.querySelector('button').onclick=()=>commit(inp.value); inp.onkeydown=e=>{ if(e.key==='Enter') commit(inp.value); }; } /* popup */ } /* ------------------------------------------------------------------ */ /* Toolbar code (unchanged from previous build) */ /* ------------------------------------------------------------------ */ const HELP_URL = 'https://promptinator.ai/shortcode-help.php'; const SNIPPETS = { plain_input:'[-labelfield-~Input~]',textarea_a:'[A-labelfield-~Textarea~]', radio_b:'[B-labelfield-|Choice 1|Choice 2|~Choice 2~]',checkbox_c:'[C-labelfield-|Opt A|Opt B|~Opt A~]', dropdown_num_d:'[D-labelfield-10~3~]',dropdown_txt_d:'[D-labelfield-|Opt A|Opt B|Opt C|~Opt B~]', url_picker_i:'[I-labelfield-|https://site1.com|site2.com|~Pick a site~]', email_submit_e:'[E-labelfield-~you@site.com~]',form_post_e:'[E-labelfield-~https://example.com/endpoint~]',h_hidden:'[H-hidden-~Internal GPT instructions here~]' }; const MENU=[ ['plain_input','Plain input'],['textarea_a','Textarea (A)'],['radio_b','Radio buttons (B)'], ['checkbox_c','Checkbox group (C)'],['dropdown_num_d','Dropdown numeric (D)'],['dropdown_txt_d','Dropdown text (D)'], ['url_picker_i','URL picker + preview (I)'],['email_submit_e','Email submit (E)'],['form_post_e','Form‑POST submit (E)'],['h_hidden','Hidden instructions (H)'] ]; function enhanceTextarea(ta){ /* ------------------------------------------------------------ * One‑time toolbar wiring * ------------------------------------------------------------ */ if (!ta || ta.dataset.scMenu) return; ta.dataset.scMenu = 'yes'; /* --- initialise running counter (per textarea) -------------- */ // If the textarea already contains tokens we may be editing an // existing prompt – start the counter *after* the highest label // number that already exists to avoid duplicates. const m = ta.value.match(/-label(\d+)(?=[-~|])/g); ta.dataset.labelCount = m ? String( Math.max( ...m.map(s => +s.replace(/\D/g, '')) ) + 1 ) : '0'; /* --- toolbar ------------------------------------------------ */ const sel = document.createElement('select'); sel.className = 'promptinator-select'; sel.innerHTML = '<option disabled selected>Insert shortcode…</option>' + MENU.map(([k, t]) => `<option value="${k}">${t}</option>`).join(''); sel.onchange = () => { const raw = SNIPPETS[sel.value]; if (raw) { /* sequentially rename “labelfield” → “label<n>” */ const n = +ta.dataset.labelCount; const snip = raw.replace(/-labelfield(?=[-~|])/i, `-label${n}`); ta.dataset.labelCount = String(n + 1); insertAtCaret(ta, snip); } sel.selectedIndex = 0; }; /* --- help link (unchanged) ---------------------------------- */ const help = document.createElement('a'); help.className = 'promptinator-help'; help.textContent = 'Help'; help.href = HELP_URL; help.title = 'Open shortcode helper'; help.onclick = e => { e.preventDefault(); window.open( HELP_URL, 'promptinatorHelp', 'popup=yes,width=520,height=720,scrollbars=yes,resizable=yes' ); }; /* --- mount toolbar ------------------------------------------ */ const bar = document.createElement('div'); bar.className = 'promptinator-bar'; bar.append(sel, help); ta.parentNode.insertBefore(bar, ta); } function insertAtCaret(el,snippet){ el.focus(); const{selectionStart:s,selectionEnd:e,value:t}=el; el.value=t.slice(0,s)+snippet+t.slice(e); const p=s+snippet.length; el.selectionStart=el.selectionEnd=p; el.dispatchEvent(new Event('input',{bubbles:true})); } /* one‑time CSS */ (function(){ const css=` .promptinator-bar{display:flex;align-items:center;gap:.55em;margin-bottom:.35em;} .promptinator-select{flex:1 1 auto;padding:.3em .55em;} .promptinator-help{flex:0 0 auto;font-size:.9rem;color:#176edc;text-decoration:underline;cursor:pointer;} .promptinator-bar+textarea{width:100%;box-sizing:border-box;} .token.h-dot{cursor:pointer;font-weight:bold;font-size:1.2em;} `; const st=document.createElement('style'); st.appendChild(document.createTextNode(css)); document.head.appendChild(st); })(); document.addEventListener('click',e=>{ const pencil=e.target.closest('#edit-link'); if(!pencil)return; const form=(pencil.closest('.Promptinator')||document.body).querySelector('#edit-form'); if(!form)return; requestAnimationFrame(()=>{ if(getComputedStyle(form).display==='none')return; const ta=form.querySelector('textarea'); if(ta)enhanceTextarea(ta);}); }); /* expose */ Promptinator.enhanceTextarea = enhanceTextarea; export { enhanceTextarea }; export default Promptinator;
Save changes
Create folder
writable 0777
Create
Cancel