@cychien/ezdesign 0.8.1 → 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.
@@ -3,25 +3,47 @@ export declare const NPM_PACKAGE = "@cychien/ezdesign";
3
3
  export declare const URL_PREFIX = "/__ezdesign";
4
4
  export declare const DATA_DIR: string;
5
5
  export declare const SESSIONS_DIR: string;
6
+ /** Where `(origin, project)` directories go once folded into project sessions:
7
+ * moved, never deleted, so a downgrade or a bad merge can be undone by hand. */
8
+ export declare const LEGACY_SESSIONS_DIR: string;
6
9
  export declare const REGISTRY_FILE: string;
7
10
  export declare const DAEMON_LOG: string;
8
11
  /** Where a self-updating daemon installs the version it hands over to. */
9
12
  export declare const VERSIONS_DIR: string;
10
13
  export declare const UPDATE_CHECK_FILE: string;
14
+ export declare const libraryDir: (dataDir?: string) => string;
15
+ /** The data dir of the capture side: the library the shell shows, and the host
16
+ * and extension folder it installs. Set, it is outside the data dir: a dev
17
+ * daemon keeps its sessions apart from the real ones, but the extension saves
18
+ * into the real library, and that is the one worth browsing. */
19
+ export declare const libraryHome: (env?: NodeJS.ProcessEnv) => string;
20
+ export declare const nativeHostDir: (dataDir?: string) => string;
21
+ export declare const installedExtensionDir: (dataDir?: string) => string;
11
22
  export declare const NO_UPDATE_CHECK_ENV: string;
23
+ export declare const DESIGN_HARNESS_ENV: string;
24
+ export declare const API_URL_ENV: string;
25
+ export declare const NO_IDLE_STOP_ENV: string;
26
+ /** Unset, empty, `0` and `false` are off; anything else is on. */
27
+ export declare function envFlagOn(raw: string | undefined): boolean;
12
28
  export declare const DEFAULT_CONTROL_PORT = 4400;
13
- /** A second daemon must never share the control range with the first:
14
- * `daemonMain` adopts any live daemon it finds inside its own range, so a
15
- * separate DATA_DIR alone does not isolate it. Falling back to the default on a
16
- * bad value would silently undo that isolation, so an unusable value is fatal
17
- * rather than ignored. */
29
+ /** Only where the daemon looks for a free control port: daemons on different
30
+ * data dirs share a range without adopting each other. A set value is still a
31
+ * deliberate choice, so one that cannot make a bindable range is fatal rather
32
+ * than quietly swapped for the default. */
18
33
  export declare function resolveControlPort(raw: string | undefined): number;
19
- /** Ten consecutive ports starting at the resolved start. Resolved on call, not
20
- * at import: this module is a dependency of the published `@cychien/ezdesign/vite`
21
- * entry point, which must never read - let alone fail on - this variable. */
34
+ /** The Fetch standard's "bad ports" (https://fetch.spec.whatwg.org/#bad-port).
35
+ * Node's fetch refuses them as a browser does, and the CLI, the agent and the
36
+ * dev scripts all reach the daemon over fetch, so it must never listen on one:
37
+ * 4190 sits inside an otherwise ordinary range. */
38
+ export declare const FETCH_BAD_PORTS: ReadonlySet<number>;
39
+ /** Ten consecutive ports starting at the resolved start; `ports` is the ones a
40
+ * daemon may listen on. Resolved on call, not at import: this module is a
41
+ * dependency of the published `@cychien/ezdesign/vite` entry point, which must
42
+ * never read - let alone fail on - this variable. */
22
43
  export declare function controlPortRange(): {
23
44
  start: number;
24
45
  end: number;
46
+ ports: number[];
25
47
  };
26
48
  /** Surfaces a bad value at the command the user just ran, instead of leaving it
27
49
  * to a detached daemon whose message only reaches the log file. */
@@ -42,4 +64,10 @@ export declare const POLL_TIMEOUT_MS = 50000;
42
64
  * daemon restart, which the CLI survives by re-resolving the session port. */
43
65
  export declare const POLL_RETRIES = 5;
44
66
  export declare const IDLE_STOP_MS: number;
67
+ export declare const IDLE_CHECK_MS = 60000;
68
+ /** How soon a shell's event stream retries a daemon that is gone. */
69
+ export declare const SHELL_RETRY_MS = 1000;
70
+ /** How long a daemon that has taken a session's port back waits for the shells
71
+ * left open on it to reconnect: one retry, its connect, and slack. */
72
+ export declare const SHELL_RETURN_MS = 2000;
45
73
  export declare const SOURCE_ATTR = "data-ez-source";
@@ -0,0 +1,77 @@
1
+ "use strict";
2
+ (() => {
3
+ var __defProp = Object.defineProperty;
4
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
5
+ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
6
+
7
+ // src/client/event-hub.ts
8
+ var CLOSED = 2;
9
+ var CLOSED_RETRY_MS = 1e3;
10
+ var STREAM_STATE = "ez:stream";
11
+ var EventHub = class {
12
+ constructor(open, schedule = (run, ms) => setTimeout(run, ms)) {
13
+ this.open = open;
14
+ this.schedule = schedule;
15
+ __publicField(this, "ports", /* @__PURE__ */ new Set());
16
+ __publicField(this, "events", /* @__PURE__ */ new Set());
17
+ __publicField(this, "source", null);
18
+ /** Streams replaced but kept until the replacement opens, so the daemon never
19
+ * sees a moment with no shell connected. */
20
+ __publicField(this, "retiring", []);
21
+ __publicField(this, "url", null);
22
+ __publicField(this, "retry");
23
+ }
24
+ receive(port, request) {
25
+ if (request.t === "leave") {
26
+ this.ports.delete(port);
27
+ if (this.ports.size === 0) this.close();
28
+ return;
29
+ }
30
+ this.ports.add(port);
31
+ this.url = request.url;
32
+ for (const type of request.events) this.events.add(type);
33
+ this.reopen();
34
+ }
35
+ reopen() {
36
+ clearTimeout(this.retry);
37
+ if (this.source) this.retiring.push(this.source);
38
+ const next = this.open(this.url);
39
+ this.source = next;
40
+ next.addEventListener("open", () => {
41
+ if (this.source !== next) return;
42
+ this.retire();
43
+ this.broadcast(STREAM_STATE, "open");
44
+ });
45
+ next.addEventListener("error", () => {
46
+ if (this.source !== next) return;
47
+ this.broadcast(STREAM_STATE, "down");
48
+ if (next.readyState === CLOSED) this.retry = this.schedule(() => this.reopen(), CLOSED_RETRY_MS);
49
+ });
50
+ for (const type of this.events) {
51
+ next.addEventListener(type, (e) => {
52
+ if (this.source === next) this.broadcast(type, e.data);
53
+ });
54
+ }
55
+ }
56
+ broadcast(type, data) {
57
+ for (const port of this.ports) port.postMessage({ type, data });
58
+ }
59
+ retire() {
60
+ for (const old of this.retiring) old.close();
61
+ this.retiring = [];
62
+ }
63
+ close() {
64
+ clearTimeout(this.retry);
65
+ this.retire();
66
+ this.source?.close();
67
+ this.source = null;
68
+ }
69
+ };
70
+
71
+ // src/client/events-worker.ts
72
+ var hub = new EventHub((url) => new EventSource(url));
73
+ self.onconnect = (e) => {
74
+ const port = e.ports[0];
75
+ port.onmessage = (m) => hub.receive(port, m.data);
76
+ };
77
+ })();
@@ -0,0 +1 @@
1
+ :root{--paper: #faf9f6;--paper-sunken: #f2f0e9;--paper-edge: #e9e6dd;--ink: #171717;--ink-muted: #676767;--ink-faint: #878787;--ink-ghost: #b3b3b3;--panel: #fff;--tag: #ece3d6;--tag-ink: #6b5038;--error: oklch(45% .15 25);--ring: var(--ink-ghost);--ring-halo: color-mix(in oklab, var(--ink) 12%, transparent);--radius: 8px;--ease-out: cubic-bezier(.23, 1, .32, 1);--t-pop: .16s;--t-menu: .18s;--t-view: .22s;color-scheme:light}*,*:before,*:after{box-sizing:border-box}html,body{margin:0;height:100%;background:transparent}body{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Noto Sans TC,sans-serif;font-size:13px;line-height:1.5;color:var(--ink);-webkit-font-smoothing:antialiased}button,input,textarea{font:inherit;color:inherit}.overlay{position:fixed;inset:0;display:grid;grid-template-columns:minmax(0,1fr);place-items:safe center;padding:16px;overflow:auto;background:#00000052;animation:fade-in var(--t-view) var(--ease-out) both}[data-where=window] .overlay{background:var(--panel);place-items:start stretch;padding:20px;animation:none}.card{width:min(440px,100%);padding:20px 20px 16px;background:var(--panel);border-radius:12px;box-shadow:0 0 0 1px #0000000f,0 24px 64px #0000003d,0 4px 12px #00000014;animation:card-in var(--t-view) var(--ease-out) both}[data-where=window] .card{width:100%;padding:0;border-radius:0;box-shadow:none;animation:none}header{margin-bottom:14px}h1{margin:0;font-size:14px;font-weight:600;letter-spacing:-.01em}.source:empty{display:none}.source{margin:2px 0 0;color:var(--ink-muted);font-size:12px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.preview{display:flex;justify-content:center;align-items:center;margin:0 0 14px;min-height:72px;padding:8px;border-radius:var(--radius);background:var(--paper-sunken)}[data-where=page] .preview{margin:-20px -20px 16px;padding:0;overflow:hidden;border-radius:12px 12px 0 0;box-shadow:0 1px 0 var(--paper-edge)}.preview img{display:block;max-width:100%;max-height:clamp(96px,calc(100vh - 400px),300px);object-fit:contain}.preview .slot{display:block;max-width:100%;animation:slot-pulse 1.2s ease-in-out infinite alternate}.preview canvas{display:block;max-width:100%;height:auto;border-radius:2px}.field{display:grid;gap:4px;margin-bottom:12px}.label{font-size:12px;font-weight:500;color:var(--ink-muted)}.combo{position:relative}.tags,textarea{width:100%;border:1px solid var(--paper-edge);border-radius:var(--radius);background:var(--panel);transition:border-color var(--t-pop) var(--ease-out),box-shadow var(--t-pop) var(--ease-out)}.tags{display:flex;flex-wrap:wrap;align-items:center;gap:4px;min-height:34px;padding:4px 6px;cursor:text}.tags:focus-within,textarea:focus{border-color:var(--ring);box-shadow:0 0 0 3px var(--ring-halo)}.chips{display:contents}.chip{display:inline-flex;align-items:center;gap:3px;max-width:180px;height:22px;padding:0 6px;border:0;border-radius:4px;background:var(--tag);color:var(--tag-ink);font-size:12px;font-weight:500;white-space:nowrap;cursor:pointer}.chip>span:first-child{overflow:hidden;text-overflow:ellipsis}.chip .x{font-size:13px;line-height:1;opacity:.6}.chip:hover .x{opacity:1}.chip.locked{background:var(--paper-sunken);color:var(--ink-muted);cursor:default}.tags input{flex:1;min-width:120px;height:24px;padding:0 2px;border:0;outline:none;background:transparent}input::placeholder,textarea::placeholder{color:var(--ink-ghost)}[role=listbox]{position:absolute;top:calc(100% + 4px);left:0;z-index:1;min-width:200px;max-width:100%;margin:0;padding:4px;list-style:none;border-radius:10px;background:var(--panel);border:1px solid var(--paper-edge);box-shadow:0 12px 32px #0000001f,0 2px 8px #0000000f;animation:menu-in var(--t-menu) var(--ease-out) both}[role=option]{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:5px 8px;border-radius:6px;cursor:pointer}[role=option][data-active],[role=option]:hover{background:var(--paper-sunken)}[role=option] .uses{color:var(--ink-faint);font-size:11px;font-variant-numeric:tabular-nums}textarea{display:block;min-height:64px;padding:7px 8px;resize:vertical;outline:none}.status{min-height:1.5em;margin:0 0 10px;color:var(--ink-muted);font-size:12px}.status:empty{display:none}.status[data-tone=error]{color:var(--error)}.install{display:flex;align-items:center;gap:8px;margin:0 0 12px;padding:6px 6px 6px 10px;border-radius:var(--radius);background:var(--paper-sunken)}.install code{flex:1;min-width:0;font:12px/1.4 ui-monospace,SF Mono,Menlo,monospace;overflow-wrap:anywhere}[hidden]{display:none!important}footer{display:flex;justify-content:flex-end;gap:8px;margin-top:4px}button{height:36px;padding:0 16px;border:0;border-radius:7px;background:var(--panel);box-shadow:0 0 0 1px var(--paper-edge);font-size:14px;font-weight:600;cursor:pointer;transition:background-color var(--t-pop) var(--ease-out)}button:not(.chip):hover{background:var(--paper-sunken)}button.primary{min-width:64px;background:var(--ink);color:#fff;box-shadow:inset 0 1px #ffffff24}button.primary:hover{background:#2e2e2e}button:disabled,button.primary:disabled{cursor:default;opacity:.45}button.primary[aria-busy=true]{opacity:.8}button.quiet{height:26px;padding:0 10px;font-size:12px}button.grant{width:100%;margin:0 0 12px}.chip:focus-visible,button:focus-visible{outline:3px solid var(--ring-halo);outline-offset:0}[data-leaving] .overlay{animation:fade-out var(--t-view) var(--ease-out) both}[data-leaving=saved] .card{transform-origin:top center;animation:card-save var(--t-view) var(--ease-out) both}[data-leaving=cancelled] .card,[data-where=window][data-leaving] .card{animation:fade-out var(--t-view) var(--ease-out) both}@keyframes fade-in{0%{opacity:0}}@keyframes fade-out{to{opacity:0}}@keyframes card-in{0%{opacity:0;transform:scale(.96)}}@keyframes card-save{to{opacity:0;transform:translateY(-36vh) scale(.3)}}@keyframes slot-pulse{to{background:var(--paper-edge)}}@keyframes menu-in{0%{opacity:0;transform:translateY(-2px)}}@media(prefers-reduced-motion:reduce){.preview .slot{animation:none}.card,[role=listbox],[data-leaving=saved] .card{animation-name:fade-in}[data-leaving] .card{animation-name:fade-out}}
@@ -0,0 +1,13 @@
1
+ <!doctype html>
2
+ <html lang="zh-Hant">
3
+ <head>
4
+ <meta charset="utf-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
6
+ <meta name="color-scheme" content="light" />
7
+ <title>儲存至 ezdesign</title>
8
+ <link rel="stylesheet" href="dialog.css" />
9
+ </head>
10
+ <body>
11
+ <script src="dialog.js"></script>
12
+ </body>
13
+ </html>
@@ -0,0 +1 @@
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 M(e){let t=e.normalize("NFC").trim().replace(/\s+/g," ");return t===""||t.length>64||/[,,]/.test(t)?null:t}function y(e){return e.normalize("NFKC").trim().replace(/\s+/g," ").toLowerCase()}var W={locked:[],chips:[],draft:"",highlighted:null},se=/[,,]/;function T(e){return[...e.locked,...e.chips]}function I(e,t){let n=M(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(se),o=r.pop()??"";return{...r.reduce(I,e),draft:o,highlighted:null}}case"enter":{let r=e.highlighted===null?e.draft:n[e.highlighted];return{...I(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{...I(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=M(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 le=location.hash.slice(1),A=window.top===window;document.documentElement.dataset.where=A?"window":"page";var N=chrome.runtime.connect({name:K+le}),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",ce="\u4E32\u6D41\u5F71\u7247\u53EA\u6703\u5132\u5B58\u9023\u7D50\u3001\u76EE\u524D\u6642\u9593\u548C\u756B\u9762",de="\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"}),pe=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"}),ue=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",{},pe,R);O.append(...A?[$,u]:[u,$],a("div",{class:"field"},a("span",{class:"label","aria-hidden":"true"},"\u6A19\u7C64"),a("div",{class:"combo"},ue,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,z=null,w=null;function J(){if(z===null||w===null||w.nonce!==z)return;let{bitmap:e}=w;z=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 C=()=>d.map(e=>e.name);l.addEventListener("input",()=>{let e=i.chips.length;i=p(i,{type:"input",value:l.value},C()),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},C()),b()):e.key==="Enter"&&!(e.metaKey||e.ctrlKey)?(e.preventDefault(),i=p(i,{type:"enter"},C()),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"},C()),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 ge(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 he(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=ge(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"?ce:e.notice==="too-large"?de: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 me="min(300px, max(96px, 100vh - 400px))",ye=1200;function V(e,t){e.style.aspectRatio=`${t.width} / ${t.height}`,e.style.width=`min(100%, ${t.width}px, calc(${me} * ${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,ye/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 fe(e){switch(e.type){case"bitmap":D(e.size),z=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"?fe(t.preview):t.type==="view"?he(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();})();
@@ -0,0 +1,9 @@
1
+ <!doctype html>
2
+ <html>
3
+ <head>
4
+ <meta charset="utf-8" />
5
+ </head>
6
+ <body>
7
+ <script src="media.js"></script>
8
+ </body>
9
+ </html>
@@ -0,0 +1 @@
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 m(t,r){let e=await y(t,r);return{...e,webp:l(e.webp)}}var d=new Map;async function E(t){let r=new Blob(t),e=await createImageBitmap(r).catch(()=>null);if(e)try{return await m(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 m(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 m(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([m(i,o),c()]);return{original:u,thumb:h}}async function M(t){switch(t.type){case"feed":return d.set(t.job,[...d.get(t.job)??[],w(t.data)]),{};case"thumbnail":{let r=d.get(t.job)??[];return d.delete(t.job),{thumb:t.at===null?await E(r):await v(r,t.at)}}case"crop":return S(t);case"drop":return d.delete(t.job),{}}}function T(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 M(n).then(e,()=>e(T(n))),!0});})();
@@ -0,0 +1,39 @@
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 I(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=I(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 T(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 T(e){let n=A.get(e);n?.listening.abort(),n?.host.remove(),A.delete(e)}function L(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=L(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",H,!0),removeEventListener("wheel",v,!0),removeEventListener("touchmove",v,!0),e.remove(),await V(),await V(),x(s))},H=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=L(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",H,!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=>(T(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}));})();
@@ -0,0 +1 @@
1
+ :root{--paper: #faf9f6;--paper-sunken: #f2f0e9;--paper-edge: #e9e6dd;--ink: #171717;--ink-muted: #676767;--ink-faint: #878787;--ok: #3d7a3a;--bad: #b4482a;--ring-halo: color-mix(in oklab, var(--ink) 12%, transparent);--radius: 8px;--ease-out: cubic-bezier(.23, 1, .32, 1);--t-view: .22s}html,body{margin:0;min-height:100%}body{display:grid;place-items:start center;padding:72px 16px;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Noto Sans TC,sans-serif;font-size:14px;line-height:1.5;background:var(--paper);color:var(--ink);-webkit-font-smoothing:antialiased}.card{width:min(520px,100%);padding:28px 28px 24px;background:#fff;border-radius:12px;box-shadow:0 0 0 1px var(--paper-edge),0 8px 28px #0000000f;animation:card-in var(--t-view) var(--ease-out) both}@keyframes card-in{0%{opacity:0;transform:translateY(4px)}}@media(prefers-reduced-motion:reduce){.card{animation:none}}h1{margin:0;font-size:18px;font-weight:600;letter-spacing:-.01em}.lede{margin:4px 0 20px;color:var(--ink-muted)}.state{display:flex;align-items:center;gap:8px;margin:0 0 12px;font-weight:600}.state:before{content:"";width:8px;height:8px;border-radius:50%;background:var(--ink-faint);flex:none}.state[data-tone=ok]:before{background:var(--ok)}.state[data-tone=bad]:before{background:var(--bad)}dl{display:grid;grid-template-columns:max-content 1fr;gap:6px 16px;margin:0;padding:12px 14px;background:var(--paper-sunken);border-radius:var(--radius)}dt{color:var(--ink-muted)}dd{margin:0;min-width:0;overflow-wrap:anywhere}p{margin:0 0 10px}.message{color:var(--bad);overflow-wrap:anywhere}.command{display:flex;align-items:center;gap:8px;padding:8px 8px 8px 12px;background:var(--paper-sunken);border-radius:var(--radius)}code{flex:1;min-width:0;font:12.5px/1.4 ui-monospace,SF Mono,Menlo,monospace;overflow-wrap:anywhere}.actions{display:flex;justify-content:flex-end;margin-top:16px}button{font:inherit;font-size:13px;font-weight:500;height:30px;padding:0 12px;border:0;border-radius:6px;cursor:pointer;background:#fff;color:var(--ink);box-shadow:0 0 0 1px var(--paper-edge);transition:background-color var(--t-view) var(--ease-out)}button:hover{background:var(--paper-sunken)}button.primary{background:var(--ink);color:#fff;box-shadow:none}button.primary:hover{background:#2e2e2e}button:disabled{cursor:default;opacity:.6}:focus-visible{outline:3px solid var(--ring-halo);outline-offset:0}.how{margin:14px 0 0;color:var(--ink-muted)}
@@ -0,0 +1,17 @@
1
+ <!doctype html>
2
+ <html lang="zh-Hant">
3
+ <head>
4
+ <meta charset="utf-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
6
+ <title>ezdesign capture</title>
7
+ <link rel="stylesheet" href="setup.css" />
8
+ </head>
9
+ <body>
10
+ <main class="card" aria-labelledby="title">
11
+ <h1 id="title">ezdesign capture</h1>
12
+ <p class="lede">把網頁上的圖片、影片和截圖存進 ezdesign 的設計收藏。</p>
13
+ <section id="status" aria-live="polite"></section>
14
+ </main>
15
+ <script src="setup.js"></script>
16
+ </body>
17
+ </html>
@@ -0,0 +1 @@
1
+ "use strict";(()=>{var o=document.getElementById("status");function l(e){let n={to:"worker",type:"host-status",recheck:e};return chrome.runtime.sendMessage(n)}function t(e,n={},...m){let a=document.createElement(e),{dataset:i,...u}=n;return Object.assign(a,u),i&&Object.assign(a.dataset,i),a.append(...m),a}function s(e,n){return t("p",{className:"state",dataset:{tone:n}},e)}function c(e){let n=t("button",{type:"button",textContent:"\u8907\u88FD"});return n.addEventListener("click",()=>{navigator.clipboard.writeText(e).then(()=>{n.textContent="\u5DF2\u8907\u88FD",setTimeout(()=>n.textContent="\u8907\u88FD",1500)})}),t("div",{className:"command"},t("code",{textContent:e}),n)}function r(){let e=t("button",{type:"button",className:"primary",textContent:"\u91CD\u65B0\u6AA2\u67E5"});return e.addEventListener("click",()=>{e.disabled=!0,e.textContent="\u6AA2\u67E5\u4E2D\u2026",l(!0).then(d)}),t("div",{className:"actions"},e)}function d(e){switch(e.type){case"connecting":o.replaceChildren(s("\u6B63\u5728\u6AA2\u67E5 ezdesign host\u2026","idle"));return;case"ready":o.replaceChildren(s("\u5DF2\u9023\u7DDA","ok"),t("dl",{},t("dt",{textContent:"ezdesign"}),t("dd",{textContent:e.version}),t("dt",{textContent:"Node"}),t("dd",{textContent:e.node}),t("dt",{textContent:"\u6536\u85CF\u4F4D\u7F6E"}),t("dd",{textContent:e.libraryDir})),t("p",{className:"how",textContent:"\u5728\u7DB2\u9801\u7684\u5716\u7247\u6216\u5F71\u7247\u4E0A\u6309\u53F3\u9375\uFF0C\u9078\u300C\u5132\u5B58\u81F3 ezdesign\u300D\uFF1B\u6309\u5DE5\u5177\u5217\u7684 ezdesign \u5716\u793A\u6216 Alt+Shift+S \u622A\u53D6\u4E00\u584A\u5340\u57DF\u3002"}));return;case"missing":o.replaceChildren(s("\u627E\u4E0D\u5230 ezdesign host","bad"),t("p",{textContent:"\u5728\u7D42\u7AEF\u6A5F\u57F7\u884C\u9019\u884C\u6307\u4EE4\uFF0C\u88DD\u597D\u5F8C\u6309\u300C\u91CD\u65B0\u6AA2\u67E5\u300D\u3002"}),c(e.installCommand),r());return;case"incompatible":o.replaceChildren(s(e.older==="host"?"ezdesign host \u7248\u672C\u592A\u820A":"\u9019\u500B\u64F4\u5145\u529F\u80FD\u7248\u672C\u592A\u820A","bad"),t("p",{textContent:"\u5728\u7D42\u7AEF\u6A5F\u57F7\u884C\u9019\u884C\u6307\u4EE4\u66F4\u65B0\uFF0C\u7136\u5F8C\u6309\u300C\u91CD\u65B0\u6AA2\u67E5\u300D\u3002"}),c(e.installCommand),r());return;case"broken":o.replaceChildren(s("ezdesign host \u7121\u6CD5\u4F7F\u7528","bad"),t("p",{className:"message",textContent:e.message}),r());return}}d({type:"connecting"});l(!1).then(d);})();