buninu-browser 0.9.0 → 0.9.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/browser-dialog.js +11 -1
- package/package.json +1 -1
- package/test/file-picker.test.js +8 -0
package/lib/browser-dialog.js
CHANGED
|
@@ -34,8 +34,18 @@ export class BrowserDialog {
|
|
|
34
34
|
await host.call('loadDocument',{url:'about:dialog',source:entry.picker?entry.picker.document(size,background):dialogDocument(entry.request,size,background),contentType:'text/html'});
|
|
35
35
|
if(this.active===entry)this.changed();
|
|
36
36
|
}
|
|
37
|
-
|
|
37
|
+
invoke(method,...args) {
|
|
38
38
|
const entry=this.active;if(!entry)return;
|
|
39
|
+
const invoke=()=>this.invokeEntry(entry,method,...args);
|
|
40
|
+
if(!['press','type','click'].includes(method))return invoke();
|
|
41
|
+
// Modal input bypasses the page's blocked script turn. Serialize it here:
|
|
42
|
+
// overlapping down/up requests must not consume the same file action twice
|
|
43
|
+
// or reload the picker while another input still uses its old document.
|
|
44
|
+
const result=(entry.inputQueue??Promise.resolve()).then(invoke);
|
|
45
|
+
entry.inputQueue=result.then(()=>{},()=>{});
|
|
46
|
+
return result;
|
|
47
|
+
}
|
|
48
|
+
async invokeEntry(entry,method,...args) {
|
|
39
49
|
await entry.ready;
|
|
40
50
|
if(this.active!==entry||!entry.host)return;
|
|
41
51
|
if(method==='press' && (args[1]?.modifiers & 6) && String(args[0]).toLowerCase()==='c') {
|
package/package.json
CHANGED
package/test/file-picker.test.js
CHANGED
|
@@ -16,6 +16,14 @@ test('file input opens browser-owned picker, selects files, and FileReader emits
|
|
|
16
16
|
const action=async value=>{await c.evaluate(`window.__fileAction=${JSON.stringify(value)}`);await c.send('Input.dispatchKeyEvent',{type:'keyDown',key:'Shift'});await c.send('Input.dispatchKeyEvent',{type:'keyUp',key:'Shift'});};
|
|
17
17
|
await action({kind:'browse',path:dir});
|
|
18
18
|
expect(await c.evaluate('document.body.textContent.includes("one.txt")')).toBe(true);
|
|
19
|
+
const point=await c.evaluate(`(()=>{const b=document.querySelector('button.entry');const r=b.getBoundingClientRect();return {x:r.x+20,y:r.y+r.height/2}})()`);
|
|
20
|
+
// Casty lets modal input bypass the page's blocked input turn. Down/up
|
|
21
|
+
// requests may overlap: one click must consume its picker action once.
|
|
22
|
+
for(const expected of ['one.txt','']) {
|
|
23
|
+
await Promise.all(['mousePressed','mouseReleased'].map(type=>c.send('Input.dispatchMouseEvent',{type,...point,button:'left',clickCount:1})));
|
|
24
|
+
expect(b.context.dialogState?.type).toBe('file');
|
|
25
|
+
expect(await c.evaluate('document.getElementById("chosen").textContent')).toBe(expected);
|
|
26
|
+
}
|
|
19
27
|
await action({kind:'select',index:0});await action({kind:'select',index:1});await action({kind:'open'});
|
|
20
28
|
for(let i=0;i<100;i++){if(await c.evaluate('window.text!==undefined'))break;await Bun.sleep(10);}
|
|
21
29
|
expect(await c.evaluate('clickReturned')).toBe(true);expect(await c.evaluate('names')).toEqual(['one.txt','two.txt']);
|