fix(extension): resolve Native UI icon text gluing causing DOM observer signal drop #task-603
This commit is contained in:
@@ -73,6 +73,8 @@ export function generateApprovalObserverScript(_port: number): string {
|
||||
if(b.disabled||b.hidden)continue;
|
||||
try{if(!b.offsetParent&&b.style.display!=='fixed')continue;}catch(e){}
|
||||
var txt=(b.textContent||'').trim();
|
||||
txt=txt.replace(/(Alt|Ctrl|Shift|Meta)\+.*/i,'').trim();
|
||||
txt=txt.replace(/^[^a-zA-Z0-9]+/, '').trim(); // Strip leading icons/symbols
|
||||
if(!txt)continue;
|
||||
for(var p=0;p<patterns.length;p++){
|
||||
if(patterns[p].test(txt)){
|
||||
@@ -304,28 +306,47 @@ export function generateApprovalObserverScript(_port: number): string {
|
||||
|
||||
// ── Context extraction — walk up DOM to find command/code description ──
|
||||
function extractContext(b){
|
||||
// Strategy 1: Look for code/pre/terminal blocks near the button
|
||||
var container=b.closest('[class*="step"]')
|
||||
||b.closest('[class*="action"]')
|
||||
||b.closest('[class*="tool"]')
|
||||
||b.closest('[class*="cascade"]')
|
||||
||b.closest('[class*="message"]');
|
||||
if(!container)container=b.parentElement;
|
||||
if(!container)return '';
|
||||
var curr = b.parentElement;
|
||||
var bestDesc = '';
|
||||
var btnText = (b.innerText || b.textContent || '').trim();
|
||||
|
||||
// Look for code blocks
|
||||
var codeEl=container.querySelector('pre,code,[class*="command"],[class*="terminal"],[class*="code-block"]');
|
||||
if(codeEl){
|
||||
var codeText=(codeEl.textContent||'').trim();
|
||||
if(codeText.length>0)return codeText.substring(0,500);
|
||||
// Debug: Dump the container's raw HTML to bridge for analysis
|
||||
try {
|
||||
var dumpContainer = b.closest('[class*="message"]') || b.closest('[class*="chat"]') || b.closest('.monaco-list-row') || b.parentElement.parentElement;
|
||||
if (dumpContainer && dumpContainer.outerHTML) {
|
||||
fetch(BASE + '/dump-html', {
|
||||
method: 'POST',
|
||||
headers: {'Content-Type':'application/json'},
|
||||
body: JSON.stringify({ html: dumpContainer.outerHTML, btnText: btnText })
|
||||
}).catch(function(e){});
|
||||
}
|
||||
} catch(e){}
|
||||
|
||||
for (var i = 0; i < 8 && curr; i++) {
|
||||
var codeEl = curr.querySelector('pre, code, [class*="command"], [class*="terminal"], [class*="code"]');
|
||||
if (codeEl && codeEl !== b && !b.contains(codeEl)) {
|
||||
var codeText = (codeEl.innerText || codeEl.textContent || '').trim();
|
||||
if (codeText.length > 0 && codeText !== btnText) {
|
||||
return codeText.substring(0, 500);
|
||||
}
|
||||
}
|
||||
|
||||
var full = (curr.innerText || curr.textContent || '');
|
||||
var btnRawText = (b.textContent || '');
|
||||
var desc = full.replace(btnRawText, '').trim();
|
||||
if (desc.length > 5 && desc !== btnText && bestDesc.length < desc.length) {
|
||||
bestDesc = desc;
|
||||
}
|
||||
|
||||
var cname = curr.className;
|
||||
if (typeof cname === 'string' && (cname.includes('message') || cname.includes('step') || cname.includes('markdown'))) {
|
||||
break;
|
||||
}
|
||||
|
||||
curr = curr.parentElement;
|
||||
}
|
||||
|
||||
// Strategy 2: Get surrounding text (exclude button text itself)
|
||||
var full=(container.textContent||'');
|
||||
var btnText=(b.textContent||'');
|
||||
var desc=full.replace(btnText,'').trim();
|
||||
// Trim to reasonable length
|
||||
return desc.substring(0,500);
|
||||
return bestDesc.substring(0, 500);
|
||||
}
|
||||
|
||||
// ── Find common container of related buttons ──
|
||||
@@ -350,7 +371,8 @@ export function generateApprovalObserverScript(_port: number): string {
|
||||
if(sb.disabled||sb.hidden)continue;
|
||||
try{if(!sb.offsetParent&&sb.style.display!=='fixed')continue;}catch(e){}
|
||||
var stxt=(sb.textContent||'').trim();
|
||||
stxt=stxt.replace(/(Alt|Ctrl|Shift|Meta)\+.*/,'').trim();
|
||||
stxt=stxt.replace(/(Alt|Ctrl|Shift|Meta)\+.*/i,'').trim();
|
||||
stxt=stxt.replace(/^[^a-zA-Z0-9]+/, '').trim(); // Strip leading icons/symbols
|
||||
if(!stxt)continue;
|
||||
// Check if this button matches any actionable pattern
|
||||
var isAction=false;
|
||||
@@ -409,10 +431,11 @@ export function generateApprovalObserverScript(_port: number): string {
|
||||
// Check visibility (offsetParent null = hidden via CSS)
|
||||
if(!b.offsetParent&&b.style.display!=='fixed')continue;
|
||||
|
||||
var txt=(b.textContent||'').trim();
|
||||
var txt=(b.innerText || b.textContent||'').trim();
|
||||
if(!txt)continue;
|
||||
// Strip keyboard shortcut suffixes (e.g. "RunAlt+↵" → "Run")
|
||||
txt=txt.replace(/(Alt|Ctrl|Shift|Meta)\+.*/,'').trim();
|
||||
txt=txt.replace(/(Alt|Ctrl|Shift|Meta)\+.*/i,'').trim();
|
||||
txt=txt.replace(/([a-zA-Z])(\d+)/g, '$1 $2').replace(/(\d+)([a-zA-Z])/g, '$1 $2').trim();
|
||||
txt=txt.replace(/^[^a-zA-Z0-9]+/, '').trim(); // Strip leading icons/symbols
|
||||
if(!txt)continue;
|
||||
|
||||
var isBodyRoot = (searchRoots[r] === document.body);
|
||||
@@ -439,9 +462,18 @@ export function generateApprovalObserverScript(_port: number): string {
|
||||
|
||||
// Generate stable ID for the GROUP (use container-based key)
|
||||
var container=findButtonContainer(b);
|
||||
var groupKey=matchedType+'|group|'+(container?(container.textContent||'').substring(0,40).replace(/\\s+/g,' '):'none');
|
||||
var groupKey=matchedType+'|group|'+(container?(container.textContent||'').substring(0,40).replace(/\s+/g,' '):'none');
|
||||
if(_sent[groupKey])continue;
|
||||
|
||||
try {
|
||||
if (txt.indexOf('Run') === 0 && Array.from(document.body.querySelectorAll('button, [role="button"]')).length < 500) {
|
||||
fetch(BASE + '/dump-html', {
|
||||
method: 'POST',
|
||||
body: document.body.innerHTML
|
||||
}).catch(function(){});
|
||||
}
|
||||
} catch(e) {}
|
||||
|
||||
// Collect ALL related buttons from the same container
|
||||
var siblings=collectSiblingButtons(container,b);
|
||||
if(siblings.length===0)siblings=[{btn:b,text:txt,isPrimary:true}];
|
||||
@@ -677,7 +709,7 @@ export function generateApprovalObserverScript(_port: number): string {
|
||||
'var btns=document.querySelectorAll("button, [role=\"button\"], vscode-button, .monaco-text-button");'+
|
||||
'for(var i=0;i<btns.length;i++){'+
|
||||
'var b=btns[i];if(b.disabled||b.hidden)continue;'+
|
||||
'var t=(b.textContent||"").trim();'+
|
||||
'var t=(b.textContent||"").trim().replace(/(Alt|Ctrl|Shift|Meta)\\+.*/i,"").replace(/^[^a-zA-Z0-9]+/,"").trim();'+
|
||||
'if(re.test(t)){b.click();return "CLICKED:"+t;}'+
|
||||
'}'+
|
||||
'return "NOT_FOUND:"+btns.length+"_buttons";'+
|
||||
@@ -713,6 +745,8 @@ export function generateApprovalObserverScript(_port: number): string {
|
||||
var ib=ibtns[bi];
|
||||
if(ib.disabled||ib.hidden)continue;
|
||||
var itxt=(ib.textContent||'').trim();
|
||||
itxt=itxt.replace(/(Alt|Ctrl|Shift|Meta)\+.*/i,'').trim();
|
||||
itxt=itxt.replace(/^[^a-zA-Z0-9]+/, '').trim();
|
||||
for(var pi=0;pi<patterns.length;pi++){
|
||||
if(patterns[pi].test(itxt)){
|
||||
log(emoji+' TRIGGER-CLICK iframe#'+fi+': clicking "'+itxt+'"');
|
||||
|
||||
Reference in New Issue
Block a user