Siteβ―Builder
Editing:
play.php
writable 0666
<!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <title>Sliding In-Place Token Editor + AI Buttons</title> <meta name="viewport" content="width=device-width,initial-scale=1"> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@picocss/pico@2/css/pico.min.css"> <style> body { max-width: 860px; margin: 3rem auto; font-family: sans-serif; } h1 { text-align: center; margin-bottom: 2rem; } article.prompt-card { background: #fff; border: 1px solid #ddd; border-radius: 8px; padding: 1rem; margin-bottom: 1.5rem; } .prompt-text { line-height: 1.6; } .token { color: #5c3bff; font-weight: 600; cursor: pointer; position: relative; } .token .tooltip { position: absolute; bottom: 100%; left: 0; background: #fff; color: #000; padding: .2rem .4rem; border: 1px solid #ccc; border-radius: 4px; font-size: .8rem; white-space: nowrap; opacity: 0; transform: translateY(4px); transition: opacity .2s, transform .2s; pointer-events: none; } .token:hover .tooltip { opacity: 1; transform: translateY(0); } .editor-panel { max-height: 0; overflow: hidden; opacity: 0; transition: max-height .3s ease, opacity .2s ease; margin-top: 1rem; } .editor-panel.open { max-height: 600px; opacity: 1; overflow-y: auto; } .editor-panel .body { background: #f9f9f9; border: 1px solid #ccc; border-radius: 6px; padding: .8rem; } .editor-panel .body input[type="text"], .editor-panel .body textarea, .editor-panel .body select { width: 100%; margin-top: .5rem; padding: .4rem; border: 1px solid #999; border-radius: 4px; font-size: 1rem; } .editor-panel .body label { display: block; margin-top: .5rem; font-weight: normal; } .ai-btns { margin-top: 1rem; display: flex; gap: .7rem; } .ai-btns a { display: inline-block; padding: .5em 1em; border-radius: 6px; color: #fff; text-decoration: none; font-weight: 600; } .ai-btns a.chatgpt { background: #6c48ff; } .ai-btns a.perplexity { background: #1ca7ec; } .ai-btns a.copilot { background: #00c853; color: #173E22; } .ai-btns a:hover { filter: brightness(1.1); } </style> </head> <body> <h1>Interactive Prompt Playground</h1> <div id="app"></div> <script type="application/json" id="seed"> [ "Write a bedtime story titled [A-story_title- ~Magical Night Adventure~] for a [D-child_gender- |girl|boy| ~girl~] named [child_name~Melanie~]. The plot must feature [C-themes- |unicorns|spaceships|fairy tales|dragons| ~unicorns, fairy tales~] and be told in a [B-tone- |gentle|funny|adventurous| ~gentle~] tone.\n\nProvide exactly [D-paragraphs-5~3~] paragraphs.\n\n(If you need inspiration: ) [I-reference- |https://en.wikipedia.org/wiki/Bedtime_story|https://www.gutenberg.org/| ~Pick a site~]" ] </script> <script> (() => { const SEP = ' β’ '; const RX = /\[(?:([A-DI]?)-)?([^~|\-\]]+)(?:-([^~\]]+))?(?:~([^~]+)~)?\]/g; const prompts = JSON.parse(document.getElementById('seed').textContent); const app = document.getElementById('app'); prompts.forEach((tpl, pi) => { const meta = [], state = {}; // Tokenize and capture metadata const tokenized = tpl.replace(RX, function(match, cmd, lab, ops, def) { cmd = cmd || ''; ops = ops || ''; def = def || ''; const opts = ops.split('|').map(s => s.trim()).filter(Boolean); // handle default multi-select values let initial = def; if (cmd === 'C' && def) { initial = def.split(',').map(s => s.trim()).join(SEP); } meta.push({ cmd, lab, opts }); state[lab] = initial; return `<span class="token" data-i="${meta.length-1}">` + `[${def}]<span class="tooltip">${lab}</span></span>`; }); // Build prompt card const card = document.createElement('article'); card.className = 'prompt-card'; card.innerHTML = `<p class="prompt-text">${tokenized.replace(/\n/g,'<br>')}</p>` + `<div class="editor-panel"><div class="body"></div></div>` + `<div class="ai-btns">` + `<a class="chatgpt" data-base="https://chatgpt.com/?prompt=">ChatGPT</a>` + `<a class="perplexity" data-base="https://www.perplexity.ai/search?q=">Perplexity</a>` + `<a class="copilot" data-base="https://copilot.microsoft.com/?q=">Copilot</a>` + `</div>`; app.append(card); // Helper to rebuild prompt and update buttons function rebuild() { let result = tpl; result = result.replace(RX, function(_, __, lab) { return state[lab] || ''; }); card.querySelectorAll('.ai-btns a').forEach(a => { a.href = a.dataset.base + encodeURIComponent(result); }); } rebuild(); // Attach token click to open editor card.querySelectorAll('.token').forEach(tok => { tok.addEventListener('click', () => { const mi = +tok.dataset.i; const { cmd, lab, opts } = meta[mi]; const cur = state[lab]; const panel = card.querySelector('.editor-panel'); const body = panel.querySelector('.body'); panel.classList.add('open'); // Reset body body.innerHTML = `<strong>${lab.replace(/[-_]/g,' ')}</strong><br>`; // Create input element let inputEl; if (cmd === 'A') { inputEl = document.createElement('textarea'); inputEl.rows = 3; inputEl.value = cur; inputEl.addEventListener('input', () => { state[lab] = inputEl.value; tok.firstChild.nodeValue = `[${inputEl.value}]`; rebuild(); }); } else if (cmd === 'B') { inputEl = document.createElement('div'); opts.forEach(o => { const lbl = document.createElement('label'); const r = document.createElement('input'); r.type = 'radio'; r.name = `r${pi}${mi}`; r.value = o; if (o === cur) r.checked = true; r.addEventListener('change', () => { state[lab] = o; tok.firstChild.nodeValue = `[${o}]`; rebuild(); panel.classList.remove('open'); }); lbl.append(r, ' ', o); inputEl.append(lbl); }); } else if (cmd === 'C') { inputEl = document.createElement('div'); opts.forEach(o => { const lbl = document.createElement('label'); const c = document.createElement('input'); c.type = 'checkbox'; c.value = o; c.checked = cur.split(SEP).includes(o); c.addEventListener('change', () => { const sel = [...inputEl.querySelectorAll('input:checked')].map(i=>i.value); state[lab] = sel.join(SEP); tok.firstChild.nodeValue = `[${state[lab]}]`; rebuild(); }); lbl.append(c, ' ', o); inputEl.append(lbl); }); } else if (cmd === 'D') { inputEl = document.createElement('select'); let list = opts; if (opts.every(o=>/^\d+$/.test(o))) { const max = Math.max(...opts.map(Number)); list = Array.from({length:max},(_,i)=>''+(i+1)); } list.forEach(o => { const optEl = document.createElement('option'); optEl.textContent = o; if (o === cur) optEl.selected = true; inputEl.append(optEl); }); inputEl.addEventListener('change', () => { state[lab] = inputEl.value; tok.firstChild.nodeValue = `[${inputEl.value}]`; rebuild(); panel.classList.remove('open'); }); } else if (cmd === 'I') { inputEl = document.createElement('select'); const placeholder = document.createElement('option'); placeholder.textContent = cur; placeholder.disabled = true; placeholder.selected = true; inputEl.append(placeholder); opts.forEach(u => { const optEl = document.createElement('option'); optEl.textContent = u; inputEl.append(optEl); }); inputEl.addEventListener('change', () => { state[lab] = inputEl.value; tok.firstChild.nodeValue = `[${inputEl.value}]`; rebuild(); panel.classList.remove('open'); }); } else { inputEl = document.createElement('input'); inputEl.type = 'text'; inputEl.value = cur; inputEl.addEventListener('input', () => { state[lab] = inputEl.value; tok.firstChild.nodeValue = `[${inputEl.value}]`; rebuild(); }); } if (inputEl) body.append(inputEl); // click-away to close const onDocClick = e => { if (!panel.contains(e.target) && !tok.contains(e.target)) { panel.classList.remove('open'); document.removeEventListener('mousedown', onDocClick); } }; document.addEventListener('mousedown', onDocClick); }); }); }); })(); </script> </body> </html>
Save changes
Create folder
writable 0777
Create
Cancel