surf-cli 2.5.2 → 2.7.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 +46 -3
- package/dist/content/accessibility-tree.js +8 -8
- package/dist/content/accessibility-tree.js.map +1 -1
- package/dist/content/visual-indicator.js +17 -17
- package/dist/content/visual-indicator.js.map +1 -1
- package/dist/manifest.json +1 -1
- package/dist/service-worker/index.js +27 -27
- package/dist/service-worker/index.js.map +1 -1
- package/native/aistudio-build.cjs +562 -0
- package/native/aistudio-client.cjs +502 -0
- package/native/aistudio-model.cjs +225 -0
- package/native/aistudio-parser.cjs +424 -0
- package/native/aistudio-response.cjs +336 -0
- package/native/cli.cjs +95 -14
- package/native/do-executor.cjs +1 -1
- package/native/gemini-client.cjs +304 -63
- package/native/host-helpers.cjs +29 -0
- package/native/host.cjs +261 -14
- package/native/mcp-server.cjs +1 -1
- package/native/network-store.cjs +3 -1
- package/package.json +10 -9
- package/scripts/install-native-host.cjs +14 -2
- package/scripts/uninstall-native-host.cjs +7 -1
- package/skills/README.md +21 -0
- package/skills/surf/SKILL.md +575 -0
package/README.md
CHANGED
|
@@ -8,7 +8,9 @@
|
|
|
8
8
|
|
|
9
9
|
[](https://www.npmjs.com/package/surf-cli)
|
|
10
10
|
[](LICENSE)
|
|
11
|
-
[]()
|
|
11
|
+
[]()
|
|
12
|
+
|
|
13
|
+
> **v2.6.0** — AI Studio support (`surf aistudio`, `surf aistudio.build`), Windows support, Helium browser support, env var overrides. See [CHANGELOG](CHANGELOG.md).
|
|
12
14
|
|
|
13
15
|
```bash
|
|
14
16
|
surf go "https://example.com"
|
|
@@ -72,10 +74,20 @@ surf tab.list
|
|
|
72
74
|
```bash
|
|
73
75
|
surf install <extension-id> # Chrome (default)
|
|
74
76
|
surf install <extension-id> --browser brave # Brave
|
|
77
|
+
surf install <extension-id> --browser helium # Helium
|
|
75
78
|
surf install <extension-id> --browser all # All supported browsers
|
|
76
79
|
```
|
|
77
80
|
|
|
78
|
-
Supported: `chrome`, `chromium`, `brave`, `edge`, `arc`
|
|
81
|
+
Supported: `chrome`, `chromium`, `brave`, `edge`, `arc`, `helium`
|
|
82
|
+
|
|
83
|
+
**Package Manager Installs (Nix, Homebrew, etc.)**
|
|
84
|
+
If surf is installed via a package manager that stores binaries in non-standard locations, set these environment variables before running `surf install`:
|
|
85
|
+
```bash
|
|
86
|
+
export SURF_NODE_PATH=/path/to/node
|
|
87
|
+
export SURF_HOST_PATH=/path/to/native/host.cjs
|
|
88
|
+
export SURF_EXTENSION_PATH=/path/to/extension/dist
|
|
89
|
+
```
|
|
90
|
+
See [Environment Variables](#environment-variables) for details.
|
|
79
91
|
|
|
80
92
|
### Uninstall
|
|
81
93
|
|
|
@@ -315,9 +327,20 @@ surf grok "find viral AI posts" --deep-search # DeepSearch mode
|
|
|
315
327
|
surf grok "quick question" --model fast # Models: auto, fast, expert, thinking
|
|
316
328
|
surf grok --validate # Check UI and available models
|
|
317
329
|
surf grok --validate --save-models # Save discovered models to settings
|
|
330
|
+
|
|
331
|
+
# AI Studio (queries aistudio.google.com using your Google login)
|
|
332
|
+
surf aistudio "explain quantum computing"
|
|
333
|
+
surf aistudio "redteam this" --with-page # Include page context
|
|
334
|
+
surf aistudio "quick answer" --model gemini-3-flash-preview # Model selection
|
|
335
|
+
|
|
336
|
+
# AI Studio App Builder (generates full web apps from a prompt)
|
|
337
|
+
surf aistudio.build "build a portfolio site"
|
|
338
|
+
surf aistudio.build "todo app" --model gemini-3.1-pro-preview # Model override
|
|
339
|
+
surf aistudio.build "crm dashboard" --output ./out # Extract zip to directory
|
|
340
|
+
surf aistudio.build "game" --keep-open --timeout 600 # Keep tab open, 10min timeout
|
|
318
341
|
```
|
|
319
342
|
|
|
320
|
-
Each AI tool uses your existing browser login - no API keys needed. Just be logged into the respective service in Chrome (chatgpt.com, gemini.google.com, perplexity.ai, or
|
|
343
|
+
Each AI tool uses your existing browser login - no API keys needed. Just be logged into the respective service in Chrome (chatgpt.com, gemini.google.com, perplexity.ai, x.com, or aistudio.google.com).
|
|
321
344
|
|
|
322
345
|
**Grok troubleshooting:** If queries fail, run `surf grok --validate` to check if the UI structure changed. Use `--save-models` to update the model cache in `surf.json`. Default model is "thinking" (Grok 4.1 Thinking).
|
|
323
346
|
|
|
@@ -511,6 +534,26 @@ surf workflow.validate ./my-workflow.json
|
|
|
511
534
|
--network-path <path> # Custom path for network logs (default: /tmp/surf, or SURF_NETWORK_PATH env)
|
|
512
535
|
```
|
|
513
536
|
|
|
537
|
+
## Environment Variables
|
|
538
|
+
|
|
539
|
+
```bash
|
|
540
|
+
SURF_NETWORK_PATH # Path for network capture logs (default: /tmp/surf)
|
|
541
|
+
SURF_NODE_PATH # Path to node binary (for native host wrapper)
|
|
542
|
+
SURF_HOST_PATH # Path to native/host.cjs (for native host wrapper)
|
|
543
|
+
SURF_EXTENSION_PATH # Path to extension dist/ directory
|
|
544
|
+
```
|
|
545
|
+
|
|
546
|
+
**Use cases:**
|
|
547
|
+
- `SURF_NODE_PATH` / `SURF_HOST_PATH`: Package manager installs (e.g., Nix) that store binaries in non-standard locations
|
|
548
|
+
- `SURF_EXTENSION_PATH`: Package managers that create stable symlinks instead of changing paths on reinstall
|
|
549
|
+
|
|
550
|
+
**Example (Nix):**
|
|
551
|
+
```bash
|
|
552
|
+
export SURF_NODE_PATH=~/.local/share/surf-cli/node
|
|
553
|
+
export SURF_HOST_PATH=~/.local/share/surf-cli/native/host.cjs
|
|
554
|
+
export SURF_EXTENSION_PATH=~/.local/share/surf-cli/extension
|
|
555
|
+
```
|
|
556
|
+
|
|
514
557
|
## Socket API
|
|
515
558
|
|
|
516
559
|
For programmatic integration, send JSON to `/tmp/surf.sock`:
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
const J=new Set(["alert","alertdialog","application","article","banner","blockquote","button","caption","cell","checkbox","code","columnheader","combobox","complementary","contentinfo","definition","deletion","dialog","directory","document","emphasis","feed","figure","form","generic","grid","gridcell","group","heading","img","insertion","link","list","listbox","listitem","log","main","mark","marquee","math","menu","menubar","menuitem","menuitemcheckbox","menuitemradio","meter","navigation","none","note","option","paragraph","presentation","progressbar","radio","radiogroup","region","row","rowgroup","rowheader","scrollbar","search","searchbox","separator","slider","spinbutton","status","strong","subscript","superscript","switch","tab","table","tablist","tabpanel","term","textbox","time","timer","toolbar","tooltip","tree","treegrid","treeitem"]);function Q(i){const m=i.tagName.toLowerCase();if(["button","input","select","textarea"].includes(m))return!i.disabled;if(m==="a"&&i.hasAttribute("href"))return!0;if(i.hasAttribute("tabindex")){const r=parseInt(i.getAttribute("tabindex")||"",10);return!isNaN(r)&&r>=0}return i.getAttribute("contenteditable")==="true"}function Z(i){const m=i.getAttribute("role");if(!m)return null;const r=m.split(/\s+/).filter(w=>w);for(const w of r)if(J.has(w))return w;return null}function X(i){const m=i.tagName.toLowerCase(),r=i.getAttribute("type"),w={a:g=>g.hasAttribute("href")?"link":"generic",article:"article",aside:"complementary",button:"button",datalist:"listbox",dd:"definition",details:"group",dialog:"dialog",dt:"term",fieldset:"group",figure:"figure",footer:g=>g.closest("article, aside, main, nav, section")?"generic":"contentinfo",form:g=>g.hasAttribute("aria-label")||g.hasAttribute("aria-labelledby")?"form":"generic",h1:"heading",h2:"heading",h3:"heading",h4:"heading",h5:"heading",h6:"heading",header:g=>g.closest("article, aside, main, nav, section")?"generic":"banner",hr:"separator",img:g=>g.getAttribute("alt")===""?"presentation":"img",li:"listitem",main:"main",math:"math",menu:"list",meter:"meter",nav:"navigation",ol:"list",optgroup:"group",option:"option",output:"status",p:"paragraph",progress:"progressbar",search:"search",section:g=>g.hasAttribute("aria-label")||g.hasAttribute("aria-labelledby")?"region":"generic",select:g=>{const e=g;return e.hasAttribute("multiple")||e.size&&e.size>1?"listbox":"combobox"},table:"table",tbody:"rowgroup",td:"cell",textarea:"textbox",tfoot:"rowgroup",th:"columnheader",thead:"rowgroup",time:"time",tr:"row",ul:"list"};if(m==="input")return{button:"button",checkbox:"checkbox",email:"textbox",file:"button",image:"button",number:"spinbutton",radio:"radio",range:"slider",reset:"button",search:"searchbox",submit:"button",tel:"textbox",text:"textbox",url:"textbox"}[r||""]||"textbox";const y=w[m];return typeof y=="function"?y(i):y||"generic"}function U(i){const m=Z(i);return!m||(m==="none"||m==="presentation")&&Q(i)?X(i):m}window.__piElementMap||(window.__piElementMap={});let ee=0;function q(i,m,r){const w=i._piRef;if(w&&w.role===m&&w.name===r)return w.ref;const y=`e${++ee}`;return i._piRef={role:m,name:r,ref:y},y}function Y(){const i=[];return document.querySelectorAll('[role="dialog"], [role="alertdialog"], dialog[open]').forEach(r=>{var c,l;const w=window.getComputedStyle(r);if(!(w.display!=="none"&&w.visibility!=="hidden"&&w.opacity!=="0"&&r.offsetWidth>0&&r.offsetHeight>0))return;const g=r.getAttribute("role")||"dialog";let e=r.getAttribute("aria-label")||((l=(c=r.querySelector('[role="heading"], h1, h2, h3'))==null?void 0:c.textContent)==null?void 0:l.trim())||"Dialog";e.length>100&&(e=e.substring(0,100)+"..."),i.push({type:g,description:`${g}: ${e}`,clearedBy:"computer(action=key, text=Escape)"})}),i}const j={wait(i){return new Promise(m=>setTimeout(m,i))},async waitForSelector(i,m={}){const{state:r="visible",timeout:w=2e4}=m,y=e=>{if(!e)return!1;const c=window.getComputedStyle(e);return c.display!=="none"&&c.visibility!=="hidden"&&c.opacity!=="0"&&e.offsetWidth>0&&e.offsetHeight>0},g=()=>{const e=document.querySelector(i);switch(r){case"attached":return e;case"detached":return e?null:document.body;case"hidden":return e?y(e)?null:e:document.body;case"visible":default:return y(e)?e:null}};return new Promise((e,c)=>{const l=g();if(l){e(r==="detached"||r==="hidden"?null:l);return}const s=new MutationObserver(()=>{const u=g();u&&(s.disconnect(),clearTimeout(d),e(r==="detached"||r==="hidden"?null:u))}),d=setTimeout(()=>{s.disconnect(),c(new Error(`Timeout waiting for "${i}" to be ${r}`))},w);s.observe(document.documentElement,{childList:!0,subtree:!0,attributes:!0,attributeFilter:["style","class","hidden"]})})},async waitForText(i,m={}){const{selector:r,timeout:w=2e4}=m,y=()=>{var c;const g=r?document.querySelector(r):document.body;if(!g)return null;const e=document.createTreeWalker(g,NodeFilter.SHOW_TEXT);for(;e.nextNode();)if((c=e.currentNode.textContent)!=null&&c.includes(i))return e.currentNode.parentElement;return null};return new Promise((g,e)=>{const c=y();if(c){g(c);return}const l=new MutationObserver(()=>{const d=y();d&&(l.disconnect(),clearTimeout(s),g(d))}),s=setTimeout(()=>{l.disconnect(),e(new Error(`Timeout waiting for text "${i}"`))},w);l.observe(document.documentElement,{childList:!0,subtree:!0,characterData:!0})})},async waitForHidden(i,m=2e4){await j.waitForSelector(i,{state:"hidden",timeout:m})},getByRole(i,m={}){var c,l,s,d;const{name:r}=m,w={button:["button",'input[type="button"]','input[type="submit"]','input[type="reset"]'],link:["a[href]"],textbox:["input:not([type])",'input[type="text"]','input[type="email"]','input[type="password"]','input[type="search"]','input[type="tel"]','input[type="url"]',"textarea"],checkbox:['input[type="checkbox"]'],radio:['input[type="radio"]'],combobox:["select"],heading:["h1","h2","h3","h4","h5","h6"],list:["ul","ol"],listitem:["li"],navigation:["nav"],main:["main"],banner:["header"],contentinfo:["footer"],form:["form"],img:["img"],table:["table"]},y=[];y.push(...document.querySelectorAll(`[role="${i}"]`));const g=w[i];if(g)for(const u of g)y.push(...document.querySelectorAll(`${u}:not([role])`));if(!r)return y[0]||null;const e=r.toLowerCase().trim();for(const u of y){const h=(c=u.getAttribute("aria-label"))==null?void 0:c.toLowerCase().trim(),b=(l=u.textContent)==null?void 0:l.toLowerCase().trim(),a=(s=u.getAttribute("title"))==null?void 0:s.toLowerCase().trim(),t=(d=u.getAttribute("placeholder"))==null?void 0:d.toLowerCase().trim();if(h===e||b===e||a===e||t===e||h!=null&&h.includes(e)||b!=null&&b.includes(e))return u}return null}};window.__piHelpers||(window.__piHelpers=j,window.piHelpers=j);function O(){return window.__piElementMap}function B(i="interactive",m=15,r,w=!1,y=!1){try{let g=function(n){return U(n)},e=function(n){var R,F;const f=n.tagName.toLowerCase(),k=n.getAttribute("aria-labelledby");if(k){const E=k.split(/\s+/).map(C=>{var P;const I=document.getElementById(C);return((P=I==null?void 0:I.textContent)==null?void 0:P.trim())||""}).filter(Boolean);if(E.length){const C=E.join(" ");return C.length>100?C.substring(0,100)+"...":C}}if(f==="select"){const E=n,C=E.querySelector("option[selected]")||(E.selectedIndex>=0?E.options[E.selectedIndex]:null);if((R=C==null?void 0:C.textContent)!=null&&R.trim())return C.textContent.trim()}const $=n.getAttribute("aria-label");if($!=null&&$.trim())return $.trim();const M=n.getAttribute("placeholder");if(M!=null&&M.trim())return M.trim();const H=n.getAttribute("title");if(H!=null&&H.trim())return H.trim();const T=n.getAttribute("alt");if(T!=null&&T.trim())return T.trim();if(n.id){const E=document.querySelector(`label[for="${n.id}"]`);if((F=E==null?void 0:E.textContent)!=null&&F.trim())return E.textContent.trim()}if(f==="input"){const E=n,C=n.getAttribute("type")||"",I=n.getAttribute("value");if(C==="submit"&&(I!=null&&I.trim()))return I.trim();if(E.value&&E.value.length<50&&E.value.trim())return E.value.trim()}if(["button","a","summary"].includes(f)){let E="";for(const C of n.childNodes)C.nodeType===Node.TEXT_NODE&&(E+=C.textContent);if(E.trim())return E.trim()}if(/^h[1-6]$/.test(f)){const E=n.textContent;if(E!=null&&E.trim()){const C=E.trim();return C.length>100?C.substring(0,100)+"...":C}}if(f==="img")return"";let N="";for(const E of n.childNodes)E.nodeType===Node.TEXT_NODE&&(N+=E.textContent);if(N!=null&&N.trim()&&N.trim().length>=3){const E=N.trim();return E.length>100?E.substring(0,100)+"...":E}return""},c=function(n){const f={},k=n.getAttribute("aria-checked");k==="true"?f.checked=!0:k==="false"?f.checked=!1:k==="mixed"?f.checked="mixed":n instanceof HTMLInputElement&&(n.type==="checkbox"||n.type==="radio")&&(n.type==="checkbox"&&n.indeterminate?f.checked="mixed":f.checked=n.checked);const $=n instanceof HTMLButtonElement||n instanceof HTMLInputElement||n instanceof HTMLSelectElement||n instanceof HTMLTextAreaElement;(n.getAttribute("aria-disabled")==="true"||$&&n.disabled||n.closest("fieldset:disabled"))&&(f.disabled=!0);const M=n.getAttribute("aria-expanded");M==="true"?f.expanded=!0:M==="false"&&(f.expanded=!1);const H=n.getAttribute("aria-pressed");H==="true"?f.pressed=!0:H==="false"?f.pressed=!1:H==="mixed"&&(f.pressed="mixed");const T=n.getAttribute("aria-selected");T==="true"?f.selected=!0:T==="false"&&(f.selected=!1);const N=n.getAttribute("aria-current");N&&N!=="false"&&(f.active=!0);const R=n.tagName.toLowerCase();if(/^h[1-6]$/.test(R))f.level=parseInt(R[1],10);else{const F=n.getAttribute("aria-level");F&&(f.level=parseInt(F,10))}return f},l=function(n){const f=[];return n.checked!==void 0&&f.push(n.checked==="mixed"?"[checked=mixed]":n.checked?"[checked]":"[unchecked]"),n.disabled&&f.push("[disabled]"),n.expanded!==void 0&&f.push(n.expanded?"[expanded]":"[collapsed]"),n.pressed!==void 0&&f.push(n.pressed==="mixed"?"[pressed=mixed]":n.pressed?"[pressed]":"[not-pressed]"),n.selected!==void 0&&f.push(n.selected?"[selected]":"[not-selected]"),n.active&&f.push("[active]"),n.level!==void 0&&f.push(`[level=${n.level}]`),f.join(" ")},s=function(n){const f=window.getComputedStyle(n);return f.display!=="none"&&f.visibility!=="hidden"&&f.opacity!=="0"&&n.offsetWidth>0&&n.offsetHeight>0},d=function(n){const f=n.tagName.toLowerCase();return["a","button","input","select","textarea","details","summary"].includes(f)||n.hasAttribute("onclick")||n.hasAttribute("tabindex")||n.getAttribute("role")==="button"||n.getAttribute("role")==="link"||n.getAttribute("contenteditable")==="true"},u=function(n){const f=n.tagName.toLowerCase();return["h1","h2","h3","h4","h5","h6","nav","main","header","footer","section","article","aside"].includes(f)||n.hasAttribute("role")},h=function(n){return window.getComputedStyle(n).cursor==="pointer"},b=function(n,f){const k=n.tagName.toLowerCase();if(["script","style","meta","link","title","noscript"].includes(k)||f.filter!=="all"&&n.getAttribute("aria-hidden")==="true"||f.filter!=="all"&&!s(n))return!1;if(f.filter!=="all"&&!f.refId){const M=n.getBoundingClientRect();if(!(M.top<window.innerHeight&&M.bottom>0&&M.left<window.innerWidth&&M.right>0))return!1}if(f.filter==="interactive")return d(n);if(d(n)||u(n)||e(n).length>0)return!0;const $=g(n);return f.compact&&new Set(["generic","group","region","article","section","complementary"]).has($)&&e(n).length===0?!1:$!=="generic"&&$!=="img"},a=function(n,f){const k=[],$={filter:i,refId:r||null,compact:y},M=O(),H=b(n,$)||r&&f===0;if(H){const T=g(n),N=e(n),R=c(n),F=q(n,T,N);window.__piRefs[F]=n,M[F]={element:new WeakRef(n),role:T,name:N};let C=`${" ".repeat(f)}${T}`;if(N){const K=N.replace(/\s+/g," ").replace(/"/g,'\\"');C+=` "${K}"`}C+=` [${F}]`;const I=l(R);I&&(C+=` ${I}`),h(n)&&(C+=" [cursor=pointer]");const P=n.getAttribute("href");P&&(C+=` href="${P}"`);const G=n.getAttribute("type");G&&(C+=` type="${G}"`);const V=n.getAttribute("placeholder");V&&(C+=` placeholder="${V}"`),k.push(C)}if(f<m)for(const T of n.children)k.push(...a(T,H?f+1:f));return k},t=function(n){return n.replace(/\[e\d+\]/g,"[REF]")},o=function(n){const f=new Map;for(const k of n){if(!k.trim())continue;const $=t(k);f.set($,(f.get($)||0)+1)}return f},p=function(n,f){const k=n.split(`
|
|
2
|
-
`)
|
|
3
|
-
`),
|
|
4
|
-
`),hasChanges:!0}};window.__piRefs={};const
|
|
5
|
-
`);if(
|
|
1
|
+
const J=new Set(["alert","alertdialog","application","article","banner","blockquote","button","caption","cell","checkbox","code","columnheader","combobox","complementary","contentinfo","definition","deletion","dialog","directory","document","emphasis","feed","figure","form","generic","grid","gridcell","group","heading","img","insertion","link","list","listbox","listitem","log","main","mark","marquee","math","menu","menubar","menuitem","menuitemcheckbox","menuitemradio","meter","navigation","none","note","option","paragraph","presentation","progressbar","radio","radiogroup","region","row","rowgroup","rowheader","scrollbar","search","searchbox","separator","slider","spinbutton","status","strong","subscript","superscript","switch","tab","table","tablist","tabpanel","term","textbox","time","timer","toolbar","tooltip","tree","treegrid","treeitem"]);function Q(i){const g=i.tagName.toLowerCase();if(["button","input","select","textarea"].includes(g))return!i.disabled;if(g==="a"&&i.hasAttribute("href"))return!0;if(i.hasAttribute("tabindex")){const r=parseInt(i.getAttribute("tabindex")||"",10);return!isNaN(r)&&r>=0}return i.getAttribute("contenteditable")==="true"}function Z(i){const g=i.getAttribute("role");if(!g)return null;const r=g.split(/\s+/).filter(e=>e);for(const e of r)if(J.has(e))return e;return null}function X(i){const g=i.tagName.toLowerCase(),r=i.getAttribute("type"),e={a:o=>o.hasAttribute("href")?"link":"generic",article:"article",aside:"complementary",button:"button",datalist:"listbox",dd:"definition",details:"group",dialog:"dialog",dt:"term",fieldset:"group",figure:"figure",footer:o=>o.closest("article, aside, main, nav, section")?"generic":"contentinfo",form:o=>o.hasAttribute("aria-label")||o.hasAttribute("aria-labelledby")?"form":"generic",h1:"heading",h2:"heading",h3:"heading",h4:"heading",h5:"heading",h6:"heading",header:o=>o.closest("article, aside, main, nav, section")?"generic":"banner",hr:"separator",img:o=>o.getAttribute("alt")===""?"presentation":"img",li:"listitem",main:"main",math:"math",menu:"list",meter:"meter",nav:"navigation",ol:"list",optgroup:"group",option:"option",output:"status",p:"paragraph",progress:"progressbar",search:"search",section:o=>o.hasAttribute("aria-label")||o.hasAttribute("aria-labelledby")?"region":"generic",select:o=>{const t=o;return t.hasAttribute("multiple")||t.size&&t.size>1?"listbox":"combobox"},table:"table",tbody:"rowgroup",td:"cell",textarea:"textbox",tfoot:"rowgroup",th:"columnheader",thead:"rowgroup",time:"time",tr:"row",ul:"list"};if(g==="input")return{button:"button",checkbox:"checkbox",email:"textbox",file:"button",image:"button",number:"spinbutton",radio:"radio",range:"slider",reset:"button",search:"searchbox",submit:"button",tel:"textbox",text:"textbox",url:"textbox"}[r||""]||"textbox";const c=e[g];return typeof c=="function"?c(i):c||"generic"}function U(i){const g=Z(i);return!g||(g==="none"||g==="presentation")&&Q(i)?X(i):g}window.__piElementMap||(window.__piElementMap={});let ee=0;function q(i,g,r){const e=i._piRef;if(e&&e.role===g&&e.name===r)return e.ref;const c=`e${++ee}`;return i._piRef={role:g,name:r,ref:c},c}function Y(){const i=[];return document.querySelectorAll('[role="dialog"], [role="alertdialog"], dialog[open]').forEach(r=>{const e=window.getComputedStyle(r);if(!(e.display!=="none"&&e.visibility!=="hidden"&&e.opacity!=="0"&&r.offsetWidth>0&&r.offsetHeight>0))return;const o=r.getAttribute("role")||"dialog";let t=r.getAttribute("aria-label")||r.querySelector('[role="heading"], h1, h2, h3')?.textContent?.trim()||"Dialog";t.length>100&&(t=t.substring(0,100)+"..."),i.push({type:o,description:`${o}: ${t}`,clearedBy:"computer(action=key, text=Escape)"})}),i}const j={wait(i){return new Promise(g=>setTimeout(g,i))},async waitForSelector(i,g={}){const{state:r="visible",timeout:e=2e4}=g,c=t=>{if(!t)return!1;const l=window.getComputedStyle(t);return l.display!=="none"&&l.visibility!=="hidden"&&l.opacity!=="0"&&t.offsetWidth>0&&t.offsetHeight>0},o=()=>{const t=document.querySelector(i);switch(r){case"attached":return t;case"detached":return t?null:document.body;case"hidden":return t?c(t)?null:t:document.body;default:return c(t)?t:null}};return new Promise((t,l)=>{const u=o();if(u){t(r==="detached"||r==="hidden"?null:u);return}const d=new MutationObserver(()=>{const a=o();a&&(d.disconnect(),clearTimeout(w),t(r==="detached"||r==="hidden"?null:a))}),w=setTimeout(()=>{d.disconnect(),l(new Error(`Timeout waiting for "${i}" to be ${r}`))},e);d.observe(document.documentElement,{childList:!0,subtree:!0,attributes:!0,attributeFilter:["style","class","hidden"]})})},async waitForText(i,g={}){const{selector:r,timeout:e=2e4}=g,c=()=>{const o=r?document.querySelector(r):document.body;if(!o)return null;const t=document.createTreeWalker(o,NodeFilter.SHOW_TEXT);for(;t.nextNode();)if(t.currentNode.textContent?.includes(i))return t.currentNode.parentElement;return null};return new Promise((o,t)=>{const l=c();if(l){o(l);return}const u=new MutationObserver(()=>{const w=c();w&&(u.disconnect(),clearTimeout(d),o(w))}),d=setTimeout(()=>{u.disconnect(),t(new Error(`Timeout waiting for text "${i}"`))},e);u.observe(document.documentElement,{childList:!0,subtree:!0,characterData:!0})})},async waitForHidden(i,g=2e4){await j.waitForSelector(i,{state:"hidden",timeout:g})},getByRole(i,g={}){const{name:r}=g,e={button:["button",'input[type="button"]','input[type="submit"]','input[type="reset"]'],link:["a[href]"],textbox:["input:not([type])",'input[type="text"]','input[type="email"]','input[type="password"]','input[type="search"]','input[type="tel"]','input[type="url"]',"textarea"],checkbox:['input[type="checkbox"]'],radio:['input[type="radio"]'],combobox:["select"],heading:["h1","h2","h3","h4","h5","h6"],list:["ul","ol"],listitem:["li"],navigation:["nav"],main:["main"],banner:["header"],contentinfo:["footer"],form:["form"],img:["img"],table:["table"]},c=[];c.push(...document.querySelectorAll(`[role="${i}"]`));const o=e[i];if(o)for(const l of o)c.push(...document.querySelectorAll(`${l}:not([role])`));if(!r)return c[0]||null;const t=r.toLowerCase().trim();for(const l of c){const u=l.getAttribute("aria-label")?.toLowerCase().trim(),d=l.textContent?.toLowerCase().trim(),w=l.getAttribute("title")?.toLowerCase().trim(),a=l.getAttribute("placeholder")?.toLowerCase().trim();if(u===t||d===t||w===t||a===t||u?.includes(t)||d?.includes(t))return l}return null}};window.__piHelpers||(window.__piHelpers=j,window.piHelpers=j);function I(){return window.__piElementMap}function B(i="interactive",g=15,r,e=!1,c=!1){try{let o=function(n){return U(n)},t=function(n){const h=n.tagName.toLowerCase(),_=n.getAttribute("aria-labelledby");if(_){const y=_.split(/\s+/).map(E=>document.getElementById(E)?.textContent?.trim()||"").filter(Boolean);if(y.length){const E=y.join(" ");return E.length>100?E.substring(0,100)+"...":E}}if(h==="select"){const y=n,E=y.querySelector("option[selected]")||(y.selectedIndex>=0?y.options[y.selectedIndex]:null);if(E?.textContent?.trim())return E.textContent.trim()}const L=n.getAttribute("aria-label");if(L?.trim())return L.trim();const N=n.getAttribute("placeholder");if(N?.trim())return N.trim();const D=n.getAttribute("title");if(D?.trim())return D.trim();const k=n.getAttribute("alt");if(k?.trim())return k.trim();if(n.id){const y=document.querySelector(`label[for="${n.id}"]`);if(y?.textContent?.trim())return y.textContent.trim()}if(h==="input"){const y=n,E=n.getAttribute("type")||"",H=n.getAttribute("value");if(E==="submit"&&H?.trim())return H.trim();if(y.value&&y.value.length<50&&y.value.trim())return y.value.trim()}if(["button","a","summary"].includes(h)){let y="";for(const E of n.childNodes)E.nodeType===Node.TEXT_NODE&&(y+=E.textContent);if(y.trim())return y.trim()}if(/^h[1-6]$/.test(h)){const y=n.textContent;if(y?.trim()){const E=y.trim();return E.length>100?E.substring(0,100)+"...":E}}if(h==="img")return"";let S="";for(const y of n.childNodes)y.nodeType===Node.TEXT_NODE&&(S+=y.textContent);if(S?.trim()&&S.trim().length>=3){const y=S.trim();return y.length>100?y.substring(0,100)+"...":y}return""},l=function(n){const h={},_=n.getAttribute("aria-checked");_==="true"?h.checked=!0:_==="false"?h.checked=!1:_==="mixed"?h.checked="mixed":n instanceof HTMLInputElement&&(n.type==="checkbox"||n.type==="radio")&&(n.type==="checkbox"&&n.indeterminate?h.checked="mixed":h.checked=n.checked);const L=n instanceof HTMLButtonElement||n instanceof HTMLInputElement||n instanceof HTMLSelectElement||n instanceof HTMLTextAreaElement;(n.getAttribute("aria-disabled")==="true"||L&&n.disabled||n.closest("fieldset:disabled"))&&(h.disabled=!0);const N=n.getAttribute("aria-expanded");N==="true"?h.expanded=!0:N==="false"&&(h.expanded=!1);const D=n.getAttribute("aria-pressed");D==="true"?h.pressed=!0:D==="false"?h.pressed=!1:D==="mixed"&&(h.pressed="mixed");const k=n.getAttribute("aria-selected");k==="true"?h.selected=!0:k==="false"&&(h.selected=!1);const S=n.getAttribute("aria-current");S&&S!=="false"&&(h.active=!0);const y=n.tagName.toLowerCase();if(/^h[1-6]$/.test(y))h.level=parseInt(y[1],10);else{const E=n.getAttribute("aria-level");E&&(h.level=parseInt(E,10))}return h},u=function(n){const h=[];return n.checked!==void 0&&h.push(n.checked==="mixed"?"[checked=mixed]":n.checked?"[checked]":"[unchecked]"),n.disabled&&h.push("[disabled]"),n.expanded!==void 0&&h.push(n.expanded?"[expanded]":"[collapsed]"),n.pressed!==void 0&&h.push(n.pressed==="mixed"?"[pressed=mixed]":n.pressed?"[pressed]":"[not-pressed]"),n.selected!==void 0&&h.push(n.selected?"[selected]":"[not-selected]"),n.active&&h.push("[active]"),n.level!==void 0&&h.push(`[level=${n.level}]`),h.join(" ")},d=function(n){const h=window.getComputedStyle(n);return h.display!=="none"&&h.visibility!=="hidden"&&h.opacity!=="0"&&n.offsetWidth>0&&n.offsetHeight>0},w=function(n){const h=n.tagName.toLowerCase();return["a","button","input","select","textarea","details","summary"].includes(h)||n.hasAttribute("onclick")||n.hasAttribute("tabindex")||n.getAttribute("role")==="button"||n.getAttribute("role")==="link"||n.getAttribute("contenteditable")==="true"},a=function(n){const h=n.tagName.toLowerCase();return["h1","h2","h3","h4","h5","h6","nav","main","header","footer","section","article","aside"].includes(h)||n.hasAttribute("role")},f=function(n){return window.getComputedStyle(n).cursor==="pointer"},m=function(n,h){const _=n.tagName.toLowerCase();if(["script","style","meta","link","title","noscript"].includes(_)||h.filter!=="all"&&n.getAttribute("aria-hidden")==="true"||h.filter!=="all"&&!d(n))return!1;if(h.filter!=="all"&&!h.refId){const N=n.getBoundingClientRect();if(!(N.top<window.innerHeight&&N.bottom>0&&N.left<window.innerWidth&&N.right>0))return!1}if(h.filter==="interactive")return w(n);if(w(n)||a(n)||t(n).length>0)return!0;const L=o(n);return h.compact&&new Set(["generic","group","region","article","section","complementary"]).has(L)&&t(n).length===0?!1:L!=="generic"&&L!=="img"},b=function(n,h){const _=[],L={filter:i,refId:r||null,compact:c},N=I(),D=m(n,L)||r&&h===0;if(D){const k=o(n),S=t(n),y=l(n),E=q(n,k,S);window.__piRefs[E]=n,N[E]={element:new WeakRef(n),role:k,name:S};let W=`${" ".repeat(h)}${k}`;if(S){const K=S.replace(/\s+/g," ").replace(/"/g,'\\"');W+=` "${K}"`}W+=` [${E}]`;const R=u(y);R&&(W+=` ${R}`),f(n)&&(W+=" [cursor=pointer]");const P=n.getAttribute("href");P&&(W+=` href="${P}"`);const G=n.getAttribute("type");G&&(W+=` type="${G}"`);const V=n.getAttribute("placeholder");V&&(W+=` placeholder="${V}"`),_.push(W)}if(h<g)for(const k of n.children)_.push(...b(k,D?h+1:h));return _},s=function(n){return n.replace(/\[e\d+\]/g,"[REF]")},p=function(n){const h=new Map;for(const _ of n){if(!_.trim())continue;const L=s(_);h.set(L,(h.get(L)||0)+1)}return h},T=function(n,h){const _=n.split(`
|
|
2
|
+
`),L=h.split(`
|
|
3
|
+
`),N=p(_),D=p(L),k=[],S=[];for(const H of L){if(!H.trim())continue;const W=s(H),R=N.get(W)||0;(D.get(W)||0)>R&&(k.push(H),N.set(W,R+1))}const y=p(_);for(const H of _){if(!H.trim())continue;const W=s(H),R=y.get(W)||0,P=D.get(W)||0;R>P&&(S.push(H),y.set(W,R-1))}if(k.length===0&&S.length===0)return{diff:"[NO CHANGES]",hasChanges:!1};const E=[];return S.length>0&&E.push(...S.map(H=>`- ${H}`)),k.length>0&&E.push(...k.map(H=>`+ ${H}`)),{diff:E.join(`
|
|
4
|
+
`),hasChanges:!0}};window.__piRefs={};const A=I();let C=null;if(r){const n=A[r];if(!n)return{error:`Element with ref_id '${r}' not found. Use read_page without ref_id to get current elements.`,pageContent:"",viewport:{width:window.innerWidth,height:window.innerHeight}};const h=n.element.deref();if(!h)return delete A[r],{error:`Element with ref_id '${r}' no longer exists. Use read_page without ref_id to get current elements.`,pageContent:"",viewport:{width:window.innerWidth,height:window.innerHeight}};C=h}else C=document.body;const O=C?b(C,0):[];for(const n of Object.keys(A))A[n].element.deref()||delete A[n];const $=O.join(`
|
|
5
|
+
`);if($.length>5e4)return{error:`Output exceeds 50000 character limit (${$.length} characters). Try using filter="interactive" or specify a ref_id.`,pageContent:"",viewport:{width:window.innerWidth,height:window.innerHeight}};const M=Y();let x,v=!1;const F=window.__piLastSnapshot;return!e&&!r&&F&&Date.now()-F.timestamp<5e3&&(x=T(F.content,$).diff,v=!0),window.__piLastSnapshot={content:$,timestamp:Date.now()},{pageContent:$+`
|
|
6
6
|
|
|
7
|
-
[Viewport: ${window.innerWidth}x${window.innerHeight}]`,diff:
|
|
8
|
-
`);return
|
|
7
|
+
[Viewport: ${window.innerWidth}x${window.innerHeight}]`,diff:v?x:void 0,viewport:{width:window.innerWidth,height:window.innerHeight},modalStates:M.length>0?M:void 0,modalLimitations:"Only custom modals ([role=dialog]) detected. Native alert/confirm/prompt dialogs and system file choosers cannot be detected from content scripts.",isIncremental:v}}catch(o){return{error:`Error generating accessibility tree: ${o instanceof Error?o.message:"Unknown error"}`,pageContent:"",viewport:{width:window.innerWidth,height:window.innerHeight}}}}function z(i){return i.length?/[\n\r]/.test(i)||/^[\s]/.test(i)||/[\s]$/.test(i)||/[:"{}[\]]/.test(i)?'"'+i.replace(/\\/g,"\\\\").replace(/"/g,'\\"').replace(/\n/g,"\\n").replace(/\r/g,"\\r")+'"':i:'""'}function te(i="interactive",g=15){try{let r=function(s){return U(s)},e=function(s){const p=s.tagName.toLowerCase(),T=s.getAttribute("aria-labelledby");if(T){const x=T.split(/\s+/).map(v=>document.getElementById(v)?.textContent?.trim()||"").filter(Boolean);if(x.length){const v=x.join(" ");return v.length>100?v.substring(0,100)+"...":v}}if(p==="select"){const x=s,v=x.querySelector("option[selected]")||(x.selectedIndex>=0?x.options[x.selectedIndex]:null);if(v?.textContent?.trim())return v.textContent.trim()}const A=s.getAttribute("aria-label");if(A?.trim())return A.trim();const C=s.getAttribute("placeholder");if(C?.trim())return C.trim();const O=s.getAttribute("title");if(O?.trim())return O.trim();const $=s.getAttribute("alt");if($?.trim())return $.trim();if(s.id){const x=document.querySelector(`label[for="${s.id}"]`);if(x?.textContent?.trim())return x.textContent.trim()}if(p==="input"){const x=s,v=s.getAttribute("type")||"",F=s.getAttribute("value");if(v==="submit"&&F?.trim())return F.trim();if(x.value&&x.value.length<50&&x.value.trim())return x.value.trim()}if(["button","a","summary"].includes(p)){let x="";for(const v of s.childNodes)v.nodeType===Node.TEXT_NODE&&(x+=v.textContent);if(x.trim())return x.trim()}if(/^h[1-6]$/.test(p)){const x=s.textContent;if(x?.trim()){const v=x.trim();return v.length>100?v.substring(0,100)+"...":v}}if(p==="img")return"";let M="";for(const x of s.childNodes)x.nodeType===Node.TEXT_NODE&&(M+=x.textContent);if(M?.trim()&&M.trim().length>=3){const x=M.trim();return x.length>100?x.substring(0,100)+"...":x}return""},c=function(s){const p={},T=s.getAttribute("aria-checked");T==="true"?p.checked=!0:T==="false"?p.checked=!1:T==="mixed"?p.checked="mixed":s instanceof HTMLInputElement&&(s.type==="checkbox"||s.type==="radio")&&(s.type==="checkbox"&&s.indeterminate?p.checked="mixed":p.checked=s.checked);const A=s instanceof HTMLButtonElement||s instanceof HTMLInputElement||s instanceof HTMLSelectElement||s instanceof HTMLTextAreaElement;(s.getAttribute("aria-disabled")==="true"||A&&s.disabled||s.closest("fieldset:disabled"))&&(p.disabled=!0);const C=s.getAttribute("aria-expanded");C==="true"?p.expanded=!0:C==="false"&&(p.expanded=!1);const O=s.getAttribute("aria-pressed");O==="true"?p.pressed=!0:O==="false"?p.pressed=!1:O==="mixed"&&(p.pressed="mixed");const $=s.getAttribute("aria-selected");$==="true"?p.selected=!0:$==="false"&&(p.selected=!1);const M=s.getAttribute("aria-current");M&&M!=="false"&&(p.active=!0);const x=s.tagName.toLowerCase();if(/^h[1-6]$/.test(x))p.level=parseInt(x[1],10);else{const v=s.getAttribute("aria-level");v&&(p.level=parseInt(v,10))}return p},o=function(s){const p=[];return s.checked!==void 0&&p.push(s.checked==="mixed"?"[checked=mixed]":s.checked?"[checked]":"[unchecked]"),s.disabled&&p.push("[disabled]"),s.expanded!==void 0&&p.push(s.expanded?"[expanded]":"[collapsed]"),s.pressed!==void 0&&p.push(s.pressed==="mixed"?"[pressed=mixed]":s.pressed?"[pressed]":"[not-pressed]"),s.selected!==void 0&&p.push(s.selected?"[selected]":"[not-selected]"),s.active&&p.push("[active]"),s.level!==void 0&&p.push(`[level=${s.level}]`),p.join(" ")},t=function(s){const p=window.getComputedStyle(s);return p.display!=="none"&&p.visibility!=="hidden"&&p.opacity!=="0"&&s.offsetWidth>0&&s.offsetHeight>0},l=function(s){const p=s.tagName.toLowerCase();return["a","button","input","select","textarea","details","summary"].includes(p)||s.hasAttribute("onclick")||s.hasAttribute("tabindex")||s.getAttribute("role")==="button"||s.getAttribute("role")==="link"||s.getAttribute("contenteditable")==="true"},u=function(s){const p=s.tagName.toLowerCase();return["h1","h2","h3","h4","h5","h6","nav","main","header","footer","section","article","aside"].includes(p)||s.hasAttribute("role")},d=function(s){return window.getComputedStyle(s).cursor==="pointer"},w=function(s,p,T,A){let C=s;p&&(C+=" "+z(p));const O=q(T,s,p);window.__piRefs[O]=T,C+=` [ref=${O}]`;const $=o(A);return $&&(C+=` ${$}`),d(T)&&(C+=" [cursor=pointer]"),C},a=function(s){const p={},T=s.getAttribute("href");T&&(p.url=T);const A=s.getAttribute("placeholder");return A&&(p.placeholder=A),p},f=function(s,p,T){if(p>g)return;const A=s.tagName.toLowerCase();if(["script","style","meta","link","title","noscript"].includes(A)||i!=="all"&&s.getAttribute("aria-hidden")==="true"||i!=="all"&&!t(s))return;if(i!=="all"){const n=s.getBoundingClientRect();if(!(n.top<window.innerHeight&&n.bottom>0&&n.left<window.innerWidth&&n.right>0))return}const C=r(s),O=e(s),$=c(s),M=l(s),x=u(s),v=O.length>0;let F;if(i==="interactive"?F=M:i==="all"?F=!0:F=M||x||v||C!=="generic"&&C!=="img",F){const n=" ".repeat(p),h=w(C,O,s,$),_=a(s),L=[];for(const k of s.children)L.push(k);const N=L.length>0,D=Object.keys(_).length>0;if(!N&&!D)m.push(`${n}- ${h}`);else{m.push(`${n}- ${h}:`);for(const[k,S]of Object.entries(_))m.push(`${n} - /${k}: ${z(S)}`);for(const k of L)f(k,p+1,!0)}}else for(const n of s.children)f(n,p,T)};window.__piRefs={};const m=[];f(document.body,0,!1);const b=m.join(`
|
|
8
|
+
`);return b.length>5e4?{error:`Output exceeds 50000 character limit (${b.length} characters). Try using filter="interactive".`,yaml:"",viewport:{width:window.innerWidth,height:window.innerHeight}}:{yaml:b+`
|
|
9
9
|
|
|
10
|
-
[Viewport: ${window.innerWidth}x${window.innerHeight}]`,viewport:{width:window.innerWidth,height:window.innerHeight}}}catch(r){return{error:`Error generating YAML tree: ${r instanceof Error?r.message:"Unknown error"}`,yaml:"",viewport:{width:window.innerWidth,height:window.innerHeight}}}}function ne(i){const m=O(),r=m[i];let w;if(r&&(w=r.element.deref(),w||delete m[i]),!w&&window.__piRefs&&(w=window.__piRefs[i]),!w)return{x:0,y:0,error:`Element ${i} not found. Use read_page to get current elements.`};const y=w.getBoundingClientRect(),g=Math.round(y.left+y.width/2),e=Math.round(y.top+y.height/2);return{x:g,y:e}}function re(i,m){var e;const r=O(),w=r[i];let y;if(w&&(y=w.element.deref(),y||delete r[i]),!y&&window.__piRefs&&(y=window.__piRefs[i]),!y)return{success:!1,error:`Element ${i} not found. Use read_page to get current elements.`};const g=y.tagName.toLowerCase();try{if(g==="input"){const c=y,l=c.type.toLowerCase();l==="checkbox"||l==="radio"?(c.checked=!!m,c.dispatchEvent(new Event("change",{bubbles:!0}))):(c.value=String(m),c.dispatchEvent(new Event("input",{bubbles:!0})),c.dispatchEvent(new Event("change",{bubbles:!0})))}else if(g==="textarea"){const c=y;c.value=String(m),c.dispatchEvent(new Event("input",{bubbles:!0})),c.dispatchEvent(new Event("change",{bubbles:!0}))}else if(g==="select"){const c=y,l=String(m);let s=!1;for(const d of c.options)if(d.value===l||((e=d.textContent)==null?void 0:e.trim())===l){c.value=d.value,s=!0;break}if(!s)return{success:!1,error:`Option "${m}" not found in select element ${i}`};c.dispatchEvent(new Event("change",{bubbles:!0}))}else if(y.getAttribute("contenteditable")==="true")y.textContent=String(m),y.dispatchEvent(new Event("input",{bubbles:!0}));else return{success:!1,error:`Element ${i} (${g}) is not a form field`};return{success:!0}}catch(c){return{success:!1,error:`Failed to set value: ${c instanceof Error?c.message:"Unknown error"}`}}}function ie(){var i;try{const m=document.querySelector("article"),r=document.querySelector("main");return{text:((i=(m||r||document.body).textContent)==null?void 0:i.replace(/\s+/g," ").trim().substring(0,5e4))||"",title:document.title,url:window.location.href}}catch(m){return{text:"",title:"",url:"",error:`Failed to extract text: ${m instanceof Error?m.message:"Unknown error"}`}}}function oe(i){const m=O(),r=m[i];let w;return r&&(w=r.element.deref(),w||delete m[i]),!w&&window.__piRefs&&(w=window.__piRefs[i]),w?(w.scrollIntoView({behavior:"smooth",block:"center"}),{success:!0}):{success:!1,error:`Element ${i} not found. Run read_page to get current element refs.`}}function se(i,m,r,w="screenshot.png"){try{const y=atob(i),g=new ArrayBuffer(y.length),e=new Uint8Array(g);for(let h=0;h<y.length;h++)e[h]=y.charCodeAt(h);const c=new Blob([g],{type:"image/png"}),l=new File([c],w,{type:"image/png"});let s=null;if(m){const h=O(),b=h[m];if(b&&(s=b.element.deref(),s||delete h[m]),!s&&window.__piRefs&&(s=window.__piRefs[m]),!s)return{success:!1,error:`Element ${m} not found. Run read_page to get current element refs.`}}else if(r&&(s=document.elementFromPoint(r[0],r[1]),!s))return{success:!1,error:`No element at (${r[0]}, ${r[1]})`};if(!s)return{success:!1,error:"No target element"};if(s.tagName==="INPUT"&&s.type==="file"){const h=s,b=new DataTransfer;return b.items.add(l),h.files=b.files,h.dispatchEvent(new Event("change",{bubbles:!0})),{success:!0}}const d=new DataTransfer;d.items.add(l);const u=new DragEvent("drop",{bubbles:!0,cancelable:!0,dataTransfer:d});return s.dispatchEvent(u),{success:!0}}catch(y){return{success:!1,error:y instanceof Error?y.message:"Upload failed"}}}chrome.runtime.onMessage.addListener((i,m,r)=>{var w,y,g;switch(i.type){case"GENERATE_ACCESSIBILITY_TREE":{const e=i.options||{};if(e.format==="yaml"){const c=te(e.filter||"interactive",e.depth??15),l=Y();c.error?r({error:c.error,pageContent:"",viewport:c.viewport}):r({pageContent:c.yaml,viewport:c.viewport,modalStates:l.length>0?l:void 0,modalLimitations:"Only custom modals ([role=dialog]) detected. Native alert/confirm/prompt dialogs and system file choosers cannot be detected from content scripts."})}else{const c=B(e.filter||"interactive",e.depth??15,e.refId,e.forceFullSnapshot??!1,e.compact??!1);r(c)}break}case"GET_ELEMENT_COORDINATES":{const e=ne(i.ref);r(e);break}case"CLICK_ELEMENT":{const e=O(),c=e[i.ref];let l;if(c&&(l=c.element.deref(),l||delete e[i.ref]),!l&&window.__piRefs&&(l=window.__piRefs[i.ref]),!l){r({error:`Element ${i.ref} not found. Use read_page to get current elements.`});break}if(i.button==="triple"){const s=new MouseEvent("click",{bubbles:!0,cancelable:!0,view:window,detail:3});l.dispatchEvent(s)}else i.button==="double"?l.dispatchEvent(new MouseEvent("dblclick",{bubbles:!0,cancelable:!0,view:window})):i.button==="right"?l.dispatchEvent(new MouseEvent("contextmenu",{bubbles:!0,cancelable:!0,view:window})):l.click();r({success:!0});break}case"FORM_INPUT":{const e=re(i.ref,i.value);r(e);break}case"EVAL_IN_PAGE":{try{const e=document.createElement("script");e.textContent=`(function() { ${i.code} })();`,document.documentElement.appendChild(e),e.remove(),r({success:!0})}catch(e){r({success:!1,error:e instanceof Error?e.message:String(e)})}break}case"GET_PAGE_TEXT":{const e=ie();r(e);break}case"GET_FRAME_BY_SELECTOR":{try{const e=document.querySelector(i.selector);if(!e||e.tagName.toLowerCase()!=="iframe"){r({error:`No iframe found with selector "${i.selector}"`});break}r({url:e.src,name:e.name||void 0})}catch(e){r({error:e instanceof Error?e.message:String(e)})}break}case"GET_FRAME_NAME":{try{r({name:window.name||null})}catch{r({name:null})}break}case"LOCATE_ROLE":{try{const{role:e,name:c,all:l}=i,s=O(),u={button:["button",'input[type="button"]','input[type="submit"]','input[type="reset"]','[role="button"]'],link:["a[href]",'[role="link"]'],textbox:["input:not([type])",'input[type="text"]','input[type="email"]','input[type="password"]','input[type="search"]','input[type="tel"]','input[type="url"]',"textarea",'[role="textbox"]'],checkbox:['input[type="checkbox"]','[role="checkbox"]'],radio:['input[type="radio"]','[role="radio"]'],combobox:["select",'[role="combobox"]'],listbox:['[role="listbox"]',"select[multiple]"],option:["option",'[role="option"]'],heading:["h1","h2","h3","h4","h5","h6",'[role="heading"]'],navigation:["nav",'[role="navigation"]'],main:["main",'[role="main"]'],img:["img[alt]",'[role="img"]'],dialog:["dialog",'[role="dialog"]','[role="alertdialog"]'],tab:['[role="tab"]'],tabpanel:['[role="tabpanel"]'],menu:['[role="menu"]'],menuitem:['[role="menuitem"]']}[e]||[`[role="${e}"]`],h=[];for(const o of u)try{h.push(...document.querySelectorAll(o))}catch{}const b=h.filter(o=>{const p=window.getComputedStyle(o);return p.display!=="none"&&p.visibility!=="hidden"&&o.offsetWidth>0&&o.offsetHeight>0});let a=b;if(c){const o=c.toLowerCase();a=b.filter(p=>{var D,W,x,n,f;const v=(D=p.getAttribute("aria-label"))==null?void 0:D.toLowerCase(),_=(W=p.textContent)==null?void 0:W.trim().toLowerCase(),S=(x=p.getAttribute("title"))==null?void 0:x.toLowerCase(),A=(n=p.placeholder)==null?void 0:n.toLowerCase(),L=(f=p.value)==null?void 0:f.toLowerCase();return(v==null?void 0:v.includes(o))||(_==null?void 0:_.includes(o))||(S==null?void 0:S.includes(o))||(A==null?void 0:A.includes(o))||(L==null?void 0:L.includes(o))})}if(a.length===0){r({error:`No element found with role "${e}"${c?` and name "${c}"`:""}`});break}const t=a.map(o=>{var v;const p=q(o,e,c||"");return window.__piRefs=window.__piRefs||{},window.__piRefs[p]=o,s[p]={element:new WeakRef(o),role:e,name:c||""},{ref:p,text:(v=o.textContent)==null?void 0:v.trim().slice(0,50)}});r(l?{matches:t}:{ref:t[0].ref,text:t[0].text})}catch(e){r({error:e instanceof Error?e.message:String(e)})}break}case"LOCATE_TEXT":{try{const{text:e,exact:c}=i,l=O(),s=document.createTreeWalker(document.body,NodeFilter.SHOW_TEXT),d=[];for(;s.nextNode();){const a=s.currentNode.textContent||"";if(c?a.trim()===e:a.toLowerCase().includes(e.toLowerCase())){const o=s.currentNode.parentElement;if(o&&!d.includes(o)){const p=window.getComputedStyle(o);p.display!=="none"&&p.visibility!=="hidden"&&d.push(o)}}}if(d.length===0){r({error:`No element found with text "${e}"`});break}const u=d.sort((a,t)=>{var o,p;return(((o=a.textContent)==null?void 0:o.length)||0)-(((p=t.textContent)==null?void 0:p.length)||0)})[0],h=U(u),b=q(u,h,e);window.__piRefs=window.__piRefs||{},window.__piRefs[b]=u,l[b]={element:new WeakRef(u),role:h,name:e},r({ref:b,text:(w=u.textContent)==null?void 0:w.trim().slice(0,50)})}catch(e){r({error:e instanceof Error?e.message:String(e)})}break}case"LOCATE_LABEL":{try{const{label:e}=i,c=O(),l=document.querySelectorAll("label");let s=null;for(const h of l){const b=(y=h.textContent)==null?void 0:y.trim().toLowerCase();if(b!=null&&b.includes(e.toLowerCase())){const a=h.getAttribute("for");if(a&&(s=document.getElementById(a)),s||(s=h.querySelector("input, select, textarea")),s)break}}if(!s){const h=e.toLowerCase();s=document.querySelector(`input[aria-label*="${e}" i], input[placeholder*="${e}" i], textarea[aria-label*="${e}" i], textarea[placeholder*="${e}" i], select[aria-label*="${e}" i]`)}if(!s){r({error:`No form field found with label "${e}"`});break}const d=U(s),u=q(s,d,e);window.__piRefs=window.__piRefs||{},window.__piRefs[u]=s,c[u]={element:new WeakRef(s),role:d,name:e},r({ref:u,label:e})}catch(e){r({error:e instanceof Error?e.message:String(e)})}break}case"GET_ELEMENT_STYLES":{try{const{selector:e}=i,c=O(),l=s=>{var h;const d=getComputedStyle(s),u=s.getBoundingClientRect();return{tag:s.tagName.toLowerCase(),text:((h=s.innerText)==null?void 0:h.trim().slice(0,80))||null,box:{x:Math.round(u.x),y:Math.round(u.y),width:Math.round(u.width),height:Math.round(u.height)},styles:{fontSize:d.fontSize,fontWeight:d.fontWeight,fontFamily:d.fontFamily.split(",")[0].trim().replace(/"/g,""),color:d.color,backgroundColor:d.backgroundColor,borderRadius:d.borderRadius,border:d.border!=="none"&&d.borderWidth!=="0px"?d.border:null,boxShadow:d.boxShadow!=="none"?d.boxShadow:null,padding:d.padding}}};if(/^e\d+$/.test(e)){const s=c[e];let d;if(s&&(d=s.element.deref(),d||delete c[e]),!d&&window.__piRefs&&(d=window.__piRefs[e]),!d){r({error:`Element ${e} not found`});break}r({styles:[l(d)]})}else{const s=document.querySelectorAll(e);if(s.length===0){r({error:`No elements found matching "${e}"`});break}const d=Array.from(s).map(l);r({styles:d})}}catch(e){r({error:e instanceof Error?e.message:String(e)})}break}case"SELECT_OPTION":{try{const{selector:e,values:c,by:l}=i,s=O();let d=null;if(/^e\d+$/.test(e)){const a=s[e];let t;if(a&&(t=a.element.deref(),t||delete s[e]),!t&&window.__piRefs&&(t=window.__piRefs[e]),!t){r({error:`Element ${e} not found`});break}if(t.tagName!=="SELECT"){r({error:`Element ${e} is not a <select>`});break}d=t}else{if(d=document.querySelector(e),!d){r({error:`No element found matching "${e}"`});break}if(d.tagName!=="SELECT"){r({error:`Element "${e}" is not a <select>`});break}}if(d.multiple)for(const a of d.options)a.selected=!1;const u=[],h=[],b=d.multiple?c:[c[0]];for(const a of b){let t=!1;for(const o of d.options){let p=!1;if(l==="index"?p=o.index===parseInt(a,10):l==="label"?p=o.text.toLowerCase().includes(a.toLowerCase()):p=o.value===a,p){o.selected=!0,u.push(o.value),t=!0;break}}t||h.push(a)}d.dispatchEvent(new Event("change",{bubbles:!0})),h.length>0?r({selected:u,warning:`Values not found: ${h.join(", ")}`}):r({selected:u})}catch(e){r({error:e instanceof Error?e.message:String(e)})}break}case"GET_ELEMENT_TEXT":{try{const{ref:e}=i,c=O(),l=c[e];let s;if(l&&(s=l.element.deref(),s||delete c[e]),!s&&window.__piRefs&&(s=window.__piRefs[e]),!s){r({error:`Element ${e} not found`});break}r({text:((g=s.textContent)==null?void 0:g.trim())||""})}catch(e){r({error:e instanceof Error?e.message:String(e)})}break}case"SCROLL_TO_ELEMENT":{const e=oe(i.ref);r(e);break}case"UPLOAD_IMAGE":{const e=se(i.base64,i.ref,i.coordinate,i.filename);r(e);break}case"WAIT_FOR_ELEMENT":{const{selector:e,state:c="visible",timeout:l=2e4}=i,s=Math.min(l,6e4),d=a=>{if(!a)return!1;const t=window.getComputedStyle(a);return t.display!=="none"&&t.visibility!=="hidden"&&t.opacity!=="0"&&a.offsetWidth>0&&a.offsetHeight>0},u=()=>{const a=document.querySelector(e);switch(c){case"attached":return!!a;case"detached":return!a;case"hidden":return!a||!d(a);case"visible":default:return d(a)}},h=Date.now();return new Promise(a=>{if(u()){a({success:!0,waited:Date.now()-h});return}const t=new MutationObserver(()=>{u()&&(t.disconnect(),clearTimeout(o),a({success:!0,waited:Date.now()-h}))}),o=setTimeout(()=>{t.disconnect(),a({success:!1,waited:Date.now()-h,error:`Timeout waiting for "${e}" to be ${c}`})},s);t.observe(document.documentElement,{childList:!0,subtree:!0,attributes:!0,attributeFilter:["style","class","hidden","disabled"]})}).then(a=>{if(!a.success){r({error:a.error,waited:a.waited,pageContent:"",viewport:{width:window.innerWidth,height:window.innerHeight}});return}const t=B("interactive",15,void 0,!0);r({...t,waited:a.waited})}),!0}case"WAIT_FOR_URL":{const{pattern:e,timeout:c=2e4}=i,l=Math.min(c,6e4),s=h=>{if(e.includes("*")){const b=e.replace(/[.+?^${}()|[\]\\]/g,"\\$&").replace(/\*\*/g,"<<<GLOBSTAR>>>").replace(/\*/g,"[^/]*").replace(/<<<GLOBSTAR>>>/g,".*");return new RegExp(`^${b}$`).test(h)}return h.includes(e)},d=Date.now();return new Promise(h=>{if(s(window.location.href)){h({success:!0,waited:Date.now()-d});return}let b=!1;const a=()=>{b||s(window.location.href)&&(b=!0,clearInterval(t),clearTimeout(o),window.removeEventListener("popstate",a),window.removeEventListener("hashchange",a),h({success:!0,waited:Date.now()-d}))},t=setInterval(a,100),o=setTimeout(()=>{b||(b=!0,clearInterval(t),window.removeEventListener("popstate",a),window.removeEventListener("hashchange",a),h({success:!1,waited:Date.now()-d,error:`Timeout waiting for URL to match "${e}". Current: ${window.location.href}`}))},l);window.addEventListener("popstate",a),window.addEventListener("hashchange",a)}).then(h=>{if(!h.success){r({error:h.error,waited:h.waited,pageContent:"",viewport:{width:window.innerWidth,height:window.innerHeight}});return}const b=B("interactive",15,void 0,!0);r({...b,waited:h.waited})}),!0}case"WAIT_FOR_DOM_STABLE":{const{stable:e=100,timeout:c=5e3}=i,l=Math.min(c,3e4),s=Date.now();return new Promise(u=>{let h=Date.now(),b=!1;const a=()=>{if(b)return;Date.now()-h>=e&&(b=!0,t.disconnect(),clearTimeout(o),clearInterval(p),u({success:!0,waited:Date.now()-s}))},t=new MutationObserver(()=>{h=Date.now()}),o=setTimeout(()=>{b||(b=!0,t.disconnect(),clearInterval(p),u({success:!1,waited:Date.now()-s,error:`Timeout: DOM did not stabilize within ${l}ms`}))},l),p=setInterval(a,Math.max(10,Math.min(50,e/2)));t.observe(document.documentElement,{childList:!0,subtree:!0,attributes:!0,characterData:!0}),a()}).then(u=>{if(!u.success){r({error:u.error,waited:u.waited,pageContent:"",viewport:{width:window.innerWidth,height:window.innerHeight}});return}const h=B("interactive",15,void 0,!0);r({...h,waited:u.waited})}),!0}case"FORM_FILL":{const{data:e}=i;if(!Array.isArray(e))return r({error:"data must be an array of {ref, value} pairs"}),!0;const c=O(),l=[];for(const d of e){const{ref:u,value:h}=d;if(!u){l.push({ref:u||"unknown",success:!1,error:"Missing ref"});continue}const b=c[u];if(!b){l.push({ref:u,success:!1,error:"Element not found (run page.read first)"});continue}const a=b.element.deref();if(!a){delete c[u],l.push({ref:u,success:!1,error:"Element no longer exists"});continue}try{if(a instanceof HTMLInputElement){const t=a.type.toLowerCase();if(t==="checkbox"||t==="radio"){const o=h===!0||h==="true"||h==="1"||h==="checked";a.checked=o,a.dispatchEvent(new Event("change",{bubbles:!0}))}else a.focus(),a.value=String(h),a.dispatchEvent(new Event("input",{bubbles:!0})),a.dispatchEvent(new Event("change",{bubbles:!0}));l.push({ref:u,success:!0})}else a instanceof HTMLTextAreaElement?(a.focus(),a.value=String(h),a.dispatchEvent(new Event("input",{bubbles:!0})),a.dispatchEvent(new Event("change",{bubbles:!0})),l.push({ref:u,success:!0})):a instanceof HTMLSelectElement?(a.value=String(h),a.dispatchEvent(new Event("change",{bubbles:!0})),l.push({ref:u,success:!0})):a.isContentEditable?(a.focus(),a.textContent=String(h),a.dispatchEvent(new Event("input",{bubbles:!0})),l.push({ref:u,success:!0})):l.push({ref:u,success:!1,error:"Element is not fillable"})}catch(t){l.push({ref:u,success:!1,error:t instanceof Error?t.message:String(t)})}}const s=l.filter(d=>!d.success);return r({success:s.length===0,filled:l.filter(d=>d.success).length,failed:s.length,results:l}),!0}case"GET_FILE_INPUT_SELECTOR":{const{ref:e}=i;if(!e)return r({error:"No ref provided"}),!0;const c=O(),l=c[e];if(!l)return r({error:"Element not found (run page.read first)"}),!0;const s=l.element.deref();if(!s)return delete c[e],r({error:"Element no longer exists"}),!0;if(!(s instanceof HTMLInputElement)||s.type!=="file")return r({error:"Element is not a file input"}),!0;const d=`__pi_file_${Date.now()}`;return s.setAttribute("data-pi-file-id",d),r({selector:`[data-pi-file-id="${d}"]`}),!0}case"WAIT_FOR_NETWORK_IDLE":{const{timeout:e=1e4}=i,c=Math.min(e,6e4),l=["doubleclick.net","googlesyndication.com","googletagmanager.com","google-analytics.com","facebook.net","connect.facebook.net","analytics","ads","tracking","pixel","hotjar.com","clarity.ms","mixpanel.com","segment.com","newrelic.com","nr-data.net","/tracker/","/collector/","/beacon/","/telemetry/","/log/","/events/","/track.","/metrics/"],s=["img","image","font","icon"],d=t=>l.some(o=>t.includes(o)),u=t=>{const o=t.initiatorType||"unknown";return!!(s.includes(o)||/\.(jpg|jpeg|png|gif|webp|svg|ico|woff|woff2|ttf|eot)(\?|$)/i.test(t.name))},h=()=>{const t=performance.now();return performance.getEntriesByType("resource").filter(p=>{if(p.responseEnd!==0||p.name.startsWith("data:")||p.name.length>500||d(p.name))return!1;const v=t-p.startTime;return!(v>1e4||u(p)&&v>3e3)})},b=Date.now();return new Promise(t=>{const o=()=>{const p=h(),v=Date.now()-b;if(p.length===0){t({success:!0,waited:v});return}if(v>=c){t({success:!1,waited:v,pendingCount:p.length});return}setTimeout(o,100)};o()}).then(t=>{if(!t.success){r({error:`Network not idle after ${t.waited}ms (${t.pendingCount} requests pending)`,waited:t.waited,pageContent:"",viewport:{width:window.innerWidth,height:window.innerHeight}});return}const o=B("interactive",15,void 0,!0);r({...o,waited:t.waited})}),!0}case"SEARCH_PAGE":{const{term:e,caseSensitive:c,limit:l}=i,s=ce(e,c||!1,l||10);r({query:e,count:s.length,matches:s});break}case"GET_ELEMENT_BOUNDS_FOR_ANNOTATION":{const e=O(),c=[];for(const[l,s]of Object.entries(e)){const d=s.element.deref();if(!d)continue;const u=d.getBoundingClientRect();u.width<=0||u.height<=0||u.bottom<0||u.top>window.innerHeight||u.right<0||u.left>window.innerWidth||c.push({ref:l,tag:d.tagName.toLowerCase(),bounds:{x:u.x,y:u.y,width:u.width,height:u.height}})}r({elements:c});break}default:return!1}return!1});function ce(i,m,r){const w=[],y=m?i:i.toLowerCase(),g=document.createTreeWalker(document.body,NodeFilter.SHOW_TEXT),e=O();let c=0;for(;g.nextNode()&&w.length<r;){const l=g.currentNode,s=l.textContent||"",d=m?s:s.toLowerCase();let u=0;for(;(u=d.indexOf(y,u))!==-1&&w.length<r;){const h=l.parentElement;if(!h){u++;continue}const b=document.createRange();b.setStart(l,u),b.setEnd(l,Math.min(u+i.length,s.length));const a=b.getBoundingClientRect();if(a.width===0||a.height===0){u++;continue}const t=l.textContent||"",o=Math.max(0,u-30),p=Math.min(t.length,u+i.length+30),v=t.slice(o,p).trim();let _=null;for(const[S,A]of Object.entries(e)){const L=A.element.deref();if(L&&(L===h||L.contains(h))){_=S;break}}w.push({ref:`m${++c}`,text:t.slice(u,u+i.length),context:v,bounds:{x:Math.round(a.x),y:Math.round(a.y),width:Math.round(a.width),height:Math.round(a.height)},elementRef:_}),u++}}return w}
|
|
10
|
+
[Viewport: ${window.innerWidth}x${window.innerHeight}]`,viewport:{width:window.innerWidth,height:window.innerHeight}}}catch(r){return{error:`Error generating YAML tree: ${r instanceof Error?r.message:"Unknown error"}`,yaml:"",viewport:{width:window.innerWidth,height:window.innerHeight}}}}function re(i){const g=I(),r=g[i];let e;if(r&&(e=r.element.deref(),e||delete g[i]),!e&&window.__piRefs&&(e=window.__piRefs[i]),!e)return{x:0,y:0,error:`Element ${i} not found. Use read_page to get current elements.`};const c=e.getBoundingClientRect(),o=Math.round(c.left+c.width/2),t=Math.round(c.top+c.height/2);return{x:o,y:t}}function ne(i,g){const r=I(),e=r[i];let c;if(e&&(c=e.element.deref(),c||delete r[i]),!c&&window.__piRefs&&(c=window.__piRefs[i]),!c)return{success:!1,error:`Element ${i} not found. Use read_page to get current elements.`};const o=c.tagName.toLowerCase();try{if(o==="input"){const t=c,l=t.type.toLowerCase();l==="checkbox"||l==="radio"?(t.checked=!!g,t.dispatchEvent(new Event("change",{bubbles:!0}))):(t.value=String(g),t.dispatchEvent(new Event("input",{bubbles:!0})),t.dispatchEvent(new Event("change",{bubbles:!0})))}else if(o==="textarea"){const t=c;t.value=String(g),t.dispatchEvent(new Event("input",{bubbles:!0})),t.dispatchEvent(new Event("change",{bubbles:!0}))}else if(o==="select"){const t=c,l=String(g);let u=!1;for(const d of t.options)if(d.value===l||d.textContent?.trim()===l){t.value=d.value,u=!0;break}if(!u)return{success:!1,error:`Option "${g}" not found in select element ${i}`};t.dispatchEvent(new Event("change",{bubbles:!0}))}else if(c.getAttribute("contenteditable")==="true")c.textContent=String(g),c.dispatchEvent(new Event("input",{bubbles:!0}));else return{success:!1,error:`Element ${i} (${o}) is not a form field`};return{success:!0}}catch(t){return{success:!1,error:`Failed to set value: ${t instanceof Error?t.message:"Unknown error"}`}}}function ie(){try{const i=document.querySelector("article"),g=document.querySelector("main");return{text:(i||g||document.body).textContent?.replace(/\s+/g," ").trim().substring(0,5e4)||"",title:document.title,url:window.location.href}}catch(i){return{text:"",title:"",url:"",error:`Failed to extract text: ${i instanceof Error?i.message:"Unknown error"}`}}}function oe(i){const g=I(),r=g[i];let e;return r&&(e=r.element.deref(),e||delete g[i]),!e&&window.__piRefs&&(e=window.__piRefs[i]),e?(e.scrollIntoView({behavior:"smooth",block:"center"}),{success:!0}):{success:!1,error:`Element ${i} not found. Run read_page to get current element refs.`}}function se(i,g,r,e="screenshot.png"){try{const c=atob(i),o=new ArrayBuffer(c.length),t=new Uint8Array(o);for(let f=0;f<c.length;f++)t[f]=c.charCodeAt(f);const l=new Blob([o],{type:"image/png"}),u=new File([l],e,{type:"image/png"});let d=null;if(g){const f=I(),m=f[g];if(m&&(d=m.element.deref(),d||delete f[g]),!d&&window.__piRefs&&(d=window.__piRefs[g]),!d)return{success:!1,error:`Element ${g} not found. Run read_page to get current element refs.`}}else if(r&&(d=document.elementFromPoint(r[0],r[1]),!d))return{success:!1,error:`No element at (${r[0]}, ${r[1]})`};if(!d)return{success:!1,error:"No target element"};if(d.tagName==="INPUT"&&d.type==="file"){const f=d,m=new DataTransfer;return m.items.add(u),f.files=m.files,f.dispatchEvent(new Event("change",{bubbles:!0})),{success:!0}}const w=new DataTransfer;w.items.add(u);const a=new DragEvent("drop",{bubbles:!0,cancelable:!0,dataTransfer:w});return d.dispatchEvent(a),{success:!0}}catch(c){return{success:!1,error:c instanceof Error?c.message:"Upload failed"}}}chrome.runtime.onMessage.addListener((i,g,r)=>{switch(i.type){case"GENERATE_ACCESSIBILITY_TREE":{const e=i.options||{};if(e.format==="yaml"){const c=te(e.filter||"interactive",e.depth??15),o=Y();c.error?r({error:c.error,pageContent:"",viewport:c.viewport}):r({pageContent:c.yaml,viewport:c.viewport,modalStates:o.length>0?o:void 0,modalLimitations:"Only custom modals ([role=dialog]) detected. Native alert/confirm/prompt dialogs and system file choosers cannot be detected from content scripts."})}else{const c=B(e.filter||"interactive",e.depth??15,e.refId,e.forceFullSnapshot??!1,e.compact??!1);r(c)}break}case"GET_ELEMENT_COORDINATES":{const e=re(i.ref);r(e);break}case"CLICK_ELEMENT":{const e=I(),c=e[i.ref];let o;if(c&&(o=c.element.deref(),o||delete e[i.ref]),!o&&window.__piRefs&&(o=window.__piRefs[i.ref]),!o){r({error:`Element ${i.ref} not found. Use read_page to get current elements.`});break}if(i.button==="triple"){const t=new MouseEvent("click",{bubbles:!0,cancelable:!0,view:window,detail:3});o.dispatchEvent(t)}else i.button==="double"?o.dispatchEvent(new MouseEvent("dblclick",{bubbles:!0,cancelable:!0,view:window})):i.button==="right"?o.dispatchEvent(new MouseEvent("contextmenu",{bubbles:!0,cancelable:!0,view:window})):o.click();r({success:!0});break}case"FORM_INPUT":{const e=ne(i.ref,i.value);r(e);break}case"EVAL_IN_PAGE":{try{const e=document.createElement("script");e.textContent=`(function() { ${i.code} })();`,document.documentElement.appendChild(e),e.remove(),r({success:!0})}catch(e){r({success:!1,error:e instanceof Error?e.message:String(e)})}break}case"GET_PAGE_TEXT":{const e=ie();r(e);break}case"GET_FRAME_BY_SELECTOR":{try{const e=document.querySelector(i.selector);if(!e||e.tagName.toLowerCase()!=="iframe"){r({error:`No iframe found with selector "${i.selector}"`});break}r({url:e.src,name:e.name||void 0})}catch(e){r({error:e instanceof Error?e.message:String(e)})}break}case"GET_FRAME_NAME":{try{r({name:window.name||null})}catch{r({name:null})}break}case"LOCATE_ROLE":{try{const{role:e,name:c,all:o}=i,t=I(),u={button:["button",'input[type="button"]','input[type="submit"]','input[type="reset"]','[role="button"]'],link:["a[href]",'[role="link"]'],textbox:["input:not([type])",'input[type="text"]','input[type="email"]','input[type="password"]','input[type="search"]','input[type="tel"]','input[type="url"]',"textarea",'[role="textbox"]'],checkbox:['input[type="checkbox"]','[role="checkbox"]'],radio:['input[type="radio"]','[role="radio"]'],combobox:["select",'[role="combobox"]'],listbox:['[role="listbox"]',"select[multiple]"],option:["option",'[role="option"]'],heading:["h1","h2","h3","h4","h5","h6",'[role="heading"]'],navigation:["nav",'[role="navigation"]'],main:["main",'[role="main"]'],img:["img[alt]",'[role="img"]'],dialog:["dialog",'[role="dialog"]','[role="alertdialog"]'],tab:['[role="tab"]'],tabpanel:['[role="tabpanel"]'],menu:['[role="menu"]'],menuitem:['[role="menuitem"]']}[e]||[`[role="${e}"]`],d=[];for(const m of u)try{d.push(...document.querySelectorAll(m))}catch{}const w=d.filter(m=>{const b=window.getComputedStyle(m);return b.display!=="none"&&b.visibility!=="hidden"&&m.offsetWidth>0&&m.offsetHeight>0});let a=w;if(c){const m=c.toLowerCase();a=w.filter(b=>{const s=b.getAttribute("aria-label")?.toLowerCase(),p=b.textContent?.trim().toLowerCase(),T=b.getAttribute("title")?.toLowerCase(),A=b.placeholder?.toLowerCase(),C=b.value?.toLowerCase();return s?.includes(m)||p?.includes(m)||T?.includes(m)||A?.includes(m)||C?.includes(m)})}if(a.length===0){r({error:`No element found with role "${e}"${c?` and name "${c}"`:""}`});break}const f=a.map(m=>{const b=q(m,e,c||"");return window.__piRefs=window.__piRefs||{},window.__piRefs[b]=m,t[b]={element:new WeakRef(m),role:e,name:c||""},{ref:b,text:m.textContent?.trim().slice(0,50)}});r(o?{matches:f}:{ref:f[0].ref,text:f[0].text})}catch(e){r({error:e instanceof Error?e.message:String(e)})}break}case"LOCATE_TEXT":{try{const{text:e,exact:c}=i,o=I(),t=document.createTreeWalker(document.body,NodeFilter.SHOW_TEXT),l=[];for(;t.nextNode();){const a=t.currentNode.textContent||"";if(c?a.trim()===e:a.toLowerCase().includes(e.toLowerCase())){const m=t.currentNode.parentElement;if(m&&!l.includes(m)){const b=window.getComputedStyle(m);b.display!=="none"&&b.visibility!=="hidden"&&l.push(m)}}}if(l.length===0){r({error:`No element found with text "${e}"`});break}const u=l.sort((a,f)=>(a.textContent?.length||0)-(f.textContent?.length||0))[0],d=U(u),w=q(u,d,e);window.__piRefs=window.__piRefs||{},window.__piRefs[w]=u,o[w]={element:new WeakRef(u),role:d,name:e},r({ref:w,text:u.textContent?.trim().slice(0,50)})}catch(e){r({error:e instanceof Error?e.message:String(e)})}break}case"LOCATE_LABEL":{try{const{label:e}=i,c=I(),o=document.querySelectorAll("label");let t=null;for(const d of o)if(d.textContent?.trim().toLowerCase()?.includes(e.toLowerCase())){const a=d.getAttribute("for");if(a&&(t=document.getElementById(a)),t||(t=d.querySelector("input, select, textarea")),t)break}if(!t){const d=e.toLowerCase();t=document.querySelector(`input[aria-label*="${e}" i], input[placeholder*="${e}" i], textarea[aria-label*="${e}" i], textarea[placeholder*="${e}" i], select[aria-label*="${e}" i]`)}if(!t){r({error:`No form field found with label "${e}"`});break}const l=U(t),u=q(t,l,e);window.__piRefs=window.__piRefs||{},window.__piRefs[u]=t,c[u]={element:new WeakRef(t),role:l,name:e},r({ref:u,label:e})}catch(e){r({error:e instanceof Error?e.message:String(e)})}break}case"GET_ELEMENT_STYLES":{try{const{selector:e}=i,c=I(),o=t=>{const l=getComputedStyle(t),u=t.getBoundingClientRect();return{tag:t.tagName.toLowerCase(),text:t.innerText?.trim().slice(0,80)||null,box:{x:Math.round(u.x),y:Math.round(u.y),width:Math.round(u.width),height:Math.round(u.height)},styles:{fontSize:l.fontSize,fontWeight:l.fontWeight,fontFamily:l.fontFamily.split(",")[0].trim().replace(/"/g,""),color:l.color,backgroundColor:l.backgroundColor,borderRadius:l.borderRadius,border:l.border!=="none"&&l.borderWidth!=="0px"?l.border:null,boxShadow:l.boxShadow!=="none"?l.boxShadow:null,padding:l.padding}}};if(/^e\d+$/.test(e)){const t=c[e];let l;if(t&&(l=t.element.deref(),l||delete c[e]),!l&&window.__piRefs&&(l=window.__piRefs[e]),!l){r({error:`Element ${e} not found`});break}r({styles:[o(l)]})}else{const t=document.querySelectorAll(e);if(t.length===0){r({error:`No elements found matching "${e}"`});break}const l=Array.from(t).map(o);r({styles:l})}}catch(e){r({error:e instanceof Error?e.message:String(e)})}break}case"SELECT_OPTION":{try{const{selector:e,values:c,by:o}=i,t=I();let l=null;if(/^e\d+$/.test(e)){const a=t[e];let f;if(a&&(f=a.element.deref(),f||delete t[e]),!f&&window.__piRefs&&(f=window.__piRefs[e]),!f){r({error:`Element ${e} not found`});break}if(f.tagName!=="SELECT"){r({error:`Element ${e} is not a <select>`});break}l=f}else{if(l=document.querySelector(e),!l){r({error:`No element found matching "${e}"`});break}if(l.tagName!=="SELECT"){r({error:`Element "${e}" is not a <select>`});break}}if(l.multiple)for(const a of l.options)a.selected=!1;const u=[],d=[],w=l.multiple?c:[c[0]];for(const a of w){let f=!1;for(const m of l.options){let b=!1;if(o==="index"?b=m.index===parseInt(a,10):o==="label"?b=m.text.toLowerCase().includes(a.toLowerCase()):b=m.value===a,b){m.selected=!0,u.push(m.value),f=!0;break}}f||d.push(a)}l.dispatchEvent(new Event("change",{bubbles:!0})),d.length>0?r({selected:u,warning:`Values not found: ${d.join(", ")}`}):r({selected:u})}catch(e){r({error:e instanceof Error?e.message:String(e)})}break}case"GET_ELEMENT_TEXT":{try{const{ref:e}=i,c=I(),o=c[e];let t;if(o&&(t=o.element.deref(),t||delete c[e]),!t&&window.__piRefs&&(t=window.__piRefs[e]),!t){r({error:`Element ${e} not found`});break}r({text:t.textContent?.trim()||""})}catch(e){r({error:e instanceof Error?e.message:String(e)})}break}case"SCROLL_TO_ELEMENT":{const e=oe(i.ref);r(e);break}case"UPLOAD_IMAGE":{const e=se(i.base64,i.ref,i.coordinate,i.filename);r(e);break}case"WAIT_FOR_ELEMENT":{const{selector:e,state:c="visible",timeout:o=2e4}=i,t=Math.min(o,6e4),l=a=>{if(!a)return!1;const f=window.getComputedStyle(a);return f.display!=="none"&&f.visibility!=="hidden"&&f.opacity!=="0"&&a.offsetWidth>0&&a.offsetHeight>0},u=()=>{const a=document.querySelector(e);switch(c){case"attached":return!!a;case"detached":return!a;case"hidden":return!a||!l(a);default:return l(a)}},d=Date.now();return new Promise(a=>{if(u()){a({success:!0,waited:Date.now()-d});return}const f=new MutationObserver(()=>{u()&&(f.disconnect(),clearTimeout(m),a({success:!0,waited:Date.now()-d}))}),m=setTimeout(()=>{f.disconnect(),a({success:!1,waited:Date.now()-d,error:`Timeout waiting for "${e}" to be ${c}`})},t);f.observe(document.documentElement,{childList:!0,subtree:!0,attributes:!0,attributeFilter:["style","class","hidden","disabled"]})}).then(a=>{if(!a.success){r({error:a.error,waited:a.waited,pageContent:"",viewport:{width:window.innerWidth,height:window.innerHeight}});return}const f=B("interactive",15,void 0,!0);r({...f,waited:a.waited})}),!0}case"WAIT_FOR_URL":{const{pattern:e,timeout:c=2e4}=i,o=Math.min(c,6e4),t=d=>{if(e.includes("*")){const w=e.replace(/[.+?^${}()|[\]\\]/g,"\\$&").replace(/\*\*/g,"<<<GLOBSTAR>>>").replace(/\*/g,"[^/]*").replace(/<<<GLOBSTAR>>>/g,".*");return new RegExp(`^${w}$`).test(d)}return d.includes(e)},l=Date.now();return new Promise(d=>{if(t(window.location.href)){d({success:!0,waited:Date.now()-l});return}let w=!1;const a=()=>{w||t(window.location.href)&&(w=!0,clearInterval(f),clearTimeout(m),window.removeEventListener("popstate",a),window.removeEventListener("hashchange",a),d({success:!0,waited:Date.now()-l}))},f=setInterval(a,100),m=setTimeout(()=>{w||(w=!0,clearInterval(f),window.removeEventListener("popstate",a),window.removeEventListener("hashchange",a),d({success:!1,waited:Date.now()-l,error:`Timeout waiting for URL to match "${e}". Current: ${window.location.href}`}))},o);window.addEventListener("popstate",a),window.addEventListener("hashchange",a)}).then(d=>{if(!d.success){r({error:d.error,waited:d.waited,pageContent:"",viewport:{width:window.innerWidth,height:window.innerHeight}});return}const w=B("interactive",15,void 0,!0);r({...w,waited:d.waited})}),!0}case"WAIT_FOR_DOM_STABLE":{const{stable:e=100,timeout:c=5e3}=i,o=Math.min(c,3e4),t=Date.now();return new Promise(u=>{let d=Date.now(),w=!1;const a=()=>{if(w)return;Date.now()-d>=e&&(w=!0,f.disconnect(),clearTimeout(m),clearInterval(b),u({success:!0,waited:Date.now()-t}))},f=new MutationObserver(()=>{d=Date.now()}),m=setTimeout(()=>{w||(w=!0,f.disconnect(),clearInterval(b),u({success:!1,waited:Date.now()-t,error:`Timeout: DOM did not stabilize within ${o}ms`}))},o),b=setInterval(a,Math.max(10,Math.min(50,e/2)));f.observe(document.documentElement,{childList:!0,subtree:!0,attributes:!0,characterData:!0}),a()}).then(u=>{if(!u.success){r({error:u.error,waited:u.waited,pageContent:"",viewport:{width:window.innerWidth,height:window.innerHeight}});return}const d=B("interactive",15,void 0,!0);r({...d,waited:u.waited})}),!0}case"FORM_FILL":{const{data:e}=i;if(!Array.isArray(e))return r({error:"data must be an array of {ref, value} pairs"}),!0;const c=I(),o=[];for(const l of e){const{ref:u,value:d}=l;if(!u){o.push({ref:u||"unknown",success:!1,error:"Missing ref"});continue}const w=c[u];if(!w){o.push({ref:u,success:!1,error:"Element not found (run page.read first)"});continue}const a=w.element.deref();if(!a){delete c[u],o.push({ref:u,success:!1,error:"Element no longer exists"});continue}try{if(a instanceof HTMLInputElement){const f=a.type.toLowerCase();if(f==="checkbox"||f==="radio"){const m=d===!0||d==="true"||d==="1"||d==="checked";a.checked=m,a.dispatchEvent(new Event("change",{bubbles:!0}))}else a.focus(),a.value=String(d),a.dispatchEvent(new Event("input",{bubbles:!0})),a.dispatchEvent(new Event("change",{bubbles:!0}));o.push({ref:u,success:!0})}else a instanceof HTMLTextAreaElement?(a.focus(),a.value=String(d),a.dispatchEvent(new Event("input",{bubbles:!0})),a.dispatchEvent(new Event("change",{bubbles:!0})),o.push({ref:u,success:!0})):a instanceof HTMLSelectElement?(a.value=String(d),a.dispatchEvent(new Event("change",{bubbles:!0})),o.push({ref:u,success:!0})):a.isContentEditable?(a.focus(),a.textContent=String(d),a.dispatchEvent(new Event("input",{bubbles:!0})),o.push({ref:u,success:!0})):o.push({ref:u,success:!1,error:"Element is not fillable"})}catch(f){o.push({ref:u,success:!1,error:f instanceof Error?f.message:String(f)})}}const t=o.filter(l=>!l.success);return r({success:t.length===0,filled:o.filter(l=>l.success).length,failed:t.length,results:o}),!0}case"GET_FILE_INPUT_SELECTOR":{const{ref:e}=i;if(!e)return r({error:"No ref provided"}),!0;const c=I(),o=c[e];if(!o)return r({error:"Element not found (run page.read first)"}),!0;const t=o.element.deref();if(!t)return delete c[e],r({error:"Element no longer exists"}),!0;if(!(t instanceof HTMLInputElement)||t.type!=="file")return r({error:"Element is not a file input"}),!0;const l=`__pi_file_${Date.now()}`;return t.setAttribute("data-pi-file-id",l),r({selector:`[data-pi-file-id="${l}"]`}),!0}case"WAIT_FOR_NETWORK_IDLE":{const{timeout:e=1e4}=i,c=Math.min(e,6e4),o=["doubleclick.net","googlesyndication.com","googletagmanager.com","google-analytics.com","facebook.net","connect.facebook.net","analytics","ads","tracking","pixel","hotjar.com","clarity.ms","mixpanel.com","segment.com","newrelic.com","nr-data.net","/tracker/","/collector/","/beacon/","/telemetry/","/log/","/events/","/track.","/metrics/"],t=["img","image","font","icon"],l=f=>o.some(m=>f.includes(m)),u=f=>{const m=f.initiatorType||"unknown";return!!(t.includes(m)||/\.(jpg|jpeg|png|gif|webp|svg|ico|woff|woff2|ttf|eot)(\?|$)/i.test(f.name))},d=()=>{const f=performance.now();return performance.getEntriesByType("resource").filter(b=>{if(b.responseEnd!==0||b.name.startsWith("data:")||b.name.length>500||l(b.name))return!1;const s=f-b.startTime;return!(s>1e4||u(b)&&s>3e3)})},w=Date.now();return new Promise(f=>{const m=()=>{const b=d(),s=Date.now()-w;if(b.length===0){f({success:!0,waited:s});return}if(s>=c){f({success:!1,waited:s,pendingCount:b.length});return}setTimeout(m,100)};m()}).then(f=>{if(!f.success){r({error:`Network not idle after ${f.waited}ms (${f.pendingCount} requests pending)`,waited:f.waited,pageContent:"",viewport:{width:window.innerWidth,height:window.innerHeight}});return}const m=B("interactive",15,void 0,!0);r({...m,waited:f.waited})}),!0}case"SEARCH_PAGE":{const{term:e,caseSensitive:c,limit:o}=i,t=ce(e,c||!1,o||10);r({query:e,count:t.length,matches:t});break}case"GET_ELEMENT_BOUNDS_FOR_ANNOTATION":{const e=I(),c=[];for(const[o,t]of Object.entries(e)){const l=t.element.deref();if(!l)continue;const u=l.getBoundingClientRect();u.width<=0||u.height<=0||u.bottom<0||u.top>window.innerHeight||u.right<0||u.left>window.innerWidth||c.push({ref:o,tag:l.tagName.toLowerCase(),bounds:{x:u.x,y:u.y,width:u.width,height:u.height}})}r({elements:c});break}default:return!1}return!1});function ce(i,g,r){const e=[],c=g?i:i.toLowerCase(),o=document.createTreeWalker(document.body,NodeFilter.SHOW_TEXT),t=I();let l=0;for(;o.nextNode()&&e.length<r;){const u=o.currentNode,d=u.textContent||"",w=g?d:d.toLowerCase();let a=0;for(;(a=w.indexOf(c,a))!==-1&&e.length<r;){const f=u.parentElement;if(!f){a++;continue}const m=document.createRange();m.setStart(u,a),m.setEnd(u,Math.min(a+i.length,d.length));const b=m.getBoundingClientRect();if(b.width===0||b.height===0){a++;continue}const s=u.textContent||"",p=Math.max(0,a-30),T=Math.min(s.length,a+i.length+30),A=s.slice(p,T).trim();let C=null;for(const[O,$]of Object.entries(t)){const M=$.element.deref();if(M&&(M===f||M.contains(f))){C=O;break}}e.push({ref:`m${++l}`,text:s.slice(a,a+i.length),context:A,bounds:{x:Math.round(b.x),y:Math.round(b.y),width:Math.round(b.width),height:Math.round(b.height)},elementRef:C}),a++}}return e}
|
|
11
11
|
//# sourceMappingURL=accessibility-tree.js.map
|