@cychien/ezdesign 0.9.2 → 0.11.0
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 +209 -550
- package/dist/cli.mjs +2640 -655
- package/dist/constants.d.ts +8 -4
- package/dist/extension/g/0.11.0-75c3fbebc3/dialog.js +1 -0
- package/dist/extension/g/0.11.0-75c3fbebc3/media.js +1 -0
- package/dist/extension/g/0.11.0-75c3fbebc3/page.js +44 -0
- package/dist/extension/g/0.11.0-75c3fbebc3/worker.js +57 -0
- package/dist/extension/manifest.json +15 -12
- package/dist/home.css +4706 -0
- package/dist/home.js +440 -0
- package/dist/native-host.mjs +33804 -115
- package/dist/overlay.css +5 -1
- package/dist/overlay.js +73 -22
- package/dist/shell.css +297 -1
- package/dist/shell.js +1230 -358
- package/dist/video-digest.js +16388 -0
- package/dist/vite.mjs +5 -1
- package/package.json +4 -3
- package/skills/ezdesign/SKILL.md +7 -3
- package/skills/ezdesign/reference/start.md +2 -1
- package/dist/extension/g/0.9.2-d9aee83dae/dialog.js +0 -1
- package/dist/extension/g/0.9.2-d9aee83dae/media.js +0 -1
- package/dist/extension/g/0.9.2-d9aee83dae/page.js +0 -39
- package/dist/extension/g/0.9.2-d9aee83dae/worker.js +0 -57
- /package/dist/extension/g/{0.9.2-d9aee83dae → 0.11.0-75c3fbebc3}/dialog.css +0 -0
- /package/dist/extension/g/{0.9.2-d9aee83dae → 0.11.0-75c3fbebc3}/dialog.html +0 -0
- /package/dist/extension/g/{0.9.2-d9aee83dae → 0.11.0-75c3fbebc3}/icon-128.png +0 -0
- /package/dist/extension/g/{0.9.2-d9aee83dae → 0.11.0-75c3fbebc3}/icon-16.png +0 -0
- /package/dist/extension/g/{0.9.2-d9aee83dae → 0.11.0-75c3fbebc3}/icon-32.png +0 -0
- /package/dist/extension/g/{0.9.2-d9aee83dae → 0.11.0-75c3fbebc3}/icon-48.png +0 -0
- /package/dist/extension/g/{0.9.2-d9aee83dae → 0.11.0-75c3fbebc3}/media.html +0 -0
- /package/dist/extension/g/{0.9.2-d9aee83dae → 0.11.0-75c3fbebc3}/setup.css +0 -0
- /package/dist/extension/g/{0.9.2-d9aee83dae → 0.11.0-75c3fbebc3}/setup.html +0 -0
- /package/dist/extension/g/{0.9.2-d9aee83dae → 0.11.0-75c3fbebc3}/setup.js +0 -0
package/dist/vite.mjs
CHANGED
|
@@ -7,6 +7,7 @@ import MagicString from "magic-string";
|
|
|
7
7
|
import { homedir } from "node:os";
|
|
8
8
|
import { join } from "node:path";
|
|
9
9
|
var APP_NAME = "ezdesign";
|
|
10
|
+
var URL_PREFIX = "/__ezdesign";
|
|
10
11
|
var ENV_PREFIX = APP_NAME.toUpperCase();
|
|
11
12
|
var DATA_DIR = process.env[`${ENV_PREFIX}_DATA_DIR`] ?? join(homedir(), `.${APP_NAME}`);
|
|
12
13
|
var SESSIONS_DIR = join(DATA_DIR, "sessions");
|
|
@@ -21,8 +22,11 @@ var NO_UPDATE_CHECK_ENV = `${ENV_PREFIX}_NO_UPDATE_CHECK`;
|
|
|
21
22
|
var DESIGN_HARNESS_ENV = `${ENV_PREFIX}_DESIGN_HARNESS`;
|
|
22
23
|
var API_URL_ENV = `${ENV_PREFIX}_API_URL`;
|
|
23
24
|
var NO_IDLE_STOP_ENV = `${ENV_PREFIX}_NO_IDLE_STOP`;
|
|
25
|
+
var PROJECTS_FILE = join(DATA_DIR, "projects.json");
|
|
26
|
+
var HOME_PATH = `${URL_PREFIX}/home`;
|
|
27
|
+
var LOGIN_ENV_VAR = `${ENV_PREFIX}_LOGIN_ENV`;
|
|
28
|
+
var LOGIN_ENV_CACHE = join(DATA_DIR, "login-env.json");
|
|
24
29
|
var CONTROL_PORT_ENV = `${ENV_PREFIX}_CONTROL_PORT`;
|
|
25
|
-
var MAX_ATTACHMENT_BYTES = 8 * 1024 * 1024;
|
|
26
30
|
var ATTACHMENT_GRACE_MS = 24 * 60 * 6e4;
|
|
27
31
|
var UPDATE_CHECK_TTL_MS = 4 * 60 * 6e4;
|
|
28
32
|
var IDLE_STOP_MS = 30 * 6e4;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cychien/ezdesign",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.11.0",
|
|
4
4
|
"description": "Annotate your live dev app in the browser; feedback flows to your local coding agent, which edits the source. Review, iterate, repeat.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"author": "Justin Chien",
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
"dev:cli": "node scripts/dev-cli.mjs",
|
|
35
35
|
"brand": "node scripts/brand-wordmark.mjs && node --import tsx scripts/brand-assets.mjs",
|
|
36
36
|
"check": "npm run build && npm run typecheck && npm test",
|
|
37
|
-
"typecheck": "tsc --noEmit && tsc -p src/extension --noEmit && tsc -p fixtures/playground --noEmit",
|
|
37
|
+
"typecheck": "tsc --noEmit && tsc -p src/extension --noEmit && tsc -p fixtures/playground --noEmit && tsc -p desktop --noEmit",
|
|
38
38
|
"test": "node scripts/test.mjs",
|
|
39
39
|
"version": "node scripts/sync-skill-version.mjs && git add skills/ezdesign/SKILL.md",
|
|
40
40
|
"prepublishOnly": "npm run check"
|
|
@@ -58,7 +58,6 @@
|
|
|
58
58
|
"dependencies": {
|
|
59
59
|
"@agentclientprotocol/sdk": "^1.4.0",
|
|
60
60
|
"@babel/parser": "^7.26.0",
|
|
61
|
-
"@hugeicons/core-free-icons": "^4.3.5",
|
|
62
61
|
"@modelcontextprotocol/sdk": "^1.30.0",
|
|
63
62
|
"express": "^5.1.0",
|
|
64
63
|
"http-proxy-middleware": "^3.0.3",
|
|
@@ -68,12 +67,14 @@
|
|
|
68
67
|
},
|
|
69
68
|
"devDependencies": {
|
|
70
69
|
"@fontsource/geist-sans": "5.3.0",
|
|
70
|
+
"@hugeicons/core-free-icons": "^4.3.5",
|
|
71
71
|
"@types/express": "^5.0.0",
|
|
72
72
|
"@types/node": "^22.10.0",
|
|
73
73
|
"@types/react": "^19.2.18",
|
|
74
74
|
"@types/react-dom": "^19.2.5",
|
|
75
75
|
"@vitejs/plugin-react": "^4.7.0",
|
|
76
76
|
"esbuild": "^0.25.0",
|
|
77
|
+
"mediabunny": "1.62.1",
|
|
77
78
|
"opentype.js": "1.3.4",
|
|
78
79
|
"react": "^19.2.8",
|
|
79
80
|
"react-dom": "^19.2.8",
|
package/skills/ezdesign/SKILL.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
name: ezdesign
|
|
3
3
|
description: Open an ezdesign review session on a running web page. The user annotates the page in the browser, and each batch reaches the coding agent with exact source locations. Use when the user invokes /ezdesign, or asks to review, annotate or give visual feedback on a running page, or to explore designs on a canvas.
|
|
4
4
|
metadata:
|
|
5
|
-
version: 0.
|
|
5
|
+
version: 0.11.0
|
|
6
6
|
---
|
|
7
7
|
|
|
8
8
|
# ezdesign
|
|
@@ -15,7 +15,8 @@ it, is that request: open a review on the project's running dev server.
|
|
|
15
15
|
The daemon has done the routing: its prompt says whether the turn is a feedback batch or an
|
|
16
16
|
explore round, and what to do with it. Do not route again. A batch carries the page's `url`, the
|
|
17
17
|
annotated `items` with their `anchor` (source `file:line`, selector, viewport), `references`, and
|
|
18
|
-
`attachments`.
|
|
18
|
+
`attachments`. A video attachment carries `video`: never open its `path`; read what `video.read`
|
|
19
|
+
says, which points you at contact sheets of its frames, each labelled with its time. An explore adds one element's capture - its markup, computed styles, slot and the
|
|
19
20
|
page's tokens - and takes each variant back through a tool, editing no file.
|
|
20
21
|
|
|
21
22
|
## Canvases
|
|
@@ -32,4 +33,7 @@ the user sent the batch from and which canvases exist.
|
|
|
32
33
|
- An item whose `anchor.frame` is set was made inside a frame: `anchor.source` is a line of that
|
|
33
34
|
frame's file under `.ezdesign/canvases/`. Change a frame with `update_frame` (pass the
|
|
34
35
|
`expectedHash` you last read) or by editing its file.
|
|
35
|
-
-
|
|
36
|
+
- When a change makes a frame's content taller or shorter, pass `height` to `update_frame`; the
|
|
37
|
+
frames below it move down to make room. Never remove a frame and add it again to resize it: that
|
|
38
|
+
loses its place and the annotations made on it. Its width stays the viewport it was added at.
|
|
39
|
+
- Never edit `canvas.json` or `layout.json` by hand. Where a frame sits is the user's.
|
|
@@ -30,7 +30,8 @@ the user did not provide an ACP command, ask them which ACP agent to use.
|
|
|
30
30
|
|
|
31
31
|
1. Make sure the dev server is running. Never start a second instance when one is already up. If
|
|
32
32
|
the user only wants to explore designs on a canvas, there may be no dev server: run the command
|
|
33
|
-
below without the url and the review opens on the project's canvases
|
|
33
|
+
below without the url and the review opens with no app attached: on the project's canvases, or
|
|
34
|
+
on an App tab where the user can start the dev server themselves.
|
|
34
35
|
2. From the project root, run:
|
|
35
36
|
|
|
36
37
|
```sh
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
"use strict";(()=>{function B(e,t,n){let r=n.width/t.width,o=n.height/t.height,c=(ae,oe)=>Math.min(oe,Math.max(0,ae)),s=c(Math.floor(e.x*r+1e-6),n.width),m=c(Math.floor(e.y*o+1e-6),n.height),ie=c(Math.ceil((e.x+e.width)*r-1e-6),n.width),re=c(Math.ceil((e.y+e.height)*o-1e-6),n.height);return{x:s,y:m,width:ie-s,height:re-m}}var K="dialog:";function I(e){let t=e.normalize("NFC").trim().replace(/\s+/g," ");return t===""||t.length>64||/[,,]/.test(t)?null:se(t)}function se(e){let[t="",n=""]=e;return n!==n.toLowerCase()?e:t.toLowerCase()+e.slice(t.length)}function y(e){return e.normalize("NFKC").trim().replace(/\s+/g," ").toLowerCase()}var W={locked:[],chips:[],draft:"",highlighted:null},le=/[,,]/;function T(e){return[...e.locked,...e.chips]}function M(e,t){let n=I(t);return n===null||T(e).some(r=>y(r)===y(n))?e:{...e,chips:[...e.chips,n]}}function p(e,t,n){switch(t.type){case"input":{let r=t.value.split(le),o=r.pop()??"";return{...r.reduce(M,e),draft:o,highlighted:null}}case"enter":{let r=e.highlighted===null?e.draft:n[e.highlighted];return{...M(e,r??e.draft),draft:"",highlighted:null}}case"backspace":return e.draft===""&&e.chips.length?{...e,chips:e.chips.slice(0,-1),highlighted:null}:e;case"arrow":{if(n.length===0)return{...e,highlighted:null};let r=e.highlighted??(t.delta===1?-1:n.length);return{...e,highlighted:(r+t.delta+n.length)%n.length}}case"pick":return{...M(e,t.name),draft:"",highlighted:null};case"remove":return{...e,chips:e.chips.filter((r,o)=>o!==t.index)};case"lock":{let r=[];for(let c of t.names){let s=I(c);s&&!r.some(m=>y(m)===y(s))&&r.push(s)}let o=e.chips.filter(c=>!r.some(s=>y(s)===y(c)));return{...e,locked:r,chips:o}}}}var ce=location.hash.slice(1),A=window.top===window;document.documentElement.dataset.where=A?"window":"page";var N=chrome.runtime.connect({name:K+ce}),h=e=>N.postMessage(e),X=()=>performance.timeOrigin+performance.now(),j="\u53EF\u7559\u7A7A\u6216\u591A\u500B\uFF0C\u4EE5 Enter \u6216\u9017\u865F\u9694\u958B",de="\u4E32\u6D41\u5F71\u7247\u53EA\u6703\u5132\u5B58\u9023\u7D50\u3001\u76EE\u524D\u6642\u9593\u548C\u756B\u9762",pe="\u5F71\u7247\u8D85\u904E 200 MB\uFF0C\u53EA\u6703\u5132\u5B58\u9023\u7D50\u548C\u756B\u9762";function a(e,t={},...n){let r=document.createElement(e);for(let[o,c]of Object.entries(t))r.setAttribute(o,c);return r.append(...n),r}var S=a("div",{class:"overlay"}),O=a("section",{class:"card",role:"dialog","aria-modal":"true","aria-labelledby":"ez-title"}),ue=a("h1",{id:"ez-title"},"\u5132\u5B58\u81F3 ezdesign"),R=a("p",{class:"source"}),u=a("figure",{class:"preview",hidden:""}),U=a("span",{class:"chips"}),l=a("input",{type:"text",role:"combobox","aria-label":"\u6A19\u7C64","aria-autocomplete":"list","aria-expanded":"false","aria-controls":"ez-suggestions","data-testid":"ez-capture-tag-input",placeholder:j,autocomplete:"off",spellcheck:"false"}),ge=a("div",{class:"tags"},U,l),v=a("ul",{id:"ez-suggestions",role:"listbox","aria-label":"\u6A19\u7C64\u5EFA\u8B70","data-testid":"ez-capture-tag-suggestions",hidden:""}),L=a("textarea",{"aria-label":"\u70BA\u4EC0\u9EBC\u597D","data-testid":"ez-capture-note",rows:"3",placeholder:"\u53EF\u7559\u7A7A"}),P=a("p",{class:"status",role:"status","data-testid":"ez-capture-status"}),F=a("code"),k=a("button",{type:"button",class:"quiet"},"\u8907\u88FD"),Q=a("div",{class:"install","data-testid":"ez-capture-install",hidden:""},F,k),g=a("button",{type:"button",class:"grant",hidden:""}),Y=a("button",{type:"button","data-testid":"ez-capture-cancel"},"\u53D6\u6D88"),x=a("button",{type:"button",class:"primary","data-testid":"ez-capture-save"},"\u5132\u5B58"),$=a("header",{},ue,R);O.append(...A?[$,u]:[u,$],a("div",{class:"field"},a("span",{class:"label","aria-hidden":"true"},"\u6A19\u7C64"),a("div",{class:"combo"},ge,v)),a("div",{class:"field"},a("span",{class:"label","aria-hidden":"true"},"\u70BA\u4EC0\u9EBC\u597D"),L),P,Q,g,a("footer",{},Y,x));S.append(O);document.body.append(S);var _=null,i=W,d=[],q=!1,E=!1,C=null,w=null;function J(){if(C===null||w===null||w.nonce!==C)return;let{bitmap:e}=w;C=null,w=null,ne(e,e.width,e.height)}function f(){let e=i.locked.map(n=>a("span",{class:"chip locked",title:"\u5DF2\u6536\u85CF\u904E\u7684\u6A19\u7C64"},n)),t=i.chips.map((n,r)=>{let o=a("button",{type:"button",class:"chip","aria-label":`\u79FB\u9664\u6A19\u7C64 ${n}`},a("span",{},n),a("span",{class:"x","aria-hidden":"true"},"\xD7"));return o.addEventListener("click",()=>{i=p(i,{type:"remove",index:r},[]),f(),l.focus(),Z()}),o});U.replaceChildren(...e,...t),l.placeholder=e.length+t.length?"":j,l.value!==i.draft&&(l.value=i.draft),b()}function b(){let e=i.draft.trim()!==""&&d.length>0;v.hidden=!e,l.setAttribute("aria-expanded",String(e)),v.replaceChildren(...d.map((t,n)=>{let r=a("li",{role:"option",id:`ez-suggestion-${n}`,"aria-selected":String(n===i.highlighted)},a("span",{class:"name"},t.name),a("span",{class:"uses"},String(t.uses)));return n===i.highlighted&&(r.dataset.active=""),r.addEventListener("mousedown",o=>{o.preventDefault(),ee(t.name)}),r})),e&&i.highlighted!==null?l.setAttribute("aria-activedescendant",`ez-suggestion-${i.highlighted}`):l.removeAttribute("aria-activedescendant")}function Z(){if(i.draft.trim()===""){d=[],b();return}h({type:"suggest",prefix:i.draft.trim(),exclude:T(i)})}function ee(e){i=p(i,{type:"pick",name:e},[]),d=[],f(),l.focus()}var z=()=>d.map(e=>e.name);l.addEventListener("input",()=>{let e=i.chips.length;i=p(i,{type:"input",value:l.value},z()),i.chips.length!==e&&(d=[]),f(),Z()});l.addEventListener("keydown",e=>{e.isComposing||((e.key==="ArrowDown"||e.key==="ArrowUp")&&d.length?(e.preventDefault(),i=p(i,{type:"arrow",delta:e.key==="ArrowDown"?1:-1},z()),b()):e.key==="Enter"&&!(e.metaKey||e.ctrlKey)?(e.preventDefault(),i=p(i,{type:"enter"},z()),d=[],f()):e.key==="Tab"&&i.highlighted!==null&&!v.hidden?(e.preventDefault(),ee(d[i.highlighted].name)):e.key==="Backspace"&&l.value===""&&(i=p(i,{type:"backspace"},z()),f()))});l.addEventListener("blur",()=>{d=[],b()});function te(){E||!_||_.confirm!=="enabled"||(i.draft.trim()&&(i=p(i,{type:"enter"},[])),i={...i,highlighted:null},f(),h({type:"confirm",tags:T(i),note:L.value}))}function G(e){if(E)return;E=!0,document.documentElement.dataset.leaving=e,A||window.parent.postMessage({type:"ez-capture-leaving",how:e},"*");let t=matchMedia("(prefers-reduced-motion: reduce)").matches,n=()=>h({type:"closed"});t?setTimeout(n,120):O.addEventListener("animationend",n,{once:!0})}function H(){E||(h({type:"cancel"}),G("cancelled"))}x.addEventListener("click",te);Y.addEventListener("click",H);S.addEventListener("mousedown",e=>{e.target===S&&H()});document.addEventListener("keydown",e=>{e.key==="Escape"?(e.preventDefault(),v.hidden?H():(d=[],b())):e.key==="Enter"&&(e.metaKey||e.ctrlKey)&&(e.preventDefault(),te())});k.addEventListener("click",()=>{navigator.clipboard.writeText(F.textContent??"").then(()=>{k.textContent="\u5DF2\u8907\u88FD",setTimeout(()=>k.textContent="\u8907\u88FD",1500)})});g.addEventListener("click",()=>{let e=g.dataset.origin;e&&(g.disabled=!0,chrome.permissions.request({origins:[`${e}/*`]}).then(t=>h({type:t?"granted":"denied",origin:e}),()=>h({type:"denied",origin:e})))});function he(e){switch(e.host.type){case"missing":return"\u9084\u6C92\u6709\u5B89\u88DD ezdesign host\uFF0C\u5728\u7D42\u7AEF\u6A5F\u57F7\u884C\u9019\u884C\u6307\u4EE4\u5F8C\u518D\u5B58\u4E00\u6B21\uFF1A";case"incompatible":return e.host.older==="host"?"ezdesign host \u7248\u672C\u592A\u820A\uFF0C\u66F4\u65B0\u5F8C\u518D\u5B58\u4E00\u6B21\uFF1A":"\u9019\u500B\u64F4\u5145\u529F\u80FD\u7248\u672C\u592A\u820A\uFF0C\u66F4\u65B0\u5F8C\u518D\u5B58\u4E00\u6B21\uFF1A";case"broken":return e.host.message;default:return null}}function me(e){_=e,R.textContent=e.page.title||e.page.url,R.title=e.page.url,e.duplicate&&!q&&(q=!0,i=p(i,{type:"lock",names:e.duplicate.tags},[]),L.value===""&&(L.value=e.duplicate.note),f());let t=he(e),n=e.host.type==="missing"||e.host.type==="incompatible"?e.host.installCommand:null;Q.hidden=n===null,F.textContent=n??"";let r=e.staging.type==="needs-permission"?e.staging.origin:null;g.hidden=r===null,r&&(g.dataset.origin=r,g.textContent=`\u5141\u8A31\u8B80\u53D6 ${r}`,g.disabled=!1);let o=t??e.error??(e.staging.type==="failed"?e.staging.message:null)??(r?"\u9019\u5F35\u5716\u7247\u9700\u8981\u4F60\u5728\u9019\u500B\u7DB2\u7AD9\u7684\u767B\u5165\u72C0\u614B\u624D\u80FD\u8B80\u53D6\u3002":null)??(e.notice==="stream-link"?de:e.notice==="too-large"?pe:null)??(e.duplicate?"\u5DF2\u6536\u85CF\u904E":"");P.textContent=o,P.dataset.tone=t||e.error||e.staging.type==="failed"?"error":"info",x.disabled=e.confirm!=="enabled",x.textContent=e.confirm==="saving"?"\u5132\u5B58\u4E2D\u2026":e.confirm==="saved"?"\u5DF2\u5132\u5B58":"\u5132\u5B58",x.setAttribute("aria-busy",String(e.confirm==="saving")),e.confirm==="saved"&&G("saved")}var ye="min(300px, max(96px, 100vh - 400px))",fe=1200;function V(e,t){e.style.aspectRatio=`${t.width} / ${t.height}`,e.style.width=`min(100%, ${t.width}px, calc(${ye} * ${t.width/t.height}))`}function D(e){if(!e||u.childElementCount)return;let t=a("div",{class:"slot","aria-hidden":"true"});V(t,e),u.replaceChildren(t),u.hidden=!1}function ne(e,t,n,r){let o=r??{x:0,y:0,width:t,height:n},c=Math.min(1,fe/Math.max(o.width,o.height)),s=a("canvas",{"data-testid":"ez-capture-preview",role:"img","aria-label":"\u9810\u89BD"});V(s,o),s.width=Math.max(1,Math.round(o.width*c)),s.height=Math.max(1,Math.round(o.height*c));let m=s.getContext("2d");m.imageSmoothingQuality="high",m.drawImage(e,o.x,o.y,o.width,o.height,0,0,s.width,s.height),u.replaceChildren(s),u.hidden=!1,requestAnimationFrame(()=>h({type:"preview-shown",at:X()}))}async function be(e){switch(e.type){case"bitmap":D(e.size),C=e.nonce,J();return;case"screenshot":{D(e.rect??e.viewport);let t=new Image;t.src=e.dataUrl,await t.decode();let n={width:t.naturalWidth,height:t.naturalHeight};ne(t,n.width,n.height,e.rect?B(e.rect,e.viewport,n):void 0);return}case"url":{D(e.size);let t=a("img",{"data-testid":"ez-capture-preview",alt:"\u9810\u89BD",src:e.src});e.size&&V(t,e.size),await t.decode().catch(()=>{}),u.replaceChildren(t),u.hidden=!1,requestAnimationFrame(()=>h({type:"preview-shown",at:X()}));return}case"none":return}}window.addEventListener("message",e=>{let t=e.data;e.source!==window.parent||t?.type!=="ez-capture-preview"||(w=t,J())});N.onMessage.addListener(e=>{let t=e;t.type==="preview"?be(t.preview):t.type==="view"?me(t.view):t.type==="suggestions"&&t.prefix===i.draft.trim()&&(d=t.tags,i={...i,highlighted:null},b())});N.onDisconnect.addListener(()=>G("cancelled"));window.addEventListener("focus",()=>{!E&&(document.activeElement===document.body||document.activeElement===null)&&l.focus()});l.focus();})();
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
"use strict";(()=>{function l(t){let r="";for(let e=0;e<t.length;e+=32768)r+=String.fromCharCode(...t.subarray(e,e+32768));return btoa(r)}function w(t){let r=atob(t),e=new Uint8Array(r.length);for(let n=0;n<r.length;n++)e[n]=r.charCodeAt(n);return e}function b(t,r,e){let n=e.width/r.width,a=e.height/r.height,i=(s,g)=>Math.min(g,Math.max(0,s)),o=i(Math.floor(t.x*n+1e-6),e.width),c=i(Math.floor(t.y*a+1e-6),e.height),h=i(Math.ceil((t.x+t.width)*n-1e-6),e.width),u=i(Math.ceil((t.y+t.height)*a-1e-6),e.height);return{x:o,y:c,width:h-o,height:u-c}}function p(t,r){let e=Math.min(1,400/Math.max(t,r));return{width:Math.max(1,Math.round(t*e)),height:Math.max(1,Math.round(r*e))}}var f="image/webp",x=.8;async function y(t,r){let e=p(r.width,r.height),n=t,{width:a,height:i}=r;for(;a/2>=e.width*2&&i/2>=e.height*2;){a=Math.round(a/2),i=Math.round(i/2);let u=new OffscreenCanvas(a,i),s=u.getContext("2d");s.imageSmoothingQuality="high",s.drawImage(n,0,0,a,i),n=u}let o=new OffscreenCanvas(e.width,e.height),c=o.getContext("2d");c.imageSmoothingQuality="high",c.drawImage(n,0,0,e.width,e.height);let h=await o.convertToBlob({type:f,quality:x});if(h.type!==f)throw new Error(`this browser encodes ${h.type}, not WebP`);return{webp:new Uint8Array(await h.arrayBuffer()),...e,source:{...r}}}async function d(t,r){let e=await y(t,r);return{...e,webp:l(e.webp)}}var m=new Map;async function E(t){let r=new Blob(t),e=await createImageBitmap(r).catch(()=>null);if(e)try{return await d(e,{width:e.width,height:e.height})}finally{e.close()}let n=URL.createObjectURL(new Blob(t,{type:"image/svg+xml"}));try{let a=new Image;return await new Promise((i,o)=>{a.onload=()=>i(),a.onerror=()=>o(new Error("cannot decode")),a.src=n}),!a.naturalWidth||!a.naturalHeight?null:await d(a,{width:a.naturalWidth,height:a.naturalHeight})}catch{return null}finally{URL.revokeObjectURL(n)}}async function v(t,r){let e=URL.createObjectURL(new Blob(t)),n=document.createElement("video");n.muted=!0,n.preload="auto";try{let a=i=>new Promise((o,c)=>{n.addEventListener(i,()=>o(),{once:!0}),n.addEventListener("error",()=>c(new Error("cannot decode the video")),{once:!0})});return n.src=e,await a("loadeddata"),n.currentTime=Math.min(r,Math.max(0,n.duration-.001)),await a("seeked"),n.videoWidth?await d(n,{width:n.videoWidth,height:n.videoHeight}):null}catch{return null}finally{n.removeAttribute("src"),n.load(),URL.revokeObjectURL(e)}}async function S(t){let r=await(await fetch(t.screenshot)).blob(),e=await createImageBitmap(r),n={width:e.width,height:e.height},a=t.rect?b(t.rect,t.viewport,n):{x:0,y:0,...n};if(a.width<1||a.height<1)return{original:null,thumb:null};let i=await createImageBitmap(e,a.x,a.y,a.width,a.height),o={width:a.width,height:a.height},c=async()=>{if(!t.original)return null;let s=new OffscreenCanvas(o.width,o.height);s.getContext("2d").drawImage(i,0,0);let g=await s.convertToBlob({type:"image/png"});return{png:l(new Uint8Array(await g.arrayBuffer())),size:o}},[h,u]=await Promise.all([d(i,o),c()]);return{original:u,thumb:h}}async function L(t){switch(t.type){case"feed":return m.set(t.job,[...m.get(t.job)??[],w(t.data)]),{};case"thumbnail":{let r=m.get(t.job)??[];return m.delete(t.job),{thumb:t.at===null?await E(r):await v(r,t.at)}}case"crop":return S(t);case"drop":return m.delete(t.job),{}}}function M(t){return t.type==="thumbnail"?{thumb:null}:t.type==="crop"?{original:null,thumb:null}:{}}chrome.runtime.onMessage.addListener((t,r,e)=>{let n=t;if(!(n?.to!=="media"||r.id!==chrome.runtime.id))return L(n).then(e,()=>e(M(n))),!0});})();
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
"use strict";(()=>{function b(e){let n="";for(let o=0;o<e.length;o+=32768)n+=String.fromCharCode(...e.subarray(o,o+32768));return btoa(n)}function H(e,n){let o=Math.min(1,400/Math.max(e,n));return{width:Math.max(1,Math.round(e*o)),height:Math.max(1,Math.round(n*o))}}var R="image/webp",Q=.8;async function B(e,n){let o=H(n.width,n.height),t=e,{width:r,height:a}=n;for(;r/2>=o.width*2&&a/2>=o.height*2;){r=Math.round(r/2),a=Math.round(a/2);let m=new OffscreenCanvas(r,a),h=m.getContext("2d");h.imageSmoothingQuality="high",h.drawImage(t,0,0,r,a),t=m}let u=new OffscreenCanvas(o.width,o.height),d=u.getContext("2d");d.imageSmoothingQuality="high",d.drawImage(t,0,0,o.width,o.height);let c=await u.convertToBlob({type:R,quality:Q});if(c.type!==R)throw new Error(`this browser encodes ${c.type}, not WebP`);return{webp:new Uint8Array(await c.arrayBuffer()),...o,source:{...n}}}async function N(e,n){let o=await B(e,n);return{...o,webp:b(o.webp)}}async function _(e,n){let o=new OffscreenCanvas(n.width,n.height);o.getContext("2d").drawImage(e,0,0,n.width,n.height);let t=await o.convertToBlob({type:"image/png"});return b(new Uint8Array(await t.arrayBuffer()))}var M=null;function J(e){let n=[e.currentSrc,e.getAttribute("src")?e.src:""];return e instanceof HTMLVideoElement&&n.push(...[...e.querySelectorAll("source")].map(o=>o.src)),n.filter(Boolean)}function z(e){let n=e.getBoundingClientRect(),o=Math.max(0,Math.min(n.right,innerWidth)-Math.max(n.left,0)),t=Math.max(0,Math.min(n.bottom,innerHeight)-Math.max(n.top,0));return o*t}function Z(e,n){let t=[...document.querySelectorAll(n==="image"?"img":"video")].filter(r=>J(r).includes(e));return t.length<=1?t[0]??null:t.find(r=>r.matches(":hover"))??t.sort((r,a)=>z(a)-z(r))[0]}function ee(e){let n=e.getBoundingClientRect(),o=Math.max(0,n.left),t=Math.max(0,n.top),r=Math.min(innerWidth,n.right)-o,a=Math.min(innerHeight,n.bottom)-t;return r>0&&a>0?{x:o,y:t,width:r,height:a}:null}async function te(e,n){if(e.readyState<HTMLMediaElement.HAVE_CURRENT_DATA||!e.videoWidth)return{type:"empty"};if(e.mediaKeys)return{type:"protected"};let o={width:e.videoWidth,height:e.videoHeight};try{let[t,r]=await Promise.all([N(e,o),n?_(e,o):null]);return{type:"encoded",thumb:t,png:r}}catch(t){if(t.name==="SecurityError")return{type:"tainted"};throw t}}async function D(e,n,o){let t=Z(e,n);M=t;let r={width:innerWidth,height:innerHeight};if(!t)return{found:!1,viewport:r,rect:null,natural:null,video:null};let a=t instanceof HTMLVideoElement?{width:t.videoWidth,height:t.videoHeight}:{width:t.naturalWidth,height:t.naturalHeight};return{found:!0,viewport:r,rect:ee(t),natural:a.width&&a.height?a:null,video:t instanceof HTMLVideoElement?{currentTime:t.currentTime,frame:await te(t,o)}:null}}function O(){return M?.isConnected?M:null}async function U(e){try{return b(new Uint8Array(await(await fetch(e)).arrayBuffer()))}catch{return null}}var ne=`
|
|
2
|
-
:host { all: initial; }
|
|
3
|
-
.pill {
|
|
4
|
-
position: fixed; top: 16px; left: 50%; z-index: 2147483647;
|
|
5
|
-
display: flex; align-items: center; gap: 6px;
|
|
6
|
-
padding: 6px 12px 6px 9px; border-radius: 8px; color: #fff; pointer-events: none;
|
|
7
|
-
background: oklch(0% 0 0 / 0.78); backdrop-filter: blur(16px) saturate(1.6);
|
|
8
|
-
box-shadow: inset 0 0 0 1px rgb(255 255 255 / 0.1), 0 4px 16px oklch(0% 0 0 / 0.16);
|
|
9
|
-
font: 500 12px/1.5 -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Noto Sans TC', sans-serif;
|
|
10
|
-
transform: translateX(-50%);
|
|
11
|
-
animation: in 0.22s cubic-bezier(0.23, 1, 0.32, 1) both;
|
|
12
|
-
}
|
|
13
|
-
.pill[data-leaving] { animation: out 0.18s cubic-bezier(0.23, 1, 0.32, 1) both; }
|
|
14
|
-
svg { flex-shrink: 0; }
|
|
15
|
-
@keyframes in { from { opacity: 0; transform: translate(-50%, -6px) scale(0.96); } }
|
|
16
|
-
@keyframes out { to { opacity: 0; } }
|
|
17
|
-
@media (prefers-reduced-motion: reduce) {
|
|
18
|
-
@keyframes in { from { opacity: 0; } }
|
|
19
|
-
}
|
|
20
|
-
`,G="http://www.w3.org/2000/svg";function oe(){let e=document.createElementNS(G,"svg");for(let[o,t]of Object.entries({width:"14",height:"14",viewBox:"0 0 24 24",fill:"none","aria-hidden":"true"}))e.setAttribute(o,t);let n=document.createElementNS(G,"path");for(let[o,t]of Object.entries({d:"M5 12.5 10 17.5 19 7",stroke:"currentColor","stroke-width":"2.2","stroke-linecap":"round","stroke-linejoin":"round"}))n.setAttribute(o,t);return e.append(n),e}var l=null,W=()=>new Promise(e=>requestAnimationFrame(e));function F(){l&&(clearTimeout(l.timer),l.host.remove());let e=document.createElement("div");e.setAttribute("data-ez-capture-saved",""),e.style.cssText="all: initial; position: fixed; z-index: 2147483647";let n=e.attachShadow({mode:"closed"}),o=document.createElement("style");o.textContent=ne;let t=document.createElement("div");t.className="pill",t.setAttribute("role","status");let r=document.createElement("span");r.textContent="\u5DF2\u5132\u5B58",t.append(oe(),r),n.append(o,t),document.documentElement.append(e);let a=setTimeout(()=>{t.dataset.leaving="",t.addEventListener("animationend",()=>{e.remove(),l?.host===e&&(l=null)},{once:!0})},1600);l={host:e,timer:a}}async function S(){l&&(clearTimeout(l.timer),l.host.remove(),l=null,await W(),await W())}var A=new Map,re=["position: fixed","inset: 0","width: 100vw","height: 100vh","margin: 0","padding: 0","border: 0","background: transparent","color-scheme: light","backdrop-filter: blur(0px)","transition: backdrop-filter 0.22s cubic-bezier(0.23, 1, 0.32, 1)","z-index: 2147483647"].join("; "),ie="blur(4px)";async function K(e){let n=document.createElement("div");n.setAttribute("data-ez-capture",""),n.style.cssText="all: initial; position: fixed; inset: 0; z-index: 2147483647";let o=n.attachShadow({mode:"closed"}),t=document.createElement("iframe");t.setAttribute("style",re),t.setAttribute("allow","clipboard-write"),t.src=chrome.runtime.getURL(e.dialogPath),o.append(t);let r=new Promise(c=>{t.addEventListener("load",()=>c(!0),{once:!0}),t.addEventListener("error",()=>c(!1),{once:!0})}),a=new AbortController;if(document.documentElement.append(n),A.set(e.captureId,{host:n,listening:a}),!await r||!t.contentWindow)return L(e.captureId),{mounted:!1,handedOff:!1};t.focus(),requestAnimationFrame(()=>t.style.backdropFilter=ie),addEventListener("message",c=>{let m=c.data;c.source!==t.contentWindow||m?.type!=="ez-capture-leaving"||(t.style.backdropFilter="blur(0px)",m.how==="saved"&&F())},{signal:a.signal});let u=e.bitmap?O():null,d=u&&await createImageBitmap(u).catch(()=>null);if(!d)return{mounted:!0,handedOff:!1};try{let c={type:"ez-capture-preview",nonce:e.nonce,bitmap:d};return t.contentWindow.postMessage(c,"*",[d]),{mounted:!0,handedOff:!0}}catch{return d.close(),{mounted:!0,handedOff:!1}}}function L(e){let n=A.get(e);n?.listening.abort(),n?.host.remove(),A.delete(e)}function T(e,n){return{x:Math.round(Math.min(e.x,n.x)),y:Math.round(Math.min(e.y,n.y)),width:Math.round(Math.abs(n.x-e.x)),height:Math.round(Math.abs(n.y-e.y))}}function C(e){return e.width>=8||e.height>=8}var ae="#e56d41",se=`
|
|
21
|
-
:host { all: initial; }
|
|
22
|
-
.layer { position: fixed; inset: 0; cursor: crosshair; touch-action: none; }
|
|
23
|
-
.shade { position: fixed; background: oklch(0% 0 0 / 0.35); pointer-events: none; }
|
|
24
|
-
.box { position: fixed; pointer-events: none; outline: 1.5px dashed ${ae}; outline-offset: -1px; }
|
|
25
|
-
.size {
|
|
26
|
-
position: fixed; pointer-events: none; padding: 2px 6px; border-radius: 4px;
|
|
27
|
-
background: #171717; color: #fff; white-space: nowrap;
|
|
28
|
-
font: 500 11px/1.5 -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
|
|
29
|
-
font-variant-numeric: tabular-nums;
|
|
30
|
-
}
|
|
31
|
-
.hint {
|
|
32
|
-
position: fixed; top: 16px; left: 50%; transform: translateX(-50%); pointer-events: none;
|
|
33
|
-
padding: 6px 12px; border-radius: 8px; color: #fff;
|
|
34
|
-
background: oklch(0% 0 0 / 0.78); backdrop-filter: blur(16px) saturate(1.6);
|
|
35
|
-
box-shadow: inset 0 0 0 1px rgb(255 255 255 / 0.1), 0 4px 16px oklch(0% 0 0 / 0.16);
|
|
36
|
-
font: 500 12px/1.5 -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Noto Sans TC', sans-serif;
|
|
37
|
-
}
|
|
38
|
-
[hidden] { display: none; }
|
|
39
|
-
`,ce=()=>performance.timeOrigin+performance.now(),V=()=>new Promise(e=>requestAnimationFrame(e));function w(e,n,o,t,r){e.style.left=`${n}px`,e.style.top=`${o}px`,e.style.width=`${Math.max(0,t)}px`,e.style.height=`${Math.max(0,r)}px`}function j(){let e=document.createElement("div");e.setAttribute("data-ez-capture",""),e.style.cssText="all: initial; position: fixed; inset: 0; z-index: 2147483647";let n=e.attachShadow({mode:"closed"}),o=document.createElement("style");o.textContent=se;let t=document.createElement("div");t.className="layer";let r=()=>{let x=document.createElement("div");return x.className="shade",x.hidden=!0,x},[a,u,d,c]=[r(),r(),r(),r()],m=[a,u,d,c],h=document.createElement("div");h.className="box",h.hidden=!0;let p=document.createElement("div");p.className="size",p.hidden=!0;let g=document.createElement("div");return g.className="hint",g.textContent="\u62D6\u66F3\u6846\u51FA\u8981\u5B58\u7684\u5340\u57DF\uFF0CEsc \u53D6\u6D88",n.append(o,t,...m,h,p,g),document.documentElement.append(e),new Promise(x=>{let y=null,P=!1,q=s=>{let i=T(y,s),f=C(i);for(let X of m)X.hidden=!f;if(h.hidden=p.hidden=!f,g.hidden=f||g.hidden,!f)return;w(a,0,0,innerWidth,i.y),w(u,0,i.y+i.height,innerWidth,innerHeight-i.y-i.height),w(d,0,i.y,i.x,i.height),w(c,i.x+i.width,i.y,innerWidth-i.x-i.width,i.height),w(h,i.x,i.y,i.width,i.height),p.textContent=`${i.width} \xD7 ${i.height}`;let E=i.y+i.height+28<innerHeight;p.style.left=`${i.x}px`,p.style.top=`${E?i.y+i.height+6:Math.max(0,i.y-26)}px`},k=async s=>{P||(P=!0,removeEventListener("keydown",I,!0),removeEventListener("wheel",v,!0),removeEventListener("touchmove",v,!0),e.remove(),await V(),await V(),x(s))},I=s=>{s.key==="Escape"&&(s.preventDefault(),s.stopPropagation(),k({type:"cancelled"}))},v=s=>s.preventDefault();t.addEventListener("pointerdown",s=>{s.button===0&&(s.preventDefault(),t.setPointerCapture(s.pointerId),y={x:s.clientX,y:s.clientY})}),t.addEventListener("pointermove",s=>{y&&q({x:s.clientX,y:s.clientY})}),t.addEventListener("pointerup",s=>{if(!y)return;let i=ce(),f=T(y,{x:s.clientX,y:s.clientY}),E={width:innerWidth,height:innerHeight};k(C(f)?{type:"rect",rect:f,viewport:E,pickedAt:i}:{type:"viewport",viewport:E,pickedAt:i})}),addEventListener("keydown",I,!0),addEventListener("wheel",v,{capture:!0,passive:!1}),addEventListener("touchmove",v,{capture:!0,passive:!1})})}var $=Symbol.for("ezdesign.capture.page-agent"),de={"select-region":()=>S().then(j),inspect:e=>S().then(()=>D(e.srcUrl,e.mediaType,e.fullFrame)),read:async e=>({data:await U(e.url)}),present:e=>K(e),dismiss:async e=>(L(e.captureId),{})},Y=globalThis;Y[$]||(Y[$]=!0,chrome.runtime.onMessage.addListener((e,n,o)=>{let t=e;if(t?.to!=="page"||n.id!==chrome.runtime.id)return;let r=de[t.type];return r(t).then(o,a=>o({error:String(a)})),!0}));})();
|