Skip to content

Commit 7b4df6b

Browse files
authored
fix(preview): open selected files reliably (#151)
## Summary - Emit an actual double-click for Code Server explorer files instead of two unrelated single clicks. - Acknowledge the parent request only after the target filename is present in an editor tab. - Reuse the same reliable interaction for initial deliverable opening. ## Production finding The image preview and viewer passed live QA, but Open in Files left Code Server in its empty directory state. A direct real double-click opened the JPEG, proving the bridge event sequence was incomplete. ## Checks - [x] Preview bridge lint - [x] Preview bridge TypeScript check - [x] Preview bridge build - [ ] Production close-editor then Open in Files validation
1 parent 17665da commit 7b4df6b

1 file changed

Lines changed: 36 additions & 8 deletions

File tree

packages/preview-bridge/src/index.ts

Lines changed: 36 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -127,18 +127,28 @@ style.textContent=[
127127
].join("");
128128
(document.head||document.documentElement).appendChild(style);
129129
130-
function dispatchClick(target){
130+
function dispatchClick(target,detail){
131131
if(!target)return;
132+
var clickDetail=typeof detail==="number"?detail:1;
132133
var pointerEvents=["pointerover","pointerenter","pointermove","pointerdown","pointerup"];
133134
for(var i=0;i<pointerEvents.length;i++){
134-
target.dispatchEvent(new PointerEvent(pointerEvents[i],{bubbles:true,cancelable:true,pointerType:"mouse",button:0,buttons:pointerEvents[i]==="pointerdown"?1:0}));
135+
target.dispatchEvent(new PointerEvent(pointerEvents[i],{bubbles:true,cancelable:true,pointerType:"mouse",button:0,buttons:pointerEvents[i]==="pointerdown"?1:0,detail:clickDetail}));
135136
}
136137
var mouseEvents=["mouseover","mouseenter","mousemove","mousedown","mouseup","click"];
137138
for(var j=0;j<mouseEvents.length;j++){
138-
target.dispatchEvent(new MouseEvent(mouseEvents[j],{bubbles:true,cancelable:true,button:0,buttons:mouseEvents[j]==="mousedown"?1:0}));
139+
target.dispatchEvent(new MouseEvent(mouseEvents[j],{bubbles:true,cancelable:true,button:0,buttons:mouseEvents[j]==="mousedown"?1:0,detail:clickDetail,view:window}));
139140
}
140141
}
141142
143+
function dispatchDoubleClick(target){
144+
if(!target)return;
145+
dispatchClick(target,1);
146+
setTimeout(function(){
147+
dispatchClick(target,2);
148+
target.dispatchEvent(new MouseEvent("dblclick",{bubbles:true,cancelable:true,button:0,buttons:0,detail:2,view:window}));
149+
},120);
150+
}
151+
142152
function visible(el){
143153
if(!el)return false;
144154
var rect=el.getBoundingClientRect();
@@ -225,8 +235,7 @@ var isDeliverable=/\.(pptx?|pdf|docx?|xlsx?|ods|odt)\b/i.test(text);
225235
if((isRequestedFile||(!cheatcodeInitialFileName&&isDeliverable))&&visible(rows[i])){
226236
window.__CHEATCODE_CS_OPENED_INITIAL_DELIVERABLE__=true;
227237
var target=rows[i].querySelector(".label-name,.monaco-icon-label,.monaco-tl-contents")||rows[i];
228-
dispatchClick(target);
229-
setTimeout(function(){dispatchClick(target)},250);
238+
dispatchDoubleClick(target);
230239
break;
231240
}
232241
}
@@ -267,6 +276,26 @@ function reportFileOpened(requestId){
267276
try{window.parent.postMessage({requestId:requestId,type:"CHEATCODE_FILE_OPENED"},cheatcodeParentOrigin)}catch(_err){}
268277
}
269278
279+
function hasOpenFileTab(filename){
280+
var tabs=document.querySelectorAll(".part.editor .tab");
281+
for(var i=0;i<tabs.length;i++){
282+
var label=(tabs[i].getAttribute("aria-label")||tabs[i].textContent||"").trim();
283+
if(label.indexOf(filename)!==-1)return true;
284+
}
285+
return false;
286+
}
287+
288+
function confirmRequestedFileOpen(filename,requestId,attempt){
289+
if(!activeFileOpenRequest||activeFileOpenRequest.requestId!==requestId)return;
290+
if(hasOpenFileTab(filename)){
291+
activeFileOpenRequest=null;
292+
reportFileOpened(requestId);
293+
return;
294+
}
295+
if(attempt>=40){activeFileOpenRequest=null;return;}
296+
setTimeout(function(){confirmRequestedFileOpen(filename,requestId,attempt+1)},100);
297+
}
298+
270299
function openRequestedFileStep(parts,index,expectedLevel,requestId,attempt){
271300
if(!activeFileOpenRequest||activeFileOpenRequest.requestId!==requestId||attempt>80)return;
272301
var row=findVisibleTreeItem(parts[index],expectedLevel);
@@ -281,9 +310,8 @@ setTimeout(function(){openRequestedFileStep(parts,index+1,level===null?null:leve
281310
return;
282311
}
283312
var target=row.querySelector(".label-name,.monaco-icon-label,.monaco-tl-contents")||row;
284-
dispatchClick(target);
285-
setTimeout(function(){dispatchClick(target);reportFileOpened(requestId)},250);
286-
activeFileOpenRequest=null;
313+
dispatchDoubleClick(target);
314+
setTimeout(function(){confirmRequestedFileOpen(parts[index],requestId,0)},200);
287315
}
288316
289317
function openWorkspaceFile(path,requestId){

0 commit comments

Comments
 (0)