@gridd/feedback-stickers 1.0.0 → 1.0.2
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 +35 -53
- package/dist/feedback-stickers.min.js +12 -12
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -23,76 +23,56 @@ View stickies
|
|
|
23
23
|
|
|
24
24
|
---
|
|
25
25
|
|
|
26
|
-
##
|
|
27
|
-
|
|
28
|
-
The `plugin/` directory contains `@gridd/docusaurus-plugin-feedback-stickers`, a thin wrapper that injects the sticker panel into every page of a Docusaurus site and handles client-side navigation automatically.
|
|
29
|
-
|
|
30
|
-
### Installation
|
|
31
|
-
|
|
32
|
-
```bash
|
|
33
|
-
# from the repo root — build the core first, then the plugin
|
|
34
|
-
npm run build
|
|
35
|
-
cd plugin && npm run build && cd ..
|
|
36
|
-
```
|
|
26
|
+
## Building from source
|
|
37
27
|
|
|
38
|
-
|
|
28
|
+
Requirements: Node.js 18+
|
|
39
29
|
|
|
40
30
|
```bash
|
|
41
|
-
|
|
42
|
-
npm
|
|
43
|
-
|
|
44
|
-
# or with npm workspaces / yarn workspaces when co-located in a monorepo
|
|
45
|
-
```
|
|
46
|
-
|
|
47
|
-
### Configuration (`docusaurus.config.js`)
|
|
48
|
-
|
|
49
|
-
```js
|
|
50
|
-
module.exports = {
|
|
51
|
-
// ...
|
|
52
|
-
plugins: [
|
|
53
|
-
[
|
|
54
|
-
'@gridd/docusaurus-plugin-feedback-stickers',
|
|
55
|
-
{
|
|
56
|
-
// enabled: true, // set false to disable without removing the entry
|
|
57
|
-
// devOnly: false, // set true to only show stickers in `docusaurus start`
|
|
58
|
-
},
|
|
59
|
-
],
|
|
60
|
-
],
|
|
61
|
-
};
|
|
31
|
+
npm install
|
|
32
|
+
npm run build # → dist/feedback-stickers.min.js (~18 KB)
|
|
33
|
+
npm run dev # watch mode, unminified + source map
|
|
62
34
|
```
|
|
63
35
|
|
|
64
|
-
|
|
36
|
+
---
|
|
65
37
|
|
|
66
|
-
|
|
38
|
+
## Embedding the script in an HTML file
|
|
67
39
|
|
|
68
|
-
|
|
69
|
-
2. Removes all sticker DOM elements for the previous page
|
|
70
|
-
3. Loads and renders stickers for the new URL from localStorage
|
|
40
|
+
### From a CDN (no build step required)
|
|
71
41
|
|
|
72
|
-
The
|
|
42
|
+
The package is published to npm as `@gridd/feedback-stickers` and is available on both major CDNs.
|
|
73
43
|
|
|
74
|
-
|
|
44
|
+
**jsDelivr** — recommended, global edge network, SRI hash support:
|
|
75
45
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
| `devOnly` | `boolean` | `false` | `true` restricts injection to `docusaurus start` (development mode). |
|
|
46
|
+
```html
|
|
47
|
+
<!-- always latest 1.x -->
|
|
48
|
+
<script src="https://cdn.jsdelivr.net/npm/@gridd/feedback-stickers@1/dist/feedback-stickers.min.js"></script>
|
|
80
49
|
|
|
81
|
-
|
|
50
|
+
<!-- pinned to an exact version (recommended for production) -->
|
|
51
|
+
<script src="https://cdn.jsdelivr.net/npm/@gridd/feedback-stickers@1.0.0/dist/feedback-stickers.min.js"></script>
|
|
52
|
+
```
|
|
82
53
|
|
|
83
|
-
|
|
54
|
+
**unpkg** — alternative CDN, also served directly from the npm registry:
|
|
84
55
|
|
|
85
|
-
|
|
56
|
+
```html
|
|
57
|
+
<!-- always latest 1.x -->
|
|
58
|
+
<script src="https://unpkg.com/@gridd/feedback-stickers@1/dist/feedback-stickers.min.js"></script>
|
|
86
59
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
npm run build # → dist/feedback-stickers.min.js (~18 KB)
|
|
90
|
-
npm run dev # watch mode, unminified + source map
|
|
60
|
+
<!-- pinned to an exact version -->
|
|
61
|
+
<script src="https://unpkg.com/@gridd/feedback-stickers@1.0.0/dist/feedback-stickers.min.js"></script>
|
|
91
62
|
```
|
|
92
63
|
|
|
93
|
-
|
|
64
|
+
> **SRI integrity hashes** — for pinned production deployments, generate a hash with:
|
|
65
|
+
> ```bash
|
|
66
|
+
> curl -s https://cdn.jsdelivr.net/npm/@gridd/feedback-stickers@1.0.0/dist/feedback-stickers.min.js \
|
|
67
|
+
> | openssl dgst -sha384 -binary | openssl base64 -A
|
|
68
|
+
> ```
|
|
69
|
+
> Then add it to the tag:
|
|
70
|
+
> ```html
|
|
71
|
+
> <script src="https://cdn.jsdelivr.net/npm/@gridd/feedback-stickers@1.0.0/dist/feedback-stickers.min.js"
|
|
72
|
+
> integrity="sha384-<hash>" crossorigin="anonymous"></script>
|
|
73
|
+
> ```
|
|
94
74
|
|
|
95
|
-
|
|
75
|
+
### From a local file
|
|
96
76
|
|
|
97
77
|
Add one line before `</body>`:
|
|
98
78
|
|
|
@@ -191,6 +171,8 @@ Or inline the minified script for a single self-contained file (see *Single-file
|
|
|
191
171
|
|
|
192
172
|
Send the HTML file to the reviewer. If the script is not inlined, include `feedback-stickers.min.js` alongside it in the same folder (or zip archive).
|
|
193
173
|
|
|
174
|
+
Alternatively if you use Docusaurus rendering engine, you can use the [@gridd/docusaurus-feedback-plugin](https://www.npmjs.com/package/@gridd/docusaurus-feedback-plugin)'s export button that generates the page with inlined scripts, images, for easy share with the less technical colleagues.
|
|
175
|
+
|
|
194
176
|
---
|
|
195
177
|
|
|
196
178
|
### Step 2 — Reviewer: open the file
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
"use strict";var FeedbackStickers=(()=>{var H=["yellow","amber","orange","red","rose","pink","purple","indigo","blue","teal","green","lime"],
|
|
1
|
+
"use strict";var FeedbackStickers=(()=>{var H=["yellow","amber","orange","red","rose","pink","purple","indigo","blue","teal","green","lime"],D={yellow:{bg:"#FDE047",border:"#CA8A04",text:"#000",defaultLabel:"Question"},amber:{bg:"#FCD34D",border:"#B45309",text:"#000",defaultLabel:"Comment"},orange:{bg:"#FB923C",border:"#C2410C",text:"#000",defaultLabel:"Check"},red:{bg:"#F87171",border:"#B91C1C",text:"#fff",defaultLabel:"Blocker"},rose:{bg:"#FB7185",border:"#BE123C",text:"#fff",defaultLabel:"Critical"},pink:{bg:"#F472B6",border:"#BE185D",text:"#fff",defaultLabel:"Visual"},purple:{bg:"#C084FC",border:"#7E22CE",text:"#fff",defaultLabel:"Message"},indigo:{bg:"#818CF8",border:"#3730A3",text:"#fff",defaultLabel:"Technical"},blue:{bg:"#60A5FA",border:"#1D4ED8",text:"#fff",defaultLabel:"Usability"},teal:{bg:"#2DD4BF",border:"#0F766E",text:"#000",defaultLabel:"FYI"},green:{bg:"#4ADE80",border:"#15803D",text:"#000",defaultLabel:"Looks good"},lime:{bg:"#A3E635",border:"#4D7C0F",text:"#000",defaultLabel:"Approved"}};var U="fs_",ce=U+"colorLabels",de=U+"reviewer";function ke(s){let r=2166136261;for(let a=0;a<s.length;a++)r^=s.charCodeAt(a),r=Math.imul(r,16777619)>>>0;return r.toString(36)}function pe(){return U+"s_"+ke(location.href)}function J(s,r){try{let a=localStorage.getItem(s);return a!==null?JSON.parse(a):r}catch{return r}}function V(s,r){try{localStorage.setItem(s,JSON.stringify(r))}catch{}}function G(){return J(pe(),[])}function C(s){V(pe(),s)}function fe(s){return{...s,...J(ce,{})}}function Q(s){V(ce,s)}function ue(){return J(de,"")}function me(s){V(de,s)}function w(s){return'"'+s.replace(/\\/g,"\\\\").replace(/"/g,'\\"').replace(/\n/g,"\\n").replace(/\r/g,"")+'"'}function ge(s){let r=['version: "1.0"',"page:",` url: ${w(s.page.url)}`,` title: ${w(s.page.title)}`,` exportedAt: ${w(s.page.exportedAt)}`,"colorLabels:",...Object.entries(s.colorLabels).map(([a,p])=>` ${a}: ${w(p)}`),"stickers:"];if(s.stickers.length===0)r.push(" []");else for(let a of s.stickers){let p=a.position;r.push(` - id: ${w(a.id)}`,` reviewer: ${w(a.reviewer)}`,` comment: ${w(a.comment)}`,` color: ${a.color}`," position:",` xPct: ${p.xPct??0}`,` yPct: ${p.yPct??0}`),p.anchorSelector&&r.push(` anchorSelector: ${w(p.anchorSelector)}`,` anchorOffsetXPct: ${p.anchorOffsetXPct??0}`,` anchorOffsetYPct: ${p.anchorOffsetYPct??0}`),r.push(` minimized: ${a.minimized}`,` rotation: ${a.rotation??0}`,` createdAt: ${w(a.createdAt)}`,` updatedAt: ${w(a.updatedAt)}`)}return r.join(`
|
|
2
2
|
`)+`
|
|
3
3
|
`}function be(s){let r={version:"1.0",page:{url:"",title:"",exportedAt:""},colorLabels:{},stickers:[]},a=s.split(`
|
|
4
|
-
`).map(f=>f.trimEnd()),p="root",
|
|
5
|
-
`).replace(/\\"/g,'"').replace(/\\\\/g,"\\"):l}function P(f){let l=f.indexOf(":");return l===-1?[f.trim(),""]:[f.slice(0,l).trim(),f.slice(l+1).trimStart()]}for(let f of a){if(!f.trim()||f.trimStart().startsWith("#"))continue;let l=f.length-f.trimStart().length,u=f.trim();if(l===0){
|
|
4
|
+
`).map(f=>f.trimEnd()),p="root",o=null,b=!1;function v(f){let l=f.trim();if(l==="true")return!0;if(l==="false")return!1;let u=Number(l);return l!==""&&!isNaN(u)?u:l.startsWith("'")&&l.endsWith("'")?l.slice(1,-1).replace(/''/g,"'"):l.startsWith('"')&&l.endsWith('"')?l.slice(1,-1).replace(/\\n/g,`
|
|
5
|
+
`).replace(/\\"/g,'"').replace(/\\\\/g,"\\"):l}function P(f){let l=f.indexOf(":");return l===-1?[f.trim(),""]:[f.slice(0,l).trim(),f.slice(l+1).trimStart()]}for(let f of a){if(!f.trim()||f.trimStart().startsWith("#"))continue;let l=f.length-f.trimStart().length,u=f.trim();if(l===0){o&&(r.stickers.push(o),o=null),b=!1,u==="page:"?p="page":u==="colorLabels:"?p="colorLabels":u==="stickers:"?p="stickers":u.startsWith("version:")&&(r.version=String(v(u.slice(8))));continue}if(p==="page"&&l===2){let[x,m]=P(u);r.page[x]=String(v(m))}else if(p==="colorLabels"&&l===2){let[x,m]=P(u);r.colorLabels[x]=String(v(m))}else if(p==="stickers"){if(l===2&&u.startsWith("- ")){b=!1,o&&r.stickers.push(o),o={};let[x,m]=P(u.slice(2));o[x]=v(m)}else if(l===4&&o)if(u==="position:")b=!0,o.position={xPct:0,yPct:0};else{b=!1;let[x,m]=P(u);o[x]=v(m)}else if(l===6&&b&&o?.position){let[x,m]=P(u);o.position[x]=v(m)}}}return o&&r.stickers.push(o),r}var xe=window;xe.__fsLoaded||(xe.__fsLoaded=!0,we());function we(){let s=Object.fromEntries(H.map(e=>[e,D[e].defaultLabel])),r=!1,a=H[0],p=ue(),o=G(),b=fe(s),v=2147483640,P=document.createElement("style");P.textContent="html.fs-mode,html.fs-mode *{cursor:crosshair!important}",(document.head??document.documentElement).appendChild(P);let f=document.createElement("div");f.dataset.fsHost="",f.style.cssText="position:fixed;bottom:16px;right:16px;z-index:2147483647;pointer-events:none";let l=f.attachShadow({mode:"open"});document.documentElement.appendChild(f);let u=document.createElement("style");u.textContent=`
|
|
6
6
|
:host{all:initial}
|
|
7
7
|
*{box-sizing:border-box;margin:0;padding:0;font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif}
|
|
8
|
-
.wrap{
|
|
8
|
+
.wrap{display:flex;flex-direction:column;align-items:flex-end;gap:8px;pointer-events:none}
|
|
9
9
|
.fab{width:40px;height:40px;border-radius:50%;background:#222;color:#fff;border:none;font-size:18px;cursor:pointer;box-shadow:0 2px 12px rgba(0,0,0,.35);display:flex;align-items:center;justify-content:center;pointer-events:auto;user-select:none;transition:background .15s}
|
|
10
10
|
.fab:hover{background:#444}.fab.on{background:#FDE047;color:#000}
|
|
11
11
|
.panel{background:#fff;border-radius:10px;box-shadow:0 6px 28px rgba(0,0,0,.22);width:256px;pointer-events:auto;overflow:hidden}
|
|
@@ -46,17 +46,17 @@
|
|
|
46
46
|
</div>
|
|
47
47
|
<button class="mbtn off" id="mb">Start Reviewing</button>
|
|
48
48
|
<div>
|
|
49
|
-
<div class="lbl">
|
|
49
|
+
<div class="lbl">Manage feedback</div>
|
|
50
50
|
<div class="acts">
|
|
51
|
-
<button class="abtn" id="eb">Export
|
|
52
|
-
<button class="abtn" id="ib">Import
|
|
51
|
+
<button class="abtn" id="eb">Export</button>
|
|
52
|
+
<button class="abtn" id="ib">Import</button>
|
|
53
53
|
<button class="abtn d" id="cb">Clear</button>
|
|
54
54
|
</div>
|
|
55
55
|
<input type="file" id="if" accept=".yaml,.yml" style="display:none" />
|
|
56
56
|
</div>
|
|
57
57
|
<div class="stat" id="st">No stickers</div>
|
|
58
58
|
</div>
|
|
59
|
-
`;let E=document.createElement("button");E.className="fab",E.textContent="\u{1F4CC}",E.title="Feedback Stickers",x.appendChild(m),x.appendChild(E);let L=e=>l.querySelector(e),K=L("#ri"),M=L("#cg"),F=L("#mb"),he=L("#st"),
|
|
59
|
+
`;let E=document.createElement("button");E.className="fab",E.textContent="\u{1F4CC}",E.title="Feedback Stickers",x.appendChild(m),x.appendChild(E);let L=e=>l.querySelector(e),K=L("#ri"),M=L("#cg"),F=L("#mb"),he=L("#st"),I=L("#if");K.value=p;function Z(){M.innerHTML="";for(let e of H){let t=D[e],n=document.createElement("div");n.className="cell"+(e===a?" active":""),n.dataset.color=e,n.innerHTML=`<div class="sdot" style="background:${t.bg};border-color:${t.border}"></div><div class="clbl" contenteditable="true" data-label="${e}">${b[e]}</div>`,M.appendChild(n)}}Z();function z(){let e=o.length;he.textContent=e===0?"No stickers":e===1?"1 sticker":`${e} stickers`}E.addEventListener("click",()=>{let e=m.style.display!=="none";m.style.display=e?"none":"",E.classList.toggle("on",!e)}),L("#pc").addEventListener("click",()=>{m.style.display="none",E.classList.remove("on")}),K.addEventListener("input",W(()=>{p=K.value.trim()||"User",me(p)},300)),M.addEventListener("click",e=>{let t=e.target;if(t.closest("[contenteditable]"))return;let n=t.closest("[data-color]");if(!n)return;let i=n.dataset.color;!i||!(i in D)||(a=i,M.querySelectorAll(".cell").forEach(h=>h.classList.remove("active")),n.classList.add("active"))}),M.addEventListener("blur",e=>{let t=e.target,n=t.dataset.label;if(!n)return;let i=t.textContent?.trim()||D[n].defaultLabel;t.textContent=i,b[n]=i,Q(b)},!0),M.addEventListener("keydown",e=>{e.key==="Enter"&&(e.target.blur(),e.preventDefault())}),F.addEventListener("click",()=>{r=!r,document.documentElement.classList.toggle("fs-mode",r),r?document.addEventListener("click",j,!0):document.removeEventListener("click",j,!0),F.textContent=r?"Stop Reviewing":"Start Reviewing",F.className="mbtn "+(r?"on":"off"),E.classList.toggle("on",r)}),L("#eb").addEventListener("click",()=>{let e={version:"1.0",page:{url:location.href,title:document.title||location.pathname,exportedAt:new Date().toISOString()},colorLabels:{...b},stickers:[...o]},t=(document.title||"page").replace(/[^a-z0-9_-]/gi,"_")+".review.yaml";Ee(ge(e),t,"text/yaml")}),L("#ib").addEventListener("click",()=>I.click()),I.addEventListener("change",()=>{let e=I.files?.[0];if(!e)return;let t=new FileReader;t.onload=()=>{try{let n=be(t.result);if(!Array.isArray(n.stickers))throw new Error("bad format");for(let i of n.stickers){let h=o.findIndex(O=>O.id===i.id);h>=0?(o[h]=i,document.querySelector(`[data-sticker-id="${i.id}"]`)?.remove()):o.push(i),Y(i)}n.colorLabels&&(Object.assign(b,n.colorLabels),Q(b),Z()),C(o),z()}catch{alert("Import failed: invalid YAML format")}},t.readAsText(e),I.value=""}),L("#cb").addEventListener("click",()=>{confirm("Clear all stickers on this page?")&&(o.length=0,document.querySelectorAll("[data-sticker-id]").forEach(e=>e.remove()),C(o),z())});function Y(e){let t=D[e.color]??D[H[0]],n=b[e.color]||t.defaultLabel,i=(e.reviewer||"U").slice(0,3),h=e.rotation??0,O=new Date(e.createdAt).toLocaleString(void 0,{month:"short",day:"numeric",hour:"2-digit",minute:"2-digit"}),d=document.createElement("div");d.dataset.fsHost="",d.dataset.stickerId=e.id;let{top:$,left:_}=te(e);d.style.cssText=`position:absolute;left:${_}px;top:${$}px;z-index:${v++}`;let N=d.attachShadow({mode:"open"}),y=document.createElement("style");y.textContent=`
|
|
60
60
|
:host{all:initial;cursor:default!important}
|
|
61
61
|
*{box-sizing:border-box;margin:0;padding:0;font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif}
|
|
62
62
|
.dot{width:32px;height:32px;border-radius:50%;background:${t.bg};border:2px solid ${t.border};
|
|
@@ -78,11 +78,11 @@
|
|
|
78
78
|
font-size:11px;line-height:1.4;color:#1a1a1a;outline:none;font-family:inherit}
|
|
79
79
|
textarea::placeholder{color:rgba(0,0,0,.4)}
|
|
80
80
|
.foot{padding:2px 8px 4px;font-size:9px;color:rgba(0,0,0,.45);text-align:right}
|
|
81
|
-
`;let
|
|
81
|
+
`;let R=document.createElement("div");R.className="dot",R.textContent=i,R.style.display=e.minimized?"flex":"none";let k=document.createElement("div");k.className="card",k.style.display=e.minimized?"none":"flex",k.innerHTML=`
|
|
82
82
|
<div class="hdr" id="hdr">
|
|
83
83
|
<span style="display:flex;align-items:center;gap:5px;overflow:hidden;min-width:0">
|
|
84
84
|
<span style="overflow:hidden;text-overflow:ellipsis;white-space:nowrap">${e.reviewer}</span>
|
|
85
|
-
<span class="tag">${
|
|
85
|
+
<span class="tag">${n}</span>
|
|
86
86
|
</span>
|
|
87
87
|
<span class="btns">
|
|
88
88
|
<button class="btn" id="mn" title="Minimize">\u2212</button>
|
|
@@ -90,5 +90,5 @@
|
|
|
90
90
|
</span>
|
|
91
91
|
</div>
|
|
92
92
|
<div class="body"><textarea placeholder="Add note\u2026">${e.comment}</textarea></div>
|
|
93
|
-
<div class="foot">${
|
|
94
|
-
`,
|
|
93
|
+
<div class="foot">${O}</div>
|
|
94
|
+
`,N.append(y,R,k);let ye=k.querySelector("#hdr"),oe=!1,ne=0,re=0,ie=0,se=0;function ae(c){d.style.left=Math.max(0,ie+c.pageX-ne)+"px",d.style.top=Math.max(0,se+c.pageY-re)+"px"}function le(){oe=!1,document.removeEventListener("pointermove",ae,!0),document.removeEventListener("pointerup",le,!0);let c=o.find(A=>A.id===e.id);if(!c)return;let g=parseFloat(d.style.left),S=parseFloat(d.style.top),q={xPct:T(g/document.documentElement.scrollWidth),yPct:T(S/document.documentElement.scrollHeight)};d.style.display="none";let X=document.elementFromPoint(g-window.scrollX,S-window.scrollY);if(d.style.display="",X&&X.dataset?.fsHost===void 0){let A=X.getBoundingClientRect();A.width>0&&A.height>0&&(q.anchorSelector=ee(X),q.anchorOffsetXPct=T((g-window.scrollX-A.left)/A.width),q.anchorOffsetYPct=T((S-window.scrollY-A.top)/A.height))}c.position=q,c.updatedAt=new Date().toISOString(),C(o)}ye.addEventListener("pointerdown",c=>{c.stopPropagation(),c.preventDefault(),oe=!0,ne=c.pageX,re=c.pageY,ie=parseFloat(d.style.left),se=parseFloat(d.style.top),v++,d.style.zIndex=String(v),document.addEventListener("pointermove",ae,!0),document.addEventListener("pointerup",le,!0)}),k.querySelector("#mn").addEventListener("click",c=>{c.stopPropagation(),k.style.display="none",R.style.display="flex";let g=o.find(S=>S.id===e.id);g&&(g.minimized=!0,g.updatedAt=new Date().toISOString(),C(o))}),R.addEventListener("click",c=>{c.stopPropagation(),R.style.display="none",k.style.display="flex",v++,d.style.zIndex=String(v);let g=o.find(S=>S.id===e.id);g&&(g.minimized=!1,g.updatedAt=new Date().toISOString(),C(o))}),k.querySelector("#dl").addEventListener("click",c=>{c.stopPropagation(),d.remove();let g=o.findIndex(S=>S.id===e.id);g>=0&&o.splice(g,1),C(o),z()});let B=k.querySelector("textarea");B.addEventListener("input",W(()=>{let c=o.find(g=>g.id===e.id);c&&(c.comment=B.value,c.updatedAt=new Date().toISOString(),C(o))},500)),B.addEventListener("pointerdown",c=>c.stopPropagation()),B.addEventListener("click",c=>c.stopPropagation()),document.documentElement.appendChild(d)}function j(e){if(!r||e.composedPath().some(y=>y.dataset?.fsHost!==void 0))return;e.preventDefault(),e.stopPropagation(),e.stopImmediatePropagation();let n=document.documentElement.scrollWidth,i=document.documentElement.scrollHeight,h=e.pageX-10,O=e.pageY-10,d={xPct:T(h/n),yPct:T(O/i)},$=document.elementFromPoint(e.clientX,e.clientY);if($&&$.dataset?.fsHost===void 0){let y=$.getBoundingClientRect();y.width>0&&y.height>0&&(d.anchorSelector=ee($),d.anchorOffsetXPct=T((e.clientX-10-y.left)/y.width),d.anchorOffsetYPct=T((e.clientY-10-y.top)/y.height))}let _=new Date().toISOString(),N={id:crypto.randomUUID(),reviewer:p,comment:"",color:a,position:d,minimized:!1,rotation:parseFloat((Math.random()*4-2).toFixed(1)),createdAt:_,updatedAt:_};o.push(N),Y(N),C(o),z()}function W(e,t){let n;return(...i)=>{clearTimeout(n),n=setTimeout(()=>e(...i),t)}}function T(e){return Math.round(e*1e4)/1e4}function ee(e){let t=[],n=e;for(;n&&n.tagName!=="HTML";){if(n.id){t.unshift("#"+CSS.escape(n.id));break}let i=n.tagName.toLowerCase(),h=n.parentElement;if(h){let O=n.tagName,d=Array.from(h.children).filter($=>$.tagName===O);t.unshift(d.length>1?`${i}:nth-of-type(${d.indexOf(n)+1})`:i)}else t.unshift(i);if(n=h,t.length>=6)break}return t.join(" > ")}function te(e){let t=e.position;if(t.anchorSelector)try{let n=document.querySelector(t.anchorSelector);if(n){let i=n.getBoundingClientRect();if(i.width>0||i.height>0)return{left:i.left+window.scrollX+(t.anchorOffsetXPct??0)*i.width,top:i.top+window.scrollY+(t.anchorOffsetYPct??0)*i.height}}}catch{}return t.xPct!=null?{left:t.xPct*document.documentElement.scrollWidth,top:t.yPct*document.documentElement.scrollHeight}:{top:t.top??0,left:t.left??0}}function ve(){r&&(r=!1,document.documentElement.classList.remove("fs-mode"),document.removeEventListener("click",j,!0),F.textContent="Start Reviewing",F.className="mbtn off",E.classList.remove("on")),document.querySelectorAll("[data-sticker-id]").forEach(e=>e.remove()),o=G(),o.forEach(Y),z()}window.__feedbackStickers={refresh:ve},o.forEach(Y),z(),window.addEventListener("resize",W(()=>{document.querySelectorAll("[data-sticker-id]").forEach(e=>{let t=o.find(h=>h.id===e.dataset.stickerId);if(!t)return;let{top:n,left:i}=te(t);e.style.top=n+"px",e.style.left=i+"px"})},150))}function Ee(s,r,a){let p=new Blob([s],{type:a}),o=URL.createObjectURL(p);Object.assign(document.createElement("a"),{href:o,download:r}).click(),URL.revokeObjectURL(o)}})();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gridd/feedback-stickers",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.2",
|
|
4
4
|
"description": "Drop-in sticky-note annotation panel for any HTML page. Self-contained IIFE — no framework required.",
|
|
5
5
|
"keywords": ["feedback", "review", "sticky", "annotation", "stickers", "docusaurus"],
|
|
6
6
|
"license": "UNLICENSED",
|