@pipeup/inline 0.9.0 → 0.9.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +25 -5
- package/dist/inline.esm.js +33 -18
- package/dist/inline.min.js +33 -18
- package/dist/pipeup+inline.min.js +34 -19
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -35,7 +35,8 @@ Nothing: the inline add-on uses no network. Answers are comments, kept and sent
|
|
|
35
35
|
|
|
36
36
|
Mark the block with a name (`data-pipeup-id`, which stays the same when you change the question's words), the
|
|
37
37
|
question, and a kind. What you put inside is the **fallback**: it shows to anyone without the add-on, so write the
|
|
38
|
-
question there too, with a way to comment.
|
|
38
|
+
question there too, with a way to comment. With the add-on, the ask is drawn in place of that fallback, so keep
|
|
39
|
+
anything reviewers should still read (a requirement, a design) outside the ask, next to it.
|
|
39
40
|
|
|
40
41
|
```html
|
|
41
42
|
<!-- choice: two to six options, separated by |; data-pipeup-ask-other adds Other, which asks for words -->
|
|
@@ -50,10 +51,12 @@ question there too, with a way to comment.
|
|
|
50
51
|
<p>Is “Go through every comment” one journey or two? Comment on this with ⇧⌥C.</p>
|
|
51
52
|
</div>
|
|
52
53
|
|
|
53
|
-
<!-- agree: Agree (words optional, to confirm or steer) or Needs change (asks what)
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
54
|
+
<!-- agree: Agree (words optional, to confirm or steer) or Needs change (asks what).
|
|
55
|
+
Keep the requirement outside the ask: the add-on hides everything inside it. -->
|
|
56
|
+
<p>FR-012: Reviewers can answer an ask without comment mode.</p>
|
|
57
|
+
<div data-pipeup-id="FR-012-agree" data-pipeup-ask="Agree with FR-012?" data-pipeup-ask-kind="agree">
|
|
58
|
+
<p>Agree with FR-012? Comment on this with ⇧⌥C.</p>
|
|
59
|
+
</div>
|
|
57
60
|
|
|
58
61
|
<!-- open (the default): the reviewer answers in words -->
|
|
59
62
|
<div data-pipeup-id="q-name" data-pipeup-ask="What should we call this feature?">
|
|
@@ -75,6 +78,23 @@ question there too, with a way to comment.
|
|
|
75
78
|
- A comment someone makes in comment mode on an ask's block is an ordinary comment, shown with the ask's threads but
|
|
76
79
|
not counted.
|
|
77
80
|
|
|
81
|
+
## Matching the page
|
|
82
|
+
|
|
83
|
+
Asks are compact: a question and its buttons share one line where they fit, words go in a one-line field that grows
|
|
84
|
+
as the reviewer writes, and an answered ask is one line ("You said Yes · Change · Remove"). The question takes the
|
|
85
|
+
page's font. To match the page's look, set these in the page's CSS, on `:root` for every ask or on one ask's element:
|
|
86
|
+
|
|
87
|
+
```css
|
|
88
|
+
:root {
|
|
89
|
+
--pipeup-ask-accent: #1f7a4d; /* the mark, the chosen button, Send, links, and the tint behind the ask */
|
|
90
|
+
--pipeup-ask-font: "Inter", sans-serif; /* the question and the controls */
|
|
91
|
+
--pipeup-ask-radius: 2px; /* corners of the ask, its buttons and its field */
|
|
92
|
+
}
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
Pipeup's mark before the question and a light tint of the accent always stay, so reviewers can tell an ask is
|
|
96
|
+
something to answer; the controls and how they work by keyboard, touch and screen reader stay the same.
|
|
97
|
+
|
|
78
98
|
An ask without a `data-pipeup-id`, or a choice with fewer than two or more than six options, is left as you wrote it,
|
|
79
99
|
with one line in the console naming it.
|
|
80
100
|
|
package/dist/inline.esm.js
CHANGED
|
@@ -1,25 +1,40 @@
|
|
|
1
|
-
var
|
|
2
|
-
|
|
1
|
+
var O=(e,n)=>n?n.getAttribute(e):globalThis.Pipeup?.setting?.(e)??globalThis.document?.documentElement.getAttribute(e)??null;var De=2n**256n-2n**32n-977n;var L="Agree",D="Needs change",E="Other",R="Asked: ";function X(e){let n=e.getAttribute("data-pipeup-id")??"",t=(e.getAttribute("data-pipeup-ask")??"").replace(/\s+/g," ").trim(),d=`<${e.localName}${n?` data-pipeup-id="${n}"`:""}>`;if(!n)return`the ask ${d} needs a data-pipeup-id, its name`;if(!t)return`the ask ${d} needs its question in data-pipeup-ask`;let o=e.getAttribute("data-pipeup-ask-kind")??"open",m=o==="agree"||o==="choice"?o:"open",u=[];return m==="agree"&&(u=[L,D]),m==="choice"&&(u=[...new Set((e.getAttribute("data-pipeup-ask-options")??"").split("|").map(h=>h.trim()).filter(Boolean))],u.length<2||u.length>6)?`the ask ${d} needs two to six options in data-pipeup-ask-options, separated by |`:{id:n,question:t,kind:m,options:u,other:m==="choice"&&e.hasAttribute("data-pipeup-ask-other"),needed:e.hasAttribute("data-pipeup-ask-needed")}}function W(e,n){let t=n.words.trim();return e.kind==="open"?t:e.kind==="choice"&&n.choice!==E?n.choice:t?`${n.choice}: ${t}`:n.choice}function fe(e,n){let t=n.trim();if(!t)return null;if(e.kind==="open")return{choice:"",words:t};let d=[...e.options,...e.other?[E]:[]];for(let o of d){if(t===o&&o!==D&&o!==E)return{choice:o,words:""};if((e.kind==="agree"||o===E)&&t.startsWith(`${o}:`)){let m=t.slice(o.length+1).trim();if(m||o===L)return{choice:o,words:m}}}return null}var Z="AI assistant",me=(e,n)=>n.includes(e.author)||e.name===Z||e.name.startsWith(`${Z} `);function he(e,n,t=[]){return n.anchor.id!==e.id||!n.anchor.snapshot.startsWith(R)||n.root.deleted||me(n.root,t)?null:fe(e,n.root.text)}function Q(e,n){let t=n.anchor.snapshot.slice(R.length);return t&&t!==e.question.slice(0,t.length)?t:null}function C(e,n,t,d=[]){let o=n.filter(h=>h.anchor.id===e.id).sort((h,A)=>h.root.at-A.root.at),m=new Map;for(let h of o){let A=he(e,h,d);A&&m.set(h.root.author,{thread:h,answer:A})}let u=new Map;for(let h of[...e.options,...e.other?[E]:[]])u.set(h,0);for(let{answer:h}of m.values())u.has(h.choice)&&u.set(h.choice,u.get(h.choice)+1);return{mine:m.get(t)?.thread??null,answers:[...m.values()],counts:u,threads:o}}function ee(e){let n=e.root,t=d=>{!d.deleted&&d.at>=n.at&&(n=d),d.replies.forEach(t)};return e.root.replies.forEach(t),n}var te=`*{box-sizing:border-box}
|
|
2
|
+
[hidden]{display:none!important}
|
|
3
|
+
:host{--ac:var(--pipeup-ask-accent,var(--pu-accent,#534AB7));--cf:var(--pipeup-ask-font,var(--pu-font,system-ui,sans-serif))}
|
|
4
|
+
.box{display:flex;flex-wrap:wrap;align-items:center;gap:6px 12px;margin:10px 0;padding:8px 12px;border-radius:var(--pipeup-ask-radius,8px);background:color-mix(in srgb,var(--ac) 7%,var(--pu-surface,#fff));font:13.5px/1.4 var(--cf);animation:in .26s var(--pu-ease)}
|
|
3
5
|
.inl{margin:6px 0 0}
|
|
4
|
-
.q{margin:0
|
|
5
|
-
.
|
|
6
|
-
|
|
6
|
+
.q{display:flex;align-items:center;gap:8px;margin:0;min-width:0;font:600 var(--inl-size,15px)/1.35 var(--pipeup-ask-font,var(--inl-font,var(--cf)));color:var(--pu-text)}
|
|
7
|
+
.q svg{flex:none;width:18px;height:18px;color:var(--ac)}
|
|
8
|
+
.ctl{display:flex;flex-wrap:wrap;align-items:center;gap:6px 10px;flex:1 1 auto;min-width:0}
|
|
9
|
+
.ctl.open{flex-basis:240px}
|
|
10
|
+
.row{display:flex;flex-wrap:wrap;gap:6px;align-items:center}
|
|
11
|
+
.words{flex-basis:100%;display:flex;flex-wrap:wrap;gap:6px;align-items:center}
|
|
12
|
+
button{appearance:none;font:inherit;color:inherit;min-height:28px;padding:2px 12px;border:1px solid color-mix(in srgb,var(--ac) 28%,var(--pu-line));border-radius:var(--pipeup-ask-radius,999px);background:var(--pu-surface,#fff);cursor:pointer;transition:background-color .2s var(--pu-ease),border-color .2s var(--pu-ease),color .2s var(--pu-ease),opacity .2s var(--pu-ease)}
|
|
7
13
|
button:hover{background:var(--pu-hover)}
|
|
8
|
-
button[aria-pressed=true],button.go{background:var(--
|
|
9
|
-
button:disabled{opacity:.
|
|
10
|
-
button.link{min-height:0;padding:2px 0;border:0;background:none;color:var(--
|
|
11
|
-
button:
|
|
12
|
-
|
|
13
|
-
.
|
|
14
|
-
.
|
|
15
|
-
|
|
16
|
-
.
|
|
14
|
+
button[aria-pressed=true],button.go{background:var(--ac);border-color:var(--ac);color:#fff}
|
|
15
|
+
button:disabled{opacity:.45;cursor:default}
|
|
16
|
+
button.link{min-height:0;padding:2px 0;border:0;border-radius:0;background:none;color:var(--ac)}
|
|
17
|
+
button.link:hover{text-decoration:underline;text-underline-offset:3px}
|
|
18
|
+
button:focus-visible,.fld:focus-within{outline:2px solid var(--ac);outline-offset:2px}
|
|
19
|
+
.fld{flex:1 1 220px;display:flex;align-items:center;gap:8px;min-width:0;padding:3px 3px 3px 10px;border:1px solid color-mix(in srgb,var(--ac) 22%,var(--pu-line));border-radius:var(--pipeup-ask-radius,6px);background:var(--pu-surface,#fff);box-shadow:inset 0 1px 2px rgb(0 0 0/.05);transition:border-color .2s var(--pu-ease)}
|
|
20
|
+
.fld:hover,.fld:focus-within{border-color:var(--ac)}
|
|
21
|
+
textarea{flex:1;display:block;min-width:0;height:24px;max-height:120px;margin:0;padding:3px 0;border:0;outline:0;background:none;color:inherit;font:inherit;line-height:18px;resize:none;overflow-y:hidden}
|
|
22
|
+
.fld button.go{flex:none;align-self:flex-end;min-height:24px;padding:0 10px;border-radius:var(--pipeup-ask-radius,4px);font-weight:600}
|
|
23
|
+
.mine{margin:0;color:var(--pu-muted)}
|
|
24
|
+
.mine b{color:var(--pu-text);font-weight:600}
|
|
25
|
+
.more{flex-basis:100%;display:flex;flex-wrap:wrap;gap:4px 10px;padding-left:26px;color:var(--pu-muted);font-size:13px}
|
|
26
|
+
.inl .more{padding-left:0}
|
|
27
|
+
.note,.err{margin:0;color:var(--pu-muted)}
|
|
28
|
+
.err{flex-basis:100%;color:#B3261E}
|
|
29
|
+
.list{flex-basis:100%}
|
|
30
|
+
.list:empty{display:none}
|
|
31
|
+
.th{margin:6px 0 0;padding:8px 0 0;border-top:1px solid var(--pu-line);animation:in .26s var(--pu-ease)}
|
|
17
32
|
.c{margin:0 0 6px;white-space:pre-wrap;overflow-wrap:anywhere}
|
|
18
33
|
.c b{font-weight:600}
|
|
19
34
|
.c i{color:var(--pu-muted);font-style:normal}
|
|
20
35
|
.re{margin-left:16px}
|
|
21
|
-
.th
|
|
36
|
+
.th .fld{margin-top:4px}
|
|
22
37
|
@keyframes in{from{opacity:0;transform:translateY(3px)}}
|
|
23
|
-
@media (pointer:coarse){button{min-height:44px}button.link{min-height:44px}}
|
|
24
|
-
@media (prefers-reduced-motion:reduce){.box,.th{animation:none}button{transition:none}}`;function
|
|
25
|
-
`)[0])),
|
|
38
|
+
@media (pointer:coarse){button,.fld button.go{min-height:44px}button.link{min-height:44px}.fld{min-height:44px}}
|
|
39
|
+
@media (prefers-reduced-motion:reduce){.box,.th{animation:none}button,.fld{transition:none}}`;function i(e,n={},...t){let d=document.createElement(e);for(let[o,m]of Object.entries(n))d.setAttribute(o,m);return d.append(...t),d}var ne="http://www.w3.org/2000/svg";function ge(){let e=document.createElementNS(ne,"svg");e.setAttribute("viewBox","0 0 20 20"),e.setAttribute("aria-hidden","true");let n="M4 3.5h12a2 2 0 0 1 2 2v7a2 2 0 0 1-2 2H9l-4 3v-3H4a2 2 0 0 1-2-2v-7a2 2 0 0 1 2-2Z";for(let[t,d]of[[n,{fill:"currentColor",opacity:".16"}],[n,{fill:"none",stroke:"currentColor","stroke-width":"1.5","stroke-linejoin":"round"}],["M6.5 9h7",{stroke:"currentColor","stroke-width":"1.5","stroke-linecap":"round"}]]){let o=document.createElementNS(ne,"path");o.setAttribute("d",t);for(let[m,u]of Object.entries(d))o.setAttribute(m,u);e.append(o)}return e}function re(e,...n){let t=i("textarea",{"aria-label":e,placeholder:e,rows:"1"}),d=()=>{t.style.height="auto";let o=Math.min(t.scrollHeight,120);t.style.height=`${Math.max(o,24)}px`,t.style.overflowY=t.scrollHeight>120?"auto":"hidden"};return t.addEventListener("input",d),{fld:i("div",{class:"fld"},t,...n),area:t}}var F=e=>e.replies.reduce((n,t)=>n+(t.deleted?0:1)+F(t),0),N=(e,n,t=`${n}s`)=>`${e} ${e===1?n:t}`,j=e=>e.name||globalThis.Pipeup?.animalName?.(e.author)||"Someone",M=()=>(O("data-pipeup-agents")??"").split(/[\s,]+/).filter(Boolean),ye=()=>matchMedia("(prefers-reduced-motion: reduce)").matches;function be(){return{id:"inline",api:1,version:"0.9.1",needs:["place","post","menu","panel","styles"],network:{when:"never",to:[],says:"Sends nothing: answers to asks are ordinary comments, kept and sent the way the page's other comments are."},setup(e){let n=!0,t=[];for(let c of e.root.querySelectorAll("[data-pipeup-ask],[data-pipeup-inline]")){if(c.closest("[data-pipeup-placed]"))continue;let g=c.hasAttribute("data-pipeup-ask")?X(c):null;if(typeof g=="string"||!g&&!c.getAttribute("data-pipeup-id")){console.warn(`pipeup: ${typeof g=="string"?g:`<${c.localName} data-pipeup-inline> needs a data-pipeup-id`}; the inline add-on leaves it as it is`);continue}t.push(xe(e,c,g,()=>n))}let d=t.filter(c=>c.ask?.needed),o=e.addStyles(".inl-asks{display:flex;flex-direction:column;gap:6px;padding:12px}.inl-asks button{padding:10px 12px;border:1px solid var(--pu-line);border-radius:8px;text-align:left;transition:background-color .2s var(--pu-ease)}.inl-asks button:hover{background:var(--pu-hover)}"),m=()=>d.filter(c=>!C(c.ask,e.document.threads(),e.document.me,M()).mine),u=d.length?e.addMenuItem({id:"asks",icon:["M4 5h16v11H9l-5 4z","M9.5 9a2.5 2.5 0 1 1 2.5 2.5V13","M12 15.5v.01"],label:()=>`${d.length-m().length} of ${N(d.length,"ask")} answered`,hint:()=>"The asks the author needs answered, and where each one is",select:()=>{let c=m(),g=i("div",{class:"inl-asks"});c.length||g.append(i("p",{},"Every ask is answered. Thank you."));for(let T of c){let k=i("button",{type:"button"},T.ask.question);k.addEventListener("click",()=>{$.close(),T.el.scrollIntoView({block:"center",behavior:ye()?"auto":"smooth"}),T.focus()}),g.append(k)}let $=e.openPanel(g,{label:"Asks to answer"})}}):null,h=()=>{for(let c of t)c.render();u?.update()},A=e.document.onChange(h),w=e.onUi(c=>{c.shown!==n&&(n=c.shown,h())});return h(),()=>{A(),w(),u?.remove(),o()}}}}function xe(e,n,t,d){let o=e.place(n),m=n.ownerDocument.defaultView?.CSSStyleSheet;if(m&&"adoptedStyleSheets"in o){let r=new m;r.replaceSync(te),o.adoptedStyleSheets=[...o.adoptedStyleSheets,r]}else o.append(i("style",{},te));let u=e.document.me,h=getComputedStyle(n);o.host.style.setProperty("--inl-font",h.fontFamily),o.host.style.setProperty("--inl-size",h.fontSize);let A=i("div",t?{class:"box",role:"group","aria-label":t.question}:{class:"inl"}),w=i("div",{class:"ctl"}),c=i("span",{class:"note"}),g=i("button",{type:"button",class:"link","aria-expanded":"false"}),$=i("div",{class:"more"},c,g),T=i("div",{class:"list"}),k=i("p",{class:"err",role:"alert",hidden:""});t&&A.append(i("p",{class:"q"},ge(),i("span",{},t.question)),w),A.append($,T,k),o.append(A);let I=!1,S=!1,P="",V=new Map,K=r=>{k.textContent=`Couldn't send: ${r instanceof Error?r.message.replace(/^pipeup: /,""):String(r)}`,k.hidden=!1};async function q(r,a){let f=W(t,{choice:r,words:a}),l=C(t,e.document.threads(),u,M()).mine;k.hidden=!0;try{return l?await e.post({edit:l.root.id,text:f}):await e.post({anchor:n,text:f,excerpt:R+t.question}),e.announce(l?"Answer changed":"Answer sent"),S=!1,P="",B(),!0}catch(y){return K(y),!1}}function J(r,a,f){let l=i("button",{type:"button",class:"go"},"Send"),{fld:y,area:s}=re(r,l),p=()=>l.disabled=a&&!s.value.trim(),x=async()=>{l.disabled||(l.disabled=!0,await f(s.value)&&(s.value="",s.dispatchEvent(new Event("input"))),p())};return s.addEventListener("input",p),s.addEventListener("keydown",b=>{b.key==="Enter"&&!b.shiftKey&&!b.isComposing&&(b.preventDefault(),x())}),l.addEventListener("click",()=>void x()),p(),t.kind==="open"&&S&&C(t,e.document.threads(),u,M()).mine?[y,Y()]:[y]}function Y(){let r=i("button",{type:"button"},"Cancel");return r.addEventListener("click",()=>{S=!1,P="",B(),w.querySelector("button")?.focus()}),r}function oe(){let r=t,a=i("div",{class:"words"});if(w.className=r.kind==="open"?"ctl open":"ctl",r.kind==="open"){w.replaceChildren(...J("Type your answer",!0,s=>q("",s)));return}let l=[...r.options,...r.other?[E]:[]].map(s=>{let p=i("button",{type:"button","aria-pressed":"false"},s);return p.addEventListener("click",()=>{if(r.kind==="choice"&&s!==E)return void q(s,"");for(let b of l)b.setAttribute("aria-pressed",String(b===p));let x=s===L?"Anything to add? (optional)":s===D?"What needs to change?":"Type your answer";a.replaceChildren(...J(x,s!==L,b=>q(s,b))),a.querySelector("textarea").focus()}),p}),y=i("div",{class:"row"},...l);S&&C(r,e.document.threads(),u,M()).mine&&y.append(Y()),w.replaceChildren(y,a)}function ie(r){let a=i("button",{type:"button",class:"link"},"Change");a.addEventListener("click",()=>{S=!0,P="",B(),w.querySelector("button, textarea")?.focus()});let f=i("button",{type:"button",class:"link"},"Remove");f.addEventListener("click",()=>se(C(t,e.document.threads(),u,M()).mine??r)),w.className="ctl",w.replaceChildren(i("p",{class:"mine"},"You said ",i("b",{},r.root.text.split(`
|
|
40
|
+
`)[0])),a,f)}function se(r){let a=F(r.root),f=performance.now(),l=()=>performance.now()-f<500,y=i("button",{type:"button",class:"go"},"Remove"),s=i("button",{type:"button"},"Keep"),p=i("div",{class:"row confirm",role:"group","aria-label":"Remove your answer"},y,s),x=()=>{P="",B(),w.querySelector("button")?.focus()};y.addEventListener("click",()=>{l()||(k.hidden=!0,y.disabled=s.disabled=!0,e.post({remove:r.root.id,text:""}).then(()=>{e.announce("Answer removed"),S=!1,P="",B(),w.querySelector("button, textarea")?.focus()},b=>{y.disabled=s.disabled=!1,K(b)}))}),s.addEventListener("click",()=>{l()||x()}),p.addEventListener("keydown",b=>{b.key==="Escape"&&(b.preventDefault(),x())}),w.className="ctl",w.replaceChildren(i("p",{class:"mine"},a?`Remove your answer and its ${N(a,"reply","replies")}?`:"Remove your answer?"),p),s.focus()}function ae(r){let a=i("div",{class:"th","data-thread":r.id}),f=(p,x="c")=>i("p",{class:x},i("b",{},p.author===u?"You":j(p)),p.edited?i("i",{}," (edited)"):"",": ",p.deleted?i("i",{},"deleted"):p.text);a.append(f(r.root));let l=t?Q(t,r):null;l&&a.append(i("p",{class:"note"},`Asked as: ${l}`));let y=p=>{a.append(f(p,"c re")),p.replies.forEach(y)};r.root.replies.forEach(y);let s=V.get(r.id);if(!s){s=re(`Reply to ${j(r.root)}`).area;let p=s;p.addEventListener("keydown",x=>{x.key!=="Enter"||x.shiftKey||x.isComposing||!p.value.trim()||(x.preventDefault(),k.hidden=!0,e.post({replyTo:r.root.id,text:p.value}).then(()=>{p.value="",e.announce("Reply sent")},K))}),V.set(r.id,s)}return a.append(s.parentElement??s),a}function B(){let r=e.document.threads(),a=t?C(t,r,u,M()):null,f=a?.mine??null;if(t){let v=f&&!S?`answered:${f.root.text}:${f.root.edited}`:"answering";v!==P&&(P=v,f&&!S?ie(f):oe())}let l=(a?.threads??r.filter(v=>v.anchor.id===n.getAttribute("data-pipeup-id"))).filter(v=>!v.root.deleted),y=d()&&(!t||!!f),s=a?a.answers.length-1:0;if(c.hidden=!y||!a||s<1,c.textContent="",a&&!c.hidden){let v=[...a.counts].filter(([,U])=>U>0).map(([U,_])=>`${U}: ${_}`);c.textContent=`${N(a.answers.length,"person","people")} answered${v.length?`. ${v.join(", ")}`:""}.`}let p=!!f&&l.length===1&&l[0].id===f.id&&F(f.root)===0;if(g.hidden=!y||!l.length||p,g.textContent="",!g.hidden){let v=l.map(ee).sort((U,_)=>_.at-U.at)[0];g.textContent=`${N(l.length,"comment")} \xB7 latest from ${v.author===u?"you":j(v)}`}$.hidden=c.hidden&&g.hidden;let x=I&&!g.hidden;g.setAttribute("aria-expanded",String(x));let b=o.activeElement;T.replaceChildren(...x?l.map(ae):[]),b instanceof HTMLTextAreaElement&&T.contains(b)&&b.focus()}return g.addEventListener("click",()=>{I=!I,B()}),{el:n,ask:t,render:B,focus:()=>o.querySelector("button, textarea")?.focus({preventScroll:!0})}}export{be as default};
|
package/dist/inline.min.js
CHANGED
|
@@ -1,25 +1,40 @@
|
|
|
1
|
-
"use strict";(()=>{function
|
|
2
|
-
|
|
1
|
+
"use strict";(()=>{function z(e){let n=globalThis;(n.pipeupAddons||=[]).push(e),typeof addEventListener=="function"&&addEventListener("load",()=>{n.Pipeup||console.error(`pipeup: the "${e.id}" add-on needs Pipeup on the page too; load pipeup.min.js.`)},{once:!0})}var O=(e,n)=>n?n.getAttribute(e):globalThis.Pipeup?.setting?.(e)??globalThis.document?.documentElement.getAttribute(e)??null;var Re=2n**256n-2n**32n-977n;var L="Agree",D="Needs change",E="Other",R="Asked: ";function W(e){let n=e.getAttribute("data-pipeup-id")??"",t=(e.getAttribute("data-pipeup-ask")??"").replace(/\s+/g," ").trim(),d=`<${e.localName}${n?` data-pipeup-id="${n}"`:""}>`;if(!n)return`the ask ${d} needs a data-pipeup-id, its name`;if(!t)return`the ask ${d} needs its question in data-pipeup-ask`;let o=e.getAttribute("data-pipeup-ask-kind")??"open",m=o==="agree"||o==="choice"?o:"open",u=[];return m==="agree"&&(u=[L,D]),m==="choice"&&(u=[...new Set((e.getAttribute("data-pipeup-ask-options")??"").split("|").map(h=>h.trim()).filter(Boolean))],u.length<2||u.length>6)?`the ask ${d} needs two to six options in data-pipeup-ask-options, separated by |`:{id:n,question:t,kind:m,options:u,other:m==="choice"&&e.hasAttribute("data-pipeup-ask-other"),needed:e.hasAttribute("data-pipeup-ask-needed")}}function Q(e,n){let t=n.words.trim();return e.kind==="open"?t:e.kind==="choice"&&n.choice!==E?n.choice:t?`${n.choice}: ${t}`:n.choice}function he(e,n){let t=n.trim();if(!t)return null;if(e.kind==="open")return{choice:"",words:t};let d=[...e.options,...e.other?[E]:[]];for(let o of d){if(t===o&&o!==D&&o!==E)return{choice:o,words:""};if((e.kind==="agree"||o===E)&&t.startsWith(`${o}:`)){let m=t.slice(o.length+1).trim();if(m||o===L)return{choice:o,words:m}}}return null}var X="AI assistant",ge=(e,n)=>n.includes(e.author)||e.name===X||e.name.startsWith(`${X} `);function ye(e,n,t=[]){return n.anchor.id!==e.id||!n.anchor.snapshot.startsWith(R)||n.root.deleted||ge(n.root,t)?null:he(e,n.root.text)}function ee(e,n){let t=n.anchor.snapshot.slice(R.length);return t&&t!==e.question.slice(0,t.length)?t:null}function C(e,n,t,d=[]){let o=n.filter(h=>h.anchor.id===e.id).sort((h,A)=>h.root.at-A.root.at),m=new Map;for(let h of o){let A=ye(e,h,d);A&&m.set(h.root.author,{thread:h,answer:A})}let u=new Map;for(let h of[...e.options,...e.other?[E]:[]])u.set(h,0);for(let{answer:h}of m.values())u.has(h.choice)&&u.set(h.choice,u.get(h.choice)+1);return{mine:m.get(t)?.thread??null,answers:[...m.values()],counts:u,threads:o}}function te(e){let n=e.root,t=d=>{!d.deleted&&d.at>=n.at&&(n=d),d.replies.forEach(t)};return e.root.replies.forEach(t),n}var ne=`*{box-sizing:border-box}
|
|
2
|
+
[hidden]{display:none!important}
|
|
3
|
+
:host{--ac:var(--pipeup-ask-accent,var(--pu-accent,#534AB7));--cf:var(--pipeup-ask-font,var(--pu-font,system-ui,sans-serif))}
|
|
4
|
+
.box{display:flex;flex-wrap:wrap;align-items:center;gap:6px 12px;margin:10px 0;padding:8px 12px;border-radius:var(--pipeup-ask-radius,8px);background:color-mix(in srgb,var(--ac) 7%,var(--pu-surface,#fff));font:13.5px/1.4 var(--cf);animation:in .26s var(--pu-ease)}
|
|
3
5
|
.inl{margin:6px 0 0}
|
|
4
|
-
.q{margin:0
|
|
5
|
-
.
|
|
6
|
-
|
|
6
|
+
.q{display:flex;align-items:center;gap:8px;margin:0;min-width:0;font:600 var(--inl-size,15px)/1.35 var(--pipeup-ask-font,var(--inl-font,var(--cf)));color:var(--pu-text)}
|
|
7
|
+
.q svg{flex:none;width:18px;height:18px;color:var(--ac)}
|
|
8
|
+
.ctl{display:flex;flex-wrap:wrap;align-items:center;gap:6px 10px;flex:1 1 auto;min-width:0}
|
|
9
|
+
.ctl.open{flex-basis:240px}
|
|
10
|
+
.row{display:flex;flex-wrap:wrap;gap:6px;align-items:center}
|
|
11
|
+
.words{flex-basis:100%;display:flex;flex-wrap:wrap;gap:6px;align-items:center}
|
|
12
|
+
button{appearance:none;font:inherit;color:inherit;min-height:28px;padding:2px 12px;border:1px solid color-mix(in srgb,var(--ac) 28%,var(--pu-line));border-radius:var(--pipeup-ask-radius,999px);background:var(--pu-surface,#fff);cursor:pointer;transition:background-color .2s var(--pu-ease),border-color .2s var(--pu-ease),color .2s var(--pu-ease),opacity .2s var(--pu-ease)}
|
|
7
13
|
button:hover{background:var(--pu-hover)}
|
|
8
|
-
button[aria-pressed=true],button.go{background:var(--
|
|
9
|
-
button:disabled{opacity:.
|
|
10
|
-
button.link{min-height:0;padding:2px 0;border:0;background:none;color:var(--
|
|
11
|
-
button:
|
|
12
|
-
|
|
13
|
-
.
|
|
14
|
-
.
|
|
15
|
-
|
|
16
|
-
.
|
|
14
|
+
button[aria-pressed=true],button.go{background:var(--ac);border-color:var(--ac);color:#fff}
|
|
15
|
+
button:disabled{opacity:.45;cursor:default}
|
|
16
|
+
button.link{min-height:0;padding:2px 0;border:0;border-radius:0;background:none;color:var(--ac)}
|
|
17
|
+
button.link:hover{text-decoration:underline;text-underline-offset:3px}
|
|
18
|
+
button:focus-visible,.fld:focus-within{outline:2px solid var(--ac);outline-offset:2px}
|
|
19
|
+
.fld{flex:1 1 220px;display:flex;align-items:center;gap:8px;min-width:0;padding:3px 3px 3px 10px;border:1px solid color-mix(in srgb,var(--ac) 22%,var(--pu-line));border-radius:var(--pipeup-ask-radius,6px);background:var(--pu-surface,#fff);box-shadow:inset 0 1px 2px rgb(0 0 0/.05);transition:border-color .2s var(--pu-ease)}
|
|
20
|
+
.fld:hover,.fld:focus-within{border-color:var(--ac)}
|
|
21
|
+
textarea{flex:1;display:block;min-width:0;height:24px;max-height:120px;margin:0;padding:3px 0;border:0;outline:0;background:none;color:inherit;font:inherit;line-height:18px;resize:none;overflow-y:hidden}
|
|
22
|
+
.fld button.go{flex:none;align-self:flex-end;min-height:24px;padding:0 10px;border-radius:var(--pipeup-ask-radius,4px);font-weight:600}
|
|
23
|
+
.mine{margin:0;color:var(--pu-muted)}
|
|
24
|
+
.mine b{color:var(--pu-text);font-weight:600}
|
|
25
|
+
.more{flex-basis:100%;display:flex;flex-wrap:wrap;gap:4px 10px;padding-left:26px;color:var(--pu-muted);font-size:13px}
|
|
26
|
+
.inl .more{padding-left:0}
|
|
27
|
+
.note,.err{margin:0;color:var(--pu-muted)}
|
|
28
|
+
.err{flex-basis:100%;color:#B3261E}
|
|
29
|
+
.list{flex-basis:100%}
|
|
30
|
+
.list:empty{display:none}
|
|
31
|
+
.th{margin:6px 0 0;padding:8px 0 0;border-top:1px solid var(--pu-line);animation:in .26s var(--pu-ease)}
|
|
17
32
|
.c{margin:0 0 6px;white-space:pre-wrap;overflow-wrap:anywhere}
|
|
18
33
|
.c b{font-weight:600}
|
|
19
34
|
.c i{color:var(--pu-muted);font-style:normal}
|
|
20
35
|
.re{margin-left:16px}
|
|
21
|
-
.th
|
|
36
|
+
.th .fld{margin-top:4px}
|
|
22
37
|
@keyframes in{from{opacity:0;transform:translateY(3px)}}
|
|
23
|
-
@media (pointer:coarse){button{min-height:44px}button.link{min-height:44px}}
|
|
24
|
-
@media (prefers-reduced-motion:reduce){.box,.th{animation:none}button{transition:none}}`;function
|
|
25
|
-
`)[0])),
|
|
38
|
+
@media (pointer:coarse){button,.fld button.go{min-height:44px}button.link{min-height:44px}.fld{min-height:44px}}
|
|
39
|
+
@media (prefers-reduced-motion:reduce){.box,.th{animation:none}button,.fld{transition:none}}`;function i(e,n={},...t){let d=document.createElement(e);for(let[o,m]of Object.entries(n))d.setAttribute(o,m);return d.append(...t),d}var re="http://www.w3.org/2000/svg";function be(){let e=document.createElementNS(re,"svg");e.setAttribute("viewBox","0 0 20 20"),e.setAttribute("aria-hidden","true");let n="M4 3.5h12a2 2 0 0 1 2 2v7a2 2 0 0 1-2 2H9l-4 3v-3H4a2 2 0 0 1-2-2v-7a2 2 0 0 1 2-2Z";for(let[t,d]of[[n,{fill:"currentColor",opacity:".16"}],[n,{fill:"none",stroke:"currentColor","stroke-width":"1.5","stroke-linejoin":"round"}],["M6.5 9h7",{stroke:"currentColor","stroke-width":"1.5","stroke-linecap":"round"}]]){let o=document.createElementNS(re,"path");o.setAttribute("d",t);for(let[m,u]of Object.entries(d))o.setAttribute(m,u);e.append(o)}return e}function oe(e,...n){let t=i("textarea",{"aria-label":e,placeholder:e,rows:"1"}),d=()=>{t.style.height="auto";let o=Math.min(t.scrollHeight,120);t.style.height=`${Math.max(o,24)}px`,t.style.overflowY=t.scrollHeight>120?"auto":"hidden"};return t.addEventListener("input",d),{fld:i("div",{class:"fld"},t,...n),area:t}}var V=e=>e.replies.reduce((n,t)=>n+(t.deleted?0:1)+V(t),0),N=(e,n,t=`${n}s`)=>`${e} ${e===1?n:t}`,F=e=>e.name||globalThis.Pipeup?.animalName?.(e.author)||"Someone",M=()=>(O("data-pipeup-agents")??"").split(/[\s,]+/).filter(Boolean),xe=()=>matchMedia("(prefers-reduced-motion: reduce)").matches;function ie(){return{id:"inline",api:1,version:"0.9.1",needs:["place","post","menu","panel","styles"],network:{when:"never",to:[],says:"Sends nothing: answers to asks are ordinary comments, kept and sent the way the page's other comments are."},setup(e){let n=!0,t=[];for(let c of e.root.querySelectorAll("[data-pipeup-ask],[data-pipeup-inline]")){if(c.closest("[data-pipeup-placed]"))continue;let g=c.hasAttribute("data-pipeup-ask")?W(c):null;if(typeof g=="string"||!g&&!c.getAttribute("data-pipeup-id")){console.warn(`pipeup: ${typeof g=="string"?g:`<${c.localName} data-pipeup-inline> needs a data-pipeup-id`}; the inline add-on leaves it as it is`);continue}t.push(we(e,c,g,()=>n))}let d=t.filter(c=>c.ask?.needed),o=e.addStyles(".inl-asks{display:flex;flex-direction:column;gap:6px;padding:12px}.inl-asks button{padding:10px 12px;border:1px solid var(--pu-line);border-radius:8px;text-align:left;transition:background-color .2s var(--pu-ease)}.inl-asks button:hover{background:var(--pu-hover)}"),m=()=>d.filter(c=>!C(c.ask,e.document.threads(),e.document.me,M()).mine),u=d.length?e.addMenuItem({id:"asks",icon:["M4 5h16v11H9l-5 4z","M9.5 9a2.5 2.5 0 1 1 2.5 2.5V13","M12 15.5v.01"],label:()=>`${d.length-m().length} of ${N(d.length,"ask")} answered`,hint:()=>"The asks the author needs answered, and where each one is",select:()=>{let c=m(),g=i("div",{class:"inl-asks"});c.length||g.append(i("p",{},"Every ask is answered. Thank you."));for(let T of c){let k=i("button",{type:"button"},T.ask.question);k.addEventListener("click",()=>{$.close(),T.el.scrollIntoView({block:"center",behavior:xe()?"auto":"smooth"}),T.focus()}),g.append(k)}let $=e.openPanel(g,{label:"Asks to answer"})}}):null,h=()=>{for(let c of t)c.render();u?.update()},A=e.document.onChange(h),w=e.onUi(c=>{c.shown!==n&&(n=c.shown,h())});return h(),()=>{A(),w(),u?.remove(),o()}}}}function we(e,n,t,d){let o=e.place(n),m=n.ownerDocument.defaultView?.CSSStyleSheet;if(m&&"adoptedStyleSheets"in o){let r=new m;r.replaceSync(ne),o.adoptedStyleSheets=[...o.adoptedStyleSheets,r]}else o.append(i("style",{},ne));let u=e.document.me,h=getComputedStyle(n);o.host.style.setProperty("--inl-font",h.fontFamily),o.host.style.setProperty("--inl-size",h.fontSize);let A=i("div",t?{class:"box",role:"group","aria-label":t.question}:{class:"inl"}),w=i("div",{class:"ctl"}),c=i("span",{class:"note"}),g=i("button",{type:"button",class:"link","aria-expanded":"false"}),$=i("div",{class:"more"},c,g),T=i("div",{class:"list"}),k=i("p",{class:"err",role:"alert",hidden:""});t&&A.append(i("p",{class:"q"},be(),i("span",{},t.question)),w),A.append($,T,k),o.append(A);let I=!1,S=!1,P="",J=new Map,K=r=>{k.textContent=`Couldn't send: ${r instanceof Error?r.message.replace(/^pipeup: /,""):String(r)}`,k.hidden=!1};async function q(r,a){let f=Q(t,{choice:r,words:a}),l=C(t,e.document.threads(),u,M()).mine;k.hidden=!0;try{return l?await e.post({edit:l.root.id,text:f}):await e.post({anchor:n,text:f,excerpt:R+t.question}),e.announce(l?"Answer changed":"Answer sent"),S=!1,P="",B(),!0}catch(y){return K(y),!1}}function Y(r,a,f){let l=i("button",{type:"button",class:"go"},"Send"),{fld:y,area:s}=oe(r,l),p=()=>l.disabled=a&&!s.value.trim(),x=async()=>{l.disabled||(l.disabled=!0,await f(s.value)&&(s.value="",s.dispatchEvent(new Event("input"))),p())};return s.addEventListener("input",p),s.addEventListener("keydown",b=>{b.key==="Enter"&&!b.shiftKey&&!b.isComposing&&(b.preventDefault(),x())}),l.addEventListener("click",()=>void x()),p(),t.kind==="open"&&S&&C(t,e.document.threads(),u,M()).mine?[y,Z()]:[y]}function Z(){let r=i("button",{type:"button"},"Cancel");return r.addEventListener("click",()=>{S=!1,P="",B(),w.querySelector("button")?.focus()}),r}function se(){let r=t,a=i("div",{class:"words"});if(w.className=r.kind==="open"?"ctl open":"ctl",r.kind==="open"){w.replaceChildren(...Y("Type your answer",!0,s=>q("",s)));return}let l=[...r.options,...r.other?[E]:[]].map(s=>{let p=i("button",{type:"button","aria-pressed":"false"},s);return p.addEventListener("click",()=>{if(r.kind==="choice"&&s!==E)return void q(s,"");for(let b of l)b.setAttribute("aria-pressed",String(b===p));let x=s===L?"Anything to add? (optional)":s===D?"What needs to change?":"Type your answer";a.replaceChildren(...Y(x,s!==L,b=>q(s,b))),a.querySelector("textarea").focus()}),p}),y=i("div",{class:"row"},...l);S&&C(r,e.document.threads(),u,M()).mine&&y.append(Z()),w.replaceChildren(y,a)}function ae(r){let a=i("button",{type:"button",class:"link"},"Change");a.addEventListener("click",()=>{S=!0,P="",B(),w.querySelector("button, textarea")?.focus()});let f=i("button",{type:"button",class:"link"},"Remove");f.addEventListener("click",()=>de(C(t,e.document.threads(),u,M()).mine??r)),w.className="ctl",w.replaceChildren(i("p",{class:"mine"},"You said ",i("b",{},r.root.text.split(`
|
|
40
|
+
`)[0])),a,f)}function de(r){let a=V(r.root),f=performance.now(),l=()=>performance.now()-f<500,y=i("button",{type:"button",class:"go"},"Remove"),s=i("button",{type:"button"},"Keep"),p=i("div",{class:"row confirm",role:"group","aria-label":"Remove your answer"},y,s),x=()=>{P="",B(),w.querySelector("button")?.focus()};y.addEventListener("click",()=>{l()||(k.hidden=!0,y.disabled=s.disabled=!0,e.post({remove:r.root.id,text:""}).then(()=>{e.announce("Answer removed"),S=!1,P="",B(),w.querySelector("button, textarea")?.focus()},b=>{y.disabled=s.disabled=!1,K(b)}))}),s.addEventListener("click",()=>{l()||x()}),p.addEventListener("keydown",b=>{b.key==="Escape"&&(b.preventDefault(),x())}),w.className="ctl",w.replaceChildren(i("p",{class:"mine"},a?`Remove your answer and its ${N(a,"reply","replies")}?`:"Remove your answer?"),p),s.focus()}function pe(r){let a=i("div",{class:"th","data-thread":r.id}),f=(p,x="c")=>i("p",{class:x},i("b",{},p.author===u?"You":F(p)),p.edited?i("i",{}," (edited)"):"",": ",p.deleted?i("i",{},"deleted"):p.text);a.append(f(r.root));let l=t?ee(t,r):null;l&&a.append(i("p",{class:"note"},`Asked as: ${l}`));let y=p=>{a.append(f(p,"c re")),p.replies.forEach(y)};r.root.replies.forEach(y);let s=J.get(r.id);if(!s){s=oe(`Reply to ${F(r.root)}`).area;let p=s;p.addEventListener("keydown",x=>{x.key!=="Enter"||x.shiftKey||x.isComposing||!p.value.trim()||(x.preventDefault(),k.hidden=!0,e.post({replyTo:r.root.id,text:p.value}).then(()=>{p.value="",e.announce("Reply sent")},K))}),J.set(r.id,s)}return a.append(s.parentElement??s),a}function B(){let r=e.document.threads(),a=t?C(t,r,u,M()):null,f=a?.mine??null;if(t){let v=f&&!S?`answered:${f.root.text}:${f.root.edited}`:"answering";v!==P&&(P=v,f&&!S?ae(f):se())}let l=(a?.threads??r.filter(v=>v.anchor.id===n.getAttribute("data-pipeup-id"))).filter(v=>!v.root.deleted),y=d()&&(!t||!!f),s=a?a.answers.length-1:0;if(c.hidden=!y||!a||s<1,c.textContent="",a&&!c.hidden){let v=[...a.counts].filter(([,U])=>U>0).map(([U,_])=>`${U}: ${_}`);c.textContent=`${N(a.answers.length,"person","people")} answered${v.length?`. ${v.join(", ")}`:""}.`}let p=!!f&&l.length===1&&l[0].id===f.id&&V(f.root)===0;if(g.hidden=!y||!l.length||p,g.textContent="",!g.hidden){let v=l.map(te).sort((U,_)=>_.at-U.at)[0];g.textContent=`${N(l.length,"comment")} \xB7 latest from ${v.author===u?"you":F(v)}`}$.hidden=c.hidden&&g.hidden;let x=I&&!g.hidden;g.setAttribute("aria-expanded",String(x));let b=o.activeElement;T.replaceChildren(...x?l.map(pe):[]),b instanceof HTMLTextAreaElement&&T.contains(b)&&b.focus()}return g.addEventListener("click",()=>{I=!I,B()}),{el:n,ask:t,render:B,focus:()=>o.querySelector("button, textarea")?.focus({preventScroll:!0})}}z(ie());})();
|