//! Scripts injectés dans la page (copiés de `computer_cdp.go`, à l'octet près : //! le journal de parité compare les expressions envoyées). /// `cdpSameTabJS` : les navigations « nouvel onglet » restent dans l'onglet. pub const SAME_TAB_JS: &str = r#"(function(){try{ window.open=function(u){if(u)location.href=u;return window;}; document.addEventListener('click',function(e){ var a=e.target&&e.target.closest&&e.target.closest('a[target]'); if(a)a.removeAttribute('target'); },true); }catch(e){}})();"#; /// `cdpHelpersJS` : rôle, nom, actionnable, visible, shadow DOM. pub const HELPERS_JS: &str = r#" function ajRole(el){var r=el.getAttribute('role');if(r)return r;var t=el.tagName.toLowerCase();if(t==='a')return 'link';if(t==='button')return 'button';if(t==='select')return 'combobox';if(t==='textarea')return 'textbox';if(t==='input'){var ty=(el.type||'text').toLowerCase();var m={checkbox:'checkbox',radio:'radio',button:'button',submit:'button',reset:'button',file:'button',range:'slider',password:'password',search:'searchbox'};return m[ty]||'textbox';}return t;} function ajName(el){var t=el.tagName.toLowerCase();var lbl=el.getAttribute('aria-label')||'';if(!lbl){var lb=el.getAttribute('aria-labelledby');if(lb){var e2=document.getElementById(lb.split(' ')[0]);if(e2)lbl=e2.innerText||'';}}if(!lbl&&el.labels&&el.labels.length)lbl=el.labels[0].innerText||'';if(!lbl)lbl=el.getAttribute('placeholder')||el.getAttribute('title')||el.getAttribute('alt')||'';var val='';if((t==='input'||t==='textarea')&&el.type!=='password'&&el.type!=='hidden')val=el.value||'';var n=val?(lbl?(lbl+' = '+val):val):lbl;if(!n&&t!=='input'&&t!=='select'&&t!=='textarea')n=el.innerText||'';if(!n){var c=el.querySelector('img[alt],[aria-label],[title],svg title');if(c)n=c.getAttribute&&(c.getAttribute('alt')||c.getAttribute('aria-label')||c.getAttribute('title'))||c.textContent||'';}if(!n)n=el.getAttribute('name')||el.getAttribute('value')||'';return (n||'').replace(/\s+/g,' ').trim().slice(0,100);} function ajActionable(el){var t=el.tagName.toLowerCase();if(t==='a')return !!el.getAttribute('href');if(t==='button'||t==='input'||t==='select'||t==='textarea'||t==='summary')return el.type!=='hidden';if(el.isContentEditable)return true;if(el.getAttribute('onclick'))return true;var r=(el.getAttribute('role')||'').toLowerCase();return {button:1,link:1,checkbox:1,radio:1,tab:1,menuitem:1,menuitemcheckbox:1,menuitemradio:1,option:1,'switch':1,combobox:1,textbox:1,searchbox:1,slider:1,spinbutton:1}[r]===1;} function ajVis(el){var r=el.getBoundingClientRect();if(r.width<3||r.height<3)return false;var s=getComputedStyle(el);if(s.visibility==='hidden'||s.display==='none'||s.opacity==='0')return false;if(r.bottom<0||r.top>innerHeight||r.right<0||r.left>innerWidth)return false;return true;} var ajSel='a[href],button,input,select,textarea,[role],[onclick],[tabindex],summary,[contenteditable="true"]'; // Traversée du SHADOW DOM : les bandeaux cookies et composants web (usercentrics, // cookiebot…) vivent dans des shadow roots que querySelectorAll ne voit pas → le // modèle ne pouvait ni les lister ni les cliquer (test Lady Sushi). ajQueryAll / // ajByRef / ajClear descendent récursivement dans chaque shadowRoot ouvert. function ajQueryAll(){var out=[];function w(r){var e=r.querySelectorAll(ajSel);for(var i=0;imaxRef)maxRef=v;} var els=pool.filter(ajActionable); var refs=[],count=0,first=null; for(var k=0;k String { format!("{HELPERS_JS}{SNAPSHOT_TAIL_JS}") }