1818import * as input from '../../input' ;
1919
2020import type * as types from '../../types' ;
21- import type { WVSession } from './wvConnection' ;
21+ import type * as frames from '../../frames' ;
22+ import type { Func1 } from '../../javascript' ;
2223import type { Progress } from '../../progress' ;
24+ import type { WVPage } from './wvPage' ;
2325
2426function modifierFlags ( modifiers : Set < types . KeyboardModifier > ) {
2527 return {
@@ -51,11 +53,16 @@ function toButtonsMask(buttons: Set<types.MouseButton>): number {
5153 return mask ;
5254}
5355
56+ async function evaluateInFrame < Arg > ( progress : Progress , frame : frames . Frame , pageFunction : Func1 < Arg , void > , arg : Arg ) : Promise < void > {
57+ const context = await progress . race ( frame . mainContext ( ) ) ;
58+ await progress . race ( context . evaluate ( pageFunction , arg ) ) ;
59+ }
60+
5461export class RawKeyboardImpl implements input . RawKeyboard {
55- private _session : WVSession | undefined ;
62+ private _page : WVPage ;
5663
57- setSession ( session : WVSession ) {
58- this . _session = session ;
64+ constructor ( page : WVPage ) {
65+ this . _page = page ;
5966 }
6067
6168 async keydown ( progress : Progress , modifiers : Set < types . KeyboardModifier > , keyName : string , description : input . KeyDescription , autoRepeat : boolean ) : Promise < void > {
@@ -65,31 +72,33 @@ export class RawKeyboardImpl implements input.RawKeyboard {
6572 ...modifierFlags ( modifiers ) ,
6673 ...( text ? { text } : { } ) ,
6774 } ;
68- await callWebViewInput ( progress , this . _session , 'keydown' , params ) ;
75+ const frame = await this . _page . deepestFocusedFrame ( progress ) ;
76+ await evaluateInFrame ( progress , frame , p => ( globalThis as any ) . __pwWebViewInput . keydown ( p ) , params ) ;
6977 }
7078
7179 async keyup ( progress : Progress , modifiers : Set < types . KeyboardModifier > , keyName : string , description : input . KeyDescription ) : Promise < void > {
7280 const { code, keyCode, key, location } = description ;
7381 const params = { code, key, keyCode, location, ...modifierFlags ( modifiers ) } ;
74- await callWebViewInput ( progress , this . _session , 'keyup' , params ) ;
82+ const frame = await this . _page . deepestFocusedFrame ( progress ) ;
83+ await evaluateInFrame ( progress , frame , p => ( globalThis as any ) . __pwWebViewInput . keyup ( p ) , params ) ;
7584 }
7685
7786 async sendText ( progress : Progress , text : string ) : Promise < void > {
78- await callWebViewInput ( progress , this . _session , 'insertText' , text ) ;
87+ const frame = await this . _page . deepestFocusedFrame ( progress ) ;
88+ await evaluateInFrame ( progress , frame , t => ( globalThis as any ) . __pwWebViewInput . insertText ( t ) , text ) ;
7989 }
8090}
8191
8292export class RawMouseImpl implements input . RawMouse {
83- private _session : WVSession | undefined ;
93+ private _page : WVPage ;
8494
85- setSession ( session : WVSession ) {
86- this . _session = session ;
95+ constructor ( page : WVPage ) {
96+ this . _page = page ;
8797 }
8898
8999 async move ( progress : Progress , x : number , y : number , button : types . MouseButton | 'none' , buttons : Set < types . MouseButton > , modifiers : Set < types . KeyboardModifier > , forClick : boolean ) : Promise < void > {
90- await callWebViewInput ( progress , this . _session , 'mouseMove' , {
91- x, y, button : buttonToNumber ( button ) , buttons : toButtonsMask ( buttons ) , ...modifierFlags ( modifiers ) ,
92- } ) ;
100+ const { frame, point } = await this . _page . deepestFrameForPoint ( progress , x , y ) ;
101+ await evaluateInFrame ( progress , frame , p => ( globalThis as any ) . __pwWebViewInput . mouseMove ( p ) , { ...point , button : buttonToNumber ( button ) , buttons : toButtonsMask ( buttons ) , ...modifierFlags ( modifiers ) } ) ;
93102 }
94103
95104 async down ( progress : Progress , x : number , y : number , button : types . MouseButton , buttons : Set < types . MouseButton > , modifiers : Set < types . KeyboardModifier > , clickCount : number ) : Promise < void > {
@@ -114,43 +123,27 @@ export class RawMouseImpl implements input.RawMouse {
114123 }
115124
116125 async wheel ( progress : Progress , x : number , y : number , buttons : Set < types . MouseButton > , modifiers : Set < types . KeyboardModifier > , deltaX : number , deltaY : number ) : Promise < void > {
117- await callWebViewInput ( progress , this . _session , 'wheel' , { x, y, deltaX, deltaY, ...modifierFlags ( modifiers ) } ) ;
126+ const { frame, point } = await this . _page . deepestFrameForPoint ( progress , x , y ) ;
127+ await evaluateInFrame ( progress , frame , p => ( globalThis as any ) . __pwWebViewInput . wheel ( p ) , { ...point , deltaX, deltaY, ...modifierFlags ( modifiers ) } ) ;
118128 }
119129
120130 private async _mouseEvent ( progress : Progress , type : string , x : number , y : number , button : number , buttons : number , modifiers : Set < types . KeyboardModifier > , clickCount : number ) {
121- await callWebViewInput ( progress , this . _session , 'mouseEvent' , {
122- type, x, y, button, buttons, clickCount, ...modifierFlags ( modifiers ) ,
131+ const { frame, point } = await this . _page . deepestFrameForPoint ( progress , x , y ) ;
132+ await evaluateInFrame ( progress , frame , p => ( globalThis as any ) . __pwWebViewInput . mouseEvent ( p ) , {
133+ type, ...point , button, buttons, clickCount, ...modifierFlags ( modifiers ) ,
123134 } ) ;
124135 }
125136}
126137
127138export class RawTouchscreenImpl implements input . RawTouchscreen {
128- private _session : WVSession | undefined ;
139+ private _page : WVPage ;
129140
130- setSession ( session : WVSession ) {
131- this . _session = session ;
141+ constructor ( page : WVPage ) {
142+ this . _page = page ;
132143 }
133144
134145 async tap ( progress : Progress , x : number , y : number , modifiers : Set < types . KeyboardModifier > ) {
135- await callWebViewInput ( progress , this . _session , 'tap' , { x, y, ...modifierFlags ( modifiers ) } ) ;
136- }
137- }
138-
139- async function callWebViewInput ( progress : Progress , session : WVSession | undefined , method : string , arg : any ) : Promise < void > {
140- if ( ! session )
141- throw new Error ( 'Page is not initialized' ) ;
142- const expression = `window.__pwWebViewInput.${ method } (${ JSON . stringify ( arg ) } )` ;
143- // Some dispatchers are async — they spread events across event-loop tasks the
144- // way a real device does. Await the returned promise so the action only
145- // resolves once every event has been delivered. Stock WebKit's Runtime.evaluate
146- // has no awaitPromise option, so use the separate Runtime.awaitPromise command.
147- const { result } = await progress . race ( session . send ( 'Runtime.evaluate' , { expression, returnByValue : false } ) ) ;
148- // `result` is absent if evaluation failed (e.g. the frame navigated away).
149- // Only promises carry an objectId here — every __pwWebViewInput method returns
150- // void or a Promise — so this both awaits async dispatch and avoids leaking a
151- // handle for the synchronous (void) case.
152- if ( result ?. className === 'Promise' && result . objectId ) {
153- await progress . race ( session . send ( 'Runtime.awaitPromise' , { promiseObjectId : result . objectId , returnByValue : true } ) ) ;
154- session . sendMayFail ( 'Runtime.releaseObject' , { objectId : result . objectId } ) ;
146+ const { frame, point } = await this . _page . deepestFrameForPoint ( progress , x , y ) ;
147+ await evaluateInFrame ( progress , frame , p => ( globalThis as any ) . __pwWebViewInput . tap ( p ) , { ...point , ...modifierFlags ( modifiers ) } ) ;
155148 }
156149}
0 commit comments