99using Newtonsoft . Json . Linq ;
1010using PuppeteerSharp . Helpers ;
1111using PuppeteerSharp . Messaging ;
12+ using PuppeteerSharp . QueryHandlers ;
1213
1314namespace PuppeteerSharp
1415{
@@ -18,9 +19,9 @@ public class ExecutionContext : IExecutionContext
1819 internal const string EvaluationScriptUrl = "__puppeteer_evaluation_script__" ;
1920
2021 private static readonly Regex _sourceUrlRegex = new ( @"^[\040\t]*\/\/[@#] sourceURL=\s*\S*?\s*$" , RegexOptions . Multiline ) ;
21- private static string _injectedSource ;
2222
2323 private readonly string _evaluationScriptSuffix = $ "//# sourceURL={ EvaluationScriptUrl } ";
24+ private readonly TaskQueue _puppeteerUtilQueue = new ( ) ;
2425 private IJSHandle _puppeteerUtil ;
2526
2627 internal ExecutionContext (
@@ -98,12 +99,27 @@ public async Task<IJSHandle> QueryObjectsAsync(IJSHandle prototypeHandle)
9899
99100 internal async Task < IJSHandle > GetPuppeteerUtilAsync ( )
100101 {
101- if ( _puppeteerUtil == null )
102+ await _puppeteerUtilQueue . Enqueue ( async ( ) =>
102103 {
103- var injectedSource = GetInjectedSource ( ) ;
104- _puppeteerUtil = await EvaluateExpressionHandleAsync ( injectedSource ) . ConfigureAwait ( false ) ;
105- }
106-
104+ if ( _puppeteerUtil == null )
105+ {
106+ await Client . Connection . ScriptInjector . InjectAsync (
107+ async ( string script ) =>
108+ {
109+ if ( _puppeteerUtil != null )
110+ {
111+ await _puppeteerUtil . DisposeAsync ( ) . ConfigureAwait ( false ) ;
112+ }
113+
114+ await InstallGlobalBindingAsync ( new Binding (
115+ "__ariaQuerySelector" ,
116+ ( Func < IElementHandle , string , Task < IElementHandle > > ) Client . Connection . CustomQuerySelectorRegistry . InternalQueryHandlers [ "aria" ] . QueryOneAsync ) )
117+ . ConfigureAwait ( false ) ;
118+ _puppeteerUtil = await EvaluateExpressionHandleAsync ( script ) . ConfigureAwait ( false ) ;
119+ } ,
120+ _puppeteerUtil == null ) . ConfigureAwait ( false ) ;
121+ }
122+ } ) . ConfigureAwait ( false ) ;
107123 return _puppeteerUtil ;
108124 }
109125
@@ -138,22 +154,6 @@ internal async Task<IElementHandle> AdoptElementHandleAsync(IElementHandle eleme
138154 return CreateJSHandle ( obj . Object ) as ElementHandle ;
139155 }
140156
141- private static string GetInjectedSource ( )
142- {
143- if ( string . IsNullOrEmpty ( _injectedSource ) )
144- {
145- var assembly = Assembly . GetExecutingAssembly ( ) ;
146- var resourceName = "PuppeteerSharp.Injected.injected.js" ;
147-
148- using var stream = assembly . GetManifestResourceStream ( resourceName ) ;
149- using var reader = new StreamReader ( stream ) ;
150- var fileContent = reader . ReadToEnd ( ) ;
151- _injectedSource = fileContent ;
152- }
153-
154- return _injectedSource ;
155- }
156-
157157 private static string GetExceptionMessage ( EvaluateExceptionResponseDetails exceptionDetails )
158158 {
159159 if ( exceptionDetails . Exception != null )
@@ -175,6 +175,24 @@ private static string GetExceptionMessage(EvaluateExceptionResponseDetails excep
175175 return message ;
176176 }
177177
178+ private async Task InstallGlobalBindingAsync ( Binding binding )
179+ {
180+ try
181+ {
182+ if ( World != null )
183+ {
184+ World . Bindings . TryAdd ( binding . Name , binding ) ;
185+ await World . AddBindingToContextAsync ( this , binding . Name ) . ConfigureAwait ( false ) ;
186+ }
187+ }
188+ catch
189+ {
190+ // If the binding cannot be added, then either the browser doesn't support
191+ // bindings (e.g. Firefox) or the context is broken. Either breakage is
192+ // okay, so we ignore the error.
193+ }
194+ }
195+
178196 private async Task < T > RemoteObjectTaskToObject < T > ( Task < RemoteObject > remote )
179197 {
180198 var response = await remote . ConfigureAwait ( false ) ;
0 commit comments