2022-11-02 18:02:19 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								/*
  
						 
					
						
							
								
									
										
										
										
											2023-04-13 00:47:15 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								 *  Copyright  ( c )  2022 - 2023 ,  Linus  Groh  < linusg @ serenityos . org > 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-02 18:02:19 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								 *  SPDX - License - Identifier :  BSD - 2 - Clause 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								# include  <AK/JsonArray.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								# include  <AK/JsonObject.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								# include  <AK/JsonValue.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								# include  <AK/NumericLimits.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								# include  <AK/ScopeGuard.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								# include  <AK/Time.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								# include  <AK/Variant.h> 
  
						 
					
						
							
								
									
										
										
										
											2022-11-23 13:28:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibJS/Parser.h> 
  
						 
					
						
							
								
									
										
										
										
											2022-11-02 18:02:19 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibJS/Runtime/Array.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibJS/Runtime/ECMAScriptFunctionObject.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibJS/Runtime/GlobalEnvironment.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibJS/Runtime/JSONObject.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibJS/Runtime/Promise.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibJS/Runtime/PromiseConstructor.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/DOM/Document.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/DOM/HTMLCollection.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/DOM/NodeList.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/FileAPI/FileList.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/HTML/BrowsingContext.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/HTML/HTMLOptionsCollection.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/HTML/Scripting/Environments.h> 
  
						 
					
						
							
								
									
										
										
										
											2023-07-06 07:43:23 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/HTML/Scripting/TemporaryExecutionContext.h> 
  
						 
					
						
							
								
									
										
										
										
											2022-11-02 18:02:19 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/HTML/Window.h> 
  
						 
					
						
							
								
									
										
										
										
											2024-02-04 03:44:19 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/HTML/WindowProxy.h> 
  
						 
					
						
							
								
									
										
										
										
											2022-11-02 18:02:19 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/Page/Page.h> 
  
						 
					
						
							
								
									
										
										
										
											2024-08-30 22:36:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/Platform/EventLoopPlugin.h> 
  
						 
					
						
							
								
									
										
										
										
											2023-04-20 17:41:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/WebDriver/Contexts.h> 
  
						 
					
						
							
								
									
										
										
										
											2022-11-02 18:02:19 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/WebDriver/ExecuteScript.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								namespace  Web : : WebDriver  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-01-14 16:34:44 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# define TRY_OR_JS_ERROR(expression)                                                                  \ 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    ( {                                                                                                \
							 
						 
					
						
							
								
									
										
										
										
											2023-02-09 13:27:43 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto & &  _temporary_result  =  ( expression ) ;                                                      \
							 
						 
					
						
							
								
									
										
										
										
											2023-01-14 16:34:44 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( _temporary_result . is_error ( ) )  [[unlikely]]                                                \
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  ExecuteScriptResultType : : JavaScriptError ;                                          \
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        static_assert ( ! : : AK : : Detail : : IsLvalueReference < decltype ( _temporary_result . release_value ( ) ) > ,  \
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            " Do not return a reference from a fallible expression " ) ;                                  \
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        _temporary_result . release_value ( ) ;                                                            \
							 
						 
					
						
							
								
									
										
										
										
											2022-11-02 18:02:19 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								static  ErrorOr < JsonValue ,  ExecuteScriptResultType >  internal_json_clone_algorithm ( JS : : Realm & ,  JS : : Value ,  HashTable < JS : : Object * > &  seen ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								static  ErrorOr < JsonValue ,  ExecuteScriptResultType >  clone_an_object ( JS : : Realm & ,  JS : : Object & ,  HashTable < JS : : Object * > &  seen ,  auto  const &  clone_algorithm ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								// https://w3c.github.io/webdriver/#dfn-collection
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								static  bool  is_collection ( JS : : Object  const &  value )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // A collection is an Object that implements the Iterable interface, and whose:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // - initial value of the toString own property is "Arguments"
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        value . has_parameter_map ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // - instance of Array
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        | |  is < JS : : Array > ( value ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // - instance of FileList
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        | |  is < FileAPI : : FileList > ( value ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // - instance of HTMLAllCollection
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        | |  false  // FIXME
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // - instance of HTMLCollection
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        | |  is < DOM : : HTMLCollection > ( value ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // - instance of HTMLFormControlsCollection
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        | |  false  // FIXME
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // - instance of HTMLOptionsCollection
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        | |  is < HTML : : HTMLOptionsCollection > ( value ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // - instance of NodeList
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        | |  is < DOM : : NodeList > ( value ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								// https://w3c.github.io/webdriver/#dfn-json-clone
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								static  ErrorOr < JsonValue ,  ExecuteScriptResultType >  json_clone ( JS : : Realm &  realm ,  JS : : Value  value )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // To perform a JSON clone return the result of calling the internal JSON clone algorithm with arguments value and an empty List.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  seen  =  HashTable < JS : : Object * >  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  internal_json_clone_algorithm ( realm ,  value ,  seen ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								// https://w3c.github.io/webdriver/#dfn-internal-json-clone-algorithm
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								static  ErrorOr < JsonValue ,  ExecuteScriptResultType >  internal_json_clone_algorithm ( JS : : Realm &  realm ,  JS : : Value  value ,  HashTable < JS : : Object * > &  seen )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto &  vm  =  realm . vm ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // When required to run the internal JSON clone algorithm with arguments value and seen, a remote end must return the value of the first matching statement, matching on value:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // -> undefined
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // -> null
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( value . is_nullish ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // Success with data null.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  JsonValue  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // -> type Boolean
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // -> type Number
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // -> type String
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    //     Success with data value.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( value . is_boolean ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  JsonValue  {  value . as_bool ( )  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( value . is_number ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  JsonValue  {  value . as_double ( )  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( value . is_string ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-12-16 17:49:34 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  JsonValue  {  value . as_string ( ) . byte_string ( )  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-02 18:02:19 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // NOTE: BigInt and Symbol not mentioned anywhere in the WebDriver spec, as it references ES5.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    //       It assumes that all primitives are handled above, and the value is an object for the remaining steps.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( value . is_bigint ( )  | |  value . is_symbol ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  ExecuteScriptResultType : : JavaScriptError ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-04-20 17:41:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // FIXME: -> a collection
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // FIXME: -> instance of element
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // FIXME: -> instance of shadow root
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // -> a WindowProxy object
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( is < HTML : : WindowProxy > ( value . as_object ( ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  const &  window_proxy  =  static_cast < HTML : : WindowProxy & > ( value . as_object ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-02-05 12:34:29 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        // If the associated browsing context of the WindowProxy object in value has been destroyed, return error with
 
							 
						 
					
						
							
								
									
										
										
										
											2023-04-20 17:41:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        // error code stale element reference.
 
							 
						 
					
						
							
								
									
										
										
										
											2024-02-05 12:34:29 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( window_proxy . associated_browsing_context ( ) - > has_navigable_been_destroyed ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-04-20 17:41:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  ExecuteScriptResultType : : BrowsingContextDiscarded ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // Otherwise return success with data set to WindowProxy reference object for value.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  window_proxy_reference_object ( window_proxy ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-02 18:02:19 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // -> has an own property named "toJSON" that is a Function
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  to_json  =  value . as_object ( ) . get_without_side_effects ( vm . names . toJSON ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( to_json . is_function ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // Return success with the value returned by Function.[[Call]](toJSON) with value as the this value.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  to_json_result  =  TRY_OR_JS_ERROR ( to_json . as_function ( ) . internal_call ( value ,  JS : : MarkedVector < JS : : Value >  {  vm . heap ( )  } ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! to_json_result . is_string ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  ExecuteScriptResultType : : JavaScriptError ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-12-16 17:49:34 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  to_json_result . as_string ( ) . byte_string ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-02 18:02:19 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // -> Otherwise
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // 1. If value is in seen, return error with error code javascript error.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( seen . contains ( & value . as_object ( ) ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  ExecuteScriptResultType : : JavaScriptError ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // 2. Append value to seen.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    seen . set ( & value . as_object ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    ScopeGuard  remove_seen  {  [ & ]  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // 4. Remove the last element of seen.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        seen . remove ( & value . as_object ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    }  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // 3. Let result be the value of running the clone an object algorithm with arguments value and seen, and the internal JSON clone algorithm as the clone algorithm.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  result  =  TRY ( clone_an_object ( realm ,  value . as_object ( ) ,  seen ,  internal_json_clone_algorithm ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // 5. Return result.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  result ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								// https://w3c.github.io/webdriver/#dfn-clone-an-object
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								static  ErrorOr < JsonValue ,  ExecuteScriptResultType >  clone_an_object ( JS : : Realm &  realm ,  JS : : Object &  value ,  HashTable < JS : : Object * > &  seen ,  auto  const &  clone_algorithm )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto &  vm  =  realm . vm ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // 1. Let result be the value of the first matching statement, matching on value:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  get_result  =  [ & ] ( )  - >  ErrorOr < Variant < JsonArray ,  JsonObject > ,  ExecuteScriptResultType >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // -> a collection
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( is_collection ( value ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            // A new Array which length property is equal to the result of getting the property length of value.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            auto  length_property  =  TRY_OR_JS_ERROR ( value . internal_get_own_property ( vm . names . length ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( ! length_property - > value . has_value ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  ExecuteScriptResultType : : JavaScriptError ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            auto  length  =  TRY_OR_JS_ERROR ( length_property - > value - > to_length ( vm ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( length  >  NumericLimits < u32 > : : max ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  ExecuteScriptResultType : : JavaScriptError ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            auto  array  =  JsonArray  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            for  ( size_t  i  =  0 ;  i  <  length ;  + + i ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-04-17 15:38:27 +10:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                array . must_append ( JsonValue  { } ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-02 18:02:19 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  array ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // -> Otherwise
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            // A new Object.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  JsonObject  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  result  =  TRY ( get_result ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // 2. For each enumerable own property in value, run the following substeps:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    for  ( auto &  key  :  MUST ( value . Object : : internal_own_property_keys ( ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // 1. Let name be the name of the property.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  name  =  MUST ( JS : : PropertyKey : : from_value ( vm ,  key ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! value . storage_get ( name ) - > attributes . is_enumerable ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // 2. Let source property value be the result of getting a property named name from value. If doing so causes script to be run and that script throws an error, return error with error code javascript error.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  source_property_value  =  TRY_OR_JS_ERROR ( value . internal_get_own_property ( name ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! source_property_value . has_value ( )  | |  ! source_property_value - > value . has_value ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // 3. Let cloned property result be the result of calling the clone algorithm with arguments source property value and seen.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  cloned_property_result  =  clone_algorithm ( realm ,  * source_property_value - > value ,  seen ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
										 
							
							
								        // 4. If cloned property result is a success, set a property of result with name name and value equal to cloned property result’  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! cloned_property_result . is_error ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            result . visit ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                [ & ] ( JsonArray &  array )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    // NOTE: If this was a JS array, only indexed properties would be serialized anyway.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    if  ( name . is_number ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-08 13:53:29 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                        array . set ( name . as_number ( ) ,  cloned_property_result . value ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-02 18:02:19 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                [ & ] ( JsonObject &  object )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    object . set ( name . to_string ( ) ,  cloned_property_result . value ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // 5. Otherwise, return cloned property result.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  cloned_property_result ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  result . visit ( [ & ] ( auto  const &  value )  - >  JsonValue  {  return  value ;  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								// https://w3c.github.io/webdriver/#dfn-execute-a-function-body
  
						 
					
						
							
								
									
										
										
										
											2023-12-16 17:49:34 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								static  JS : : ThrowCompletionOr < JS : : Value >  execute_a_function_body ( Web : : Page &  page ,  ByteString  const &  body ,  JS : : MarkedVector < JS : : Value >  parameters )  
						 
					
						
							
								
									
										
										
										
											2022-11-02 18:02:19 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // FIXME: If at any point during the algorithm a user prompt appears, immediately return Completion { [[Type]]: normal, [[Value]]: null, [[Target]]: empty }, but continue to run the other steps of this algorithm in parallel.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
										 
							
							
								    // 1. Let window be the associated window of the current browsing context’  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // FIXME: This will need adjusting when WebDriver supports frames.
 
							 
						 
					
						
							
								
									
										
										
										
											2024-03-10 08:41:18 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  window  =  page . top_level_browsing_context ( ) . active_document ( ) - > window ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-02 18:02:19 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // 2. Let environment settings be the environment settings object for window.
 
							 
						 
					
						
							
								
									
										
										
										
											2024-03-10 08:41:18 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto &  environment_settings  =  Web : : HTML : : relevant_settings_object ( * window ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-02 18:02:19 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
										 
							
							
								    // 3. Let global scope be environment settings realm’  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto &  global_scope  =  environment_settings . realm ( ) . global_environment ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-03-10 08:41:18 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto &  realm  =  window - > realm ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-02 18:02:19 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-12-16 17:49:34 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  source_text  =  ByteString : : formatted ( " function() {{ {} }} " ,  body ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-02 18:02:19 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  parser  =  JS : : Parser  {  JS : : Lexer  {  source_text  }  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  function_expression  =  parser . parse_function_node < JS : : FunctionExpression > ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // 4. If body is not parsable as a FunctionBody or if parsing detects an early error, return Completion { [[Type]]: normal, [[Value]]: null, [[Target]]: empty }.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( parser . has_errors ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  JS : : js_null ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // 5. If body begins with a directive prologue that contains a use strict directive then let strict be true, otherwise let strict be false.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // NOTE: Handled in step 8 below.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // 6. Prepare to run a script with environment settings.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    environment_settings . prepare_to_run_script ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // 7. Prepare to run a callback with environment settings.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    environment_settings . prepare_to_run_callback ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // 8. Let function be the result of calling FunctionCreate, with arguments:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // kind
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    //    Normal.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // list
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    //    An empty List.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // body
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    //    The result of parsing body above.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // global scope
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    //    The result of parsing global scope above.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // strict
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    //    The result of parsing strict above.
 
							 
						 
					
						
							
								
									
										
										
										
											2024-05-22 11:04:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  function  =  JS : : ECMAScriptFunctionObject : : create ( realm ,  " " ,  move ( source_text ) ,  function_expression - > body ( ) ,  function_expression - > parameters ( ) ,  function_expression - > function_length ( ) ,  function_expression - > local_variables_names ( ) ,  & global_scope ,  nullptr ,  function_expression - > kind ( ) ,  function_expression - > is_strict_mode ( ) ,  function_expression - > parsing_insights ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-02 18:02:19 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // 9. Let completion be Function.[[Call]](window, parameters) with function as the this value.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // NOTE: This is not entirely clear, but I don't think they mean actually passing `function` as
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // the this value argument, but using it as the object [[Call]] is executed on.
 
							 
						 
					
						
							
								
									
										
										
										
											2024-03-10 08:41:18 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  completion  =  function - > internal_call ( window ,  move ( parameters ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-02 18:02:19 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // 10. Clean up after running a callback with environment settings.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    environment_settings . clean_up_after_running_callback ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // 11. Clean up after running a script with environment settings.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    environment_settings . clean_up_after_running_script ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // 12. Return completion.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  completion ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-09-13 07:42:24 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								class  HeapTimer  :  public  JS : : Cell  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    JS_CELL ( HeapTimer ,  JS : : Cell ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    JS_DECLARE_ALLOCATOR ( HeapTimer ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								public :  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    explicit  HeapTimer ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        :  m_timer ( Core : : Timer : : create ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    virtual  ~ HeapTimer ( )  override  =  default ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    void  start ( u64  timeout_ms ,  JS : : NonnullGCPtr < OnScriptComplete >  on_timeout ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        m_on_timeout  =  on_timeout ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        m_timer - > on_timeout  =  [ this ] ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            m_timed_out  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( m_on_timeout )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                auto  error_object  =  JsonObject  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                error_object . set ( " name " ,  " Error " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                error_object . set ( " message " ,  " Script Timeout " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                m_on_timeout - > function ( ) ( {  ExecuteScriptResultType : : Timeout ,  move ( error_object )  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                m_on_timeout  =  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        m_timer - > set_interval ( static_cast < int > ( timeout_ms ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        m_timer - > set_single_shot ( true ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        m_timer - > start ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    void  stop ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        m_on_timeout  =  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        m_timer - > stop ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    bool  is_timed_out ( )  const  {  return  m_timed_out ;  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								private :  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    virtual  void  visit_edges ( JS : : Cell : : Visitor &  visitor )  override 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        Base : : visit_edges ( visitor ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        visitor . visit ( m_on_timeout ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    NonnullRefPtr < Core : : Timer >  m_timer ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    JS : : GCPtr < OnScriptComplete >  m_on_timeout ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    bool  m_timed_out  {  false  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								} ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								JS_DEFINE_ALLOCATOR ( HeapTimer ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								void  execute_script ( Web : : Page &  page ,  ByteString  body ,  JS : : MarkedVector < JS : : Value >  arguments ,  Optional < u64 >  const &  timeout_ms ,  JS : : NonnullGCPtr < OnScriptComplete >  on_complete )  
						 
					
						
							
								
									
										
										
										
											2022-11-02 18:02:19 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2024-08-30 22:36:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto *  document  =  page . top_level_browsing_context ( ) . active_document ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-02 18:02:19 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto *  window  =  page . top_level_browsing_context ( ) . active_window ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto &  realm  =  window - > realm ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-08-30 22:36:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto &  vm  =  window - > vm ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-02 18:02:19 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-08-30 22:36:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // 5. Let timer be a new timer.
 
							 
						 
					
						
							
								
									
										
										
										
											2024-09-13 07:42:24 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  timer  =  vm . heap ( ) . allocate < HeapTimer > ( realm ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-08-30 22:36:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // 6. If timeout is not null:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( timeout_ms . has_value ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // 1. Start the timer with timer and timeout.
 
							 
						 
					
						
							
								
									
										
										
										
											2024-09-13 07:42:24 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        timer - > start ( timeout_ms . value ( ) ,  on_complete ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-08-30 22:36:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-02 18:02:19 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-08-30 22:36:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // AD-HOC: An execution context is required for Promise creation hooks.
 
							 
						 
					
						
							
								
									
										
										
										
											2024-09-13 07:42:24 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    HTML : : TemporaryExecutionContext  execution_context  {  document - > relevant_settings_object ( ) ,  HTML : : TemporaryExecutionContext : : CallbacksEnabled : : Yes  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-08-30 22:36:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // 7. Let promise be a new Promise.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  promise_capability  =  WebIDL : : create_promise ( realm ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    JS : : NonnullGCPtr  promise  {  verify_cast < JS : : Promise > ( * promise_capability - > promise ( ) )  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // 8. Run the following substeps in parallel:
 
							 
						 
					
						
							
								
									
										
										
										
											2024-09-13 07:42:24 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    Platform : : EventLoopPlugin : : the ( ) . deferred_invoke ( [ & realm ,  & page ,  promise_capability ,  document ,  promise ,  body  =  move ( body ) ,  arguments  =  move ( arguments ) ] ( )  mutable  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        HTML : : TemporaryExecutionContext  execution_context  {  document - > relevant_settings_object ( )  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-11-02 18:02:19 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // 1. Let scriptPromise be the result of promise-calling execute a function body, with arguments body and arguments.
 
							 
						 
					
						
							
								
									
										
										
										
											2024-08-30 22:36:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto  script_result  =  execute_a_function_body ( page ,  body ,  move ( arguments ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-02 18:02:19 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // 2. Upon fulfillment of scriptPromise with value v, resolve promise with value v.
 
							 
						 
					
						
							
								
									
										
										
										
											2024-08-30 22:36:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( script_result . has_value ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            WebIDL : : resolve_promise ( realm ,  promise_capability ,  script_result . release_value ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-11-02 18:02:19 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // 3. Upon rejection of scriptPromise with value r, reject promise with value r.
 
							 
						 
					
						
							
								
									
										
										
										
											2024-08-30 22:36:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( script_result . is_throw_completion ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            promise - > reject ( * script_result . throw_completion ( ) . value ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // 9. Wait until promise is resolved, or timer's timeout fired flag is set, whichever occurs first.
 
							 
						 
					
						
							
								
									
										
										
										
											2024-09-13 07:42:24 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  reaction_steps  =  JS : : create_heap_function ( vm . heap ( ) ,  [ & realm ,  promise ,  timer ,  on_complete ] ( JS : : Value )  - >  WebIDL : : ExceptionOr < JS : : Value >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( timer - > is_timed_out ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  JS : : js_undefined ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        timer - > stop ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  json_value_or_error  =  json_clone ( realm ,  promise - > result ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( json_value_or_error . is_error ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            auto  error_object  =  JsonObject  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            error_object . set ( " name " ,  " Error " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            error_object . set ( " message " ,  " Could not clone result value " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            on_complete - > function ( ) ( {  ExecuteScriptResultType : : JavaScriptError ,  move ( error_object )  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2024-08-30 22:36:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-09-13 07:42:24 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        // 10. If promise is still pending and timer's timeout fired flag is set, return error with error code script timeout.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // NOTE: This is handled by the HeapTimer.
 
							 
						 
					
						
							
								
									
										
										
										
											2024-08-30 22:36:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-09-13 07:42:24 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        // 11. If promise is fulfilled with value v, let result be JSON clone with session and v, and return success with data result.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        else  if  ( promise - > state ( )  = =  JS : : Promise : : State : : Fulfilled )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            on_complete - > function ( ) ( {  ExecuteScriptResultType : : PromiseResolved ,  json_value_or_error . release_value ( )  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2024-08-30 22:36:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-09-13 07:42:24 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        // 12. If promise is rejected with reason r, let result be JSON clone with session and r, and return error with error code javascript error and data result.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        else  if  ( promise - > state ( )  = =  JS : : Promise : : State : : Rejected )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            on_complete - > function ( ) ( {  ExecuteScriptResultType : : PromiseRejected ,  json_value_or_error . release_value ( )  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2024-08-30 22:36:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-09-13 07:42:24 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  JS : : js_undefined ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-08-30 22:36:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-09-13 07:42:24 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    WebIDL : : react_to_promise ( promise_capability ,  reaction_steps ,  reaction_steps ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-02 18:02:19 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-09-13 07:42:24 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								void  execute_async_script ( Web : : Page &  page ,  ByteString  body ,  JS : : MarkedVector < JS : : Value >  arguments ,  Optional < u64 >  const &  timeout_ms ,  JS : : NonnullGCPtr < OnScriptComplete >  on_complete )  
						 
					
						
							
								
									
										
										
										
											2022-11-02 18:02:19 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2023-03-11 05:47:16 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto *  document  =  page . top_level_browsing_context ( ) . active_document ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-02 18:02:19 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto *  window  =  page . top_level_browsing_context ( ) . active_window ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto &  realm  =  window - > realm ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto &  vm  =  window - > vm ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-08-30 22:36:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // 5. Let timer be a new timer.
 
							 
						 
					
						
							
								
									
										
										
										
											2024-09-13 07:42:24 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  timer  =  vm . heap ( ) . allocate < HeapTimer > ( realm ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-08-30 22:36:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // 6. If timeout is not null:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( timeout_ms . has_value ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // 1. Start the timer with timer and timeout.
 
							 
						 
					
						
							
								
									
										
										
										
											2024-09-13 07:42:24 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        timer - > start ( timeout_ms . value ( ) ,  on_complete ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-08-30 22:36:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-17 18:07:27 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-07-06 07:43:23 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // AD-HOC: An execution context is required for Promise creation hooks.
 
							 
						 
					
						
							
								
									
										
										
										
											2024-09-13 07:42:24 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    HTML : : TemporaryExecutionContext  execution_context  {  document - > relevant_settings_object ( ) ,  HTML : : TemporaryExecutionContext : : CallbacksEnabled : : Yes  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-30 15:23:46 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-08-30 22:36:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // 7. Let promise be a new Promise.
 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-30 15:23:46 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  promise_capability  =  WebIDL : : create_promise ( realm ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    JS : : NonnullGCPtr  promise  {  verify_cast < JS : : Promise > ( * promise_capability - > promise ( ) )  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-02 18:02:19 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-08-30 22:36:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // 8. Run the following substeps in parallel:
 
							 
						 
					
						
							
								
									
										
										
										
											2024-09-13 07:42:24 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    Platform : : EventLoopPlugin : : the ( ) . deferred_invoke ( [ & vm ,  & realm ,  & page ,  timer ,  document ,  promise_capability ,  promise ,  body  =  move ( body ) ,  arguments  =  move ( arguments ) ] ( )  mutable  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        HTML : : TemporaryExecutionContext  execution_context  {  document - > relevant_settings_object ( )  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-11-02 18:02:19 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // 1. Let resolvingFunctions be CreateResolvingFunctions(promise).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  resolving_functions  =  promise - > create_resolving_functions ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // 2. Append resolvingFunctions.[[Resolve]] to arguments.
 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-26 16:09:02 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        arguments . append ( resolving_functions . resolve ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-02 18:02:19 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // 3. Let result be the result of calling execute a function body, with arguments body and arguments.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // FIXME: 'result' -> 'scriptResult' (spec issue)
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  script_result  =  execute_a_function_body ( page ,  body ,  move ( arguments ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-08-30 22:36:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        // 4. If scriptResult.[[Type]] is not normal, then reject promise with value scriptResult.[[Value]], and abort these steps.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-02 18:02:19 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // NOTE: Prior revisions of this specification did not recognize the return value of the provided script.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        //       In order to preserve legacy behavior, the return value only influences the command if it is a
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        //       "thenable"  object or if determining this produces an exception.
 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-17 18:17:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( script_result . is_throw_completion ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            promise - > reject ( * script_result . throw_completion ( ) . value ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-30 15:23:46 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-17 18:17:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-02 18:02:19 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // 5. If Type(scriptResult.[[Value]]) is not Object, then abort these steps.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! script_result . value ( ) . is_object ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-30 15:23:46 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-02 18:02:19 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // 6. Let then be Get(scriptResult.[[Value]], "then").
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  then  =  script_result . value ( ) . as_object ( ) . get ( vm . names . then ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // 7. If then.[[Type]] is not normal, then reject promise with value then.[[Value]], and abort these steps.
 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-17 18:17:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( then . is_throw_completion ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            promise - > reject ( * then . throw_completion ( ) . value ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-30 15:23:46 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-17 18:17:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-02 18:02:19 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // 8. If IsCallable(then.[[Type]]) is false, then abort these steps.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! then . value ( ) . is_function ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-30 15:23:46 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-02 18:02:19 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // 9. Let scriptPromise be PromiseResolve(Promise, scriptResult.[[Value]]).
 
							 
						 
					
						
							
								
									
										
										
										
											2023-04-13 00:47:15 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto  script_promise_or_error  =  JS : : promise_resolve ( vm ,  realm . intrinsics ( ) . promise_constructor ( ) ,  script_result . value ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-02 18:02:19 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( script_promise_or_error . is_throw_completion ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-30 15:23:46 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-02 18:02:19 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto &  script_promise  =  static_cast < JS : : Promise & > ( * script_promise_or_error . value ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        vm . custom_data ( ) - > spin_event_loop_until ( [ & ]  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-09-13 07:42:24 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  timer - > is_timed_out ( )  | |  script_promise . state ( )  ! =  JS : : Promise : : State : : Pending ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-02 18:02:19 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // 10. Upon fulfillment of scriptPromise with value v, resolve promise with value v.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( script_promise . state ( )  = =  JS : : Promise : : State : : Fulfilled ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-30 15:23:46 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            WebIDL : : resolve_promise ( realm ,  promise_capability ,  script_promise . result ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-02 18:02:19 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // 11. Upon rejection of scriptPromise with value r, reject promise with value r.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( script_promise . state ( )  = =  JS : : Promise : : State : : Rejected ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-30 15:23:46 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            WebIDL : : reject_promise ( realm ,  promise_capability ,  script_promise . result ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-08-30 22:36:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-02 18:02:19 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-08-30 22:36:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // 9. Wait until promise is resolved, or timer's timeout fired flag is set, whichever occurs first.
 
							 
						 
					
						
							
								
									
										
										
										
											2024-09-13 07:42:24 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  reaction_steps  =  JS : : create_heap_function ( vm . heap ( ) ,  [ & realm ,  promise ,  timer ,  on_complete ] ( JS : : Value )  - >  WebIDL : : ExceptionOr < JS : : Value >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( timer - > is_timed_out ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  JS : : js_undefined ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        timer - > stop ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  json_value_or_error  =  json_clone ( realm ,  promise - > result ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( json_value_or_error . is_error ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            auto  error_object  =  JsonObject  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            error_object . set ( " name " ,  " Error " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            error_object . set ( " message " ,  " Could not clone result value " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            on_complete - > function ( ) ( {  ExecuteScriptResultType : : JavaScriptError ,  move ( error_object )  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-30 15:23:46 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-09-13 07:42:24 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        // 10. If promise is still pending and timer's timeout fired flag is set, return error with error code script timeout.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // NOTE: This is handled by the HeapTimer.
 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-17 18:07:27 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-09-13 07:42:24 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        // 11. If promise is fulfilled with value v, let result be JSON clone with session and v, and return success with data result.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        else  if  ( promise - > state ( )  = =  JS : : Promise : : State : : Fulfilled )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            on_complete - > function ( ) ( {  ExecuteScriptResultType : : PromiseResolved ,  json_value_or_error . release_value ( )  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-30 15:23:46 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-09-13 07:42:24 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        // 12. If promise is rejected with reason r, let result be JSON clone with session and r, and return error with error code javascript error and data result.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        else  if  ( promise - > state ( )  = =  JS : : Promise : : State : : Rejected )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            on_complete - > function ( ) ( {  ExecuteScriptResultType : : PromiseRejected ,  json_value_or_error . release_value ( )  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2024-08-30 22:36:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-09-13 07:42:24 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  JS : : js_undefined ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-30 15:23:46 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-09-13 07:42:24 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    WebIDL : : react_to_promise ( promise_capability ,  reaction_steps ,  reaction_steps ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-02 18:02:19 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}