2020-03-18 20:20:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								/*
  
						 
					
						
							
								
									
										
										
										
											2022-01-24 16:39:02 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								 *  Copyright  ( c )  2020 - 2022 ,  Andreas  Kling  < kling @ serenityos . org > 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-14 18:03:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								 *  Copyright  ( c )  2022 ,  Luke  Wilde  < lukew @ serenityos . org > 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-18 20:20:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								 * 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-22 01:24:48 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								 *  SPDX - License - Identifier :  BSD - 2 - Clause 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-18 20:20:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-09-19 01:38:14 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <AK/StringBuilder.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibJS/Interpreter.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibJS/Parser.h> 
  
						 
					
						
							
								
									
										
										
										
											2021-10-14 18:03:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibJS/Runtime/AbstractOperations.h> 
  
						 
					
						
							
								
									
										
										
										
											2021-09-24 22:40:38 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibJS/Runtime/ECMAScriptFunctionObject.h> 
  
						 
					
						
							
								
									
										
										
										
											2021-10-14 18:03:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibJS/Runtime/NativeFunction.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibJS/Runtime/ObjectEnvironment.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibJS/Runtime/VM.h> 
  
						 
					
						
							
								
									
										
										
										
											2022-08-28 13:42:07 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/Bindings/EventTargetPrototype.h> 
  
						 
					
						
							
								
									
										
										
										
											2021-10-14 18:03:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/Bindings/IDLAbstractOperations.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/Bindings/MainThreadVM.h> 
  
						 
					
						
							
								
									
										
										
										
											2022-02-16 20:43:24 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/DOM/AbortSignal.h> 
  
						 
					
						
							
								
									
										
										
										
											2022-08-08 14:12:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/DOM/DOMEventListener.h> 
  
						 
					
						
							
								
									
										
										
										
											2021-09-19 12:49:27 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/DOM/Document.h> 
  
						 
					
						
							
								
									
										
										
										
											2021-05-04 22:38:36 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/DOM/Event.h> 
  
						 
					
						
							
								
									
										
										
										
											2021-09-25 23:11:51 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/DOM/EventDispatcher.h> 
  
						 
					
						
							
								
									
										
										
										
											2020-03-18 15:22:31 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/DOM/EventTarget.h> 
  
						 
					
						
							
								
									
										
										
										
											2022-02-16 20:43:24 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/DOM/IDLEventListener.h> 
  
						 
					
						
							
								
									
										
										
										
											2021-10-14 18:03:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/HTML/ErrorEvent.h> 
  
						 
					
						
							
								
									
										
										
										
											2021-09-19 01:38:14 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/HTML/EventHandler.h> 
  
						 
					
						
							
								
									
										
										
										
											2022-01-24 16:39:02 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/HTML/EventNames.h> 
  
						 
					
						
							
								
									
										
										
										
											2021-10-14 18:03:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/HTML/FormAssociatedElement.h> 
  
						 
					
						
							
								
									
										
										
										
											2021-09-19 12:49:27 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/HTML/HTMLBodyElement.h> 
  
						 
					
						
							
								
									
										
										
										
											2021-10-14 18:03:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/HTML/HTMLFormElement.h> 
  
						 
					
						
							
								
									
										
										
										
											2021-09-19 12:49:27 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/HTML/HTMLFrameSetElement.h> 
  
						 
					
						
							
								
									
										
										
										
											2022-03-07 23:08:26 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/HTML/Window.h> 
  
						 
					
						
							
								
									
										
										
										
											2022-01-24 16:39:02 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/UIEvents/EventNames.h> 
  
						 
					
						
							
								
									
										
										
										
											2020-03-18 15:22:31 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-07-26 19:37:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								namespace  Web : : DOM  {  
						 
					
						
							
								
									
										
										
										
											2020-03-18 15:22:31 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-08-28 13:42:07 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								EventTarget : : EventTarget ( JS : : Realm &  realm )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    :  PlatformObject ( realm ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-14 13:21:51 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								EventTarget : : ~ EventTarget ( )  =  default ;  
						 
					
						
							
								
									
										
										
										
											2020-03-18 15:22:31 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-08-28 13:42:07 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								void  EventTarget : : visit_edges ( Cell : : Visitor &  visitor )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    Base : : visit_edges ( visitor ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    for  ( auto &  event_listener  :  m_event_listener_list ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        visitor . visit ( event_listener . ptr ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    for  ( auto &  it  :  m_event_handler_map ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        visitor . visit ( it . value . ptr ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								Vector < JS : : Handle < DOMEventListener > >  EventTarget : : event_listener_list ( )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    Vector < JS : : Handle < DOMEventListener > >  list ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    for  ( auto &  listener  :  m_event_listener_list ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        list . append ( * listener ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  list ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-19 22:02:32 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								// https://dom.spec.whatwg.org/#concept-flatten-options
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								static  bool  flatten_event_listener_options ( Variant < EventListenerOptions ,  bool >  const &  options )  
						 
					
						
							
								
									
										
										
										
											2022-02-16 20:43:24 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2022-02-19 22:02:32 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // 1. If options is a boolean, then return options.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( options . has < bool > ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  options . get < bool > ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // 2. Return options["capture"].
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  options . get < EventListenerOptions > ( ) . capture ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								static  bool  flatten_event_listener_options ( Variant < AddEventListenerOptions ,  bool >  const &  options )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // 1. If options is a boolean, then return options.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( options . has < bool > ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  options . get < bool > ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // 2. Return options["capture"].
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  options . get < AddEventListenerOptions > ( ) . capture ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								struct  FlattenedAddEventListenerOptions  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    bool  capture  {  false  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    bool  passive  {  false  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    bool  once  {  false  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-28 13:42:07 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    JS : : GCPtr < AbortSignal >  signal ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-19 22:02:32 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								} ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								// https://dom.spec.whatwg.org/#event-flatten-more
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								static  FlattenedAddEventListenerOptions  flatten_add_event_listener_options ( Variant < AddEventListenerOptions ,  bool >  const &  options )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // 1. Let capture be the result of flattening options.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    bool  capture  =  flatten_event_listener_options ( options ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // 2. Let once and passive be false.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-16 20:43:24 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    bool  once  =  false ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-19 22:02:32 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    bool  passive  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // 3. Let signal be null.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-28 13:42:07 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    JS : : GCPtr < AbortSignal >  signal ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-19 22:02:32 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // 4. If options is a dictionary, then:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( options . has < AddEventListenerOptions > ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto &  add_event_listener_options  =  options . get < AddEventListenerOptions > ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // 1. Set passive to options["passive"] and once to options["once"].
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        passive  =  add_event_listener_options . passive ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        once  =  add_event_listener_options . once ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // 2. If options["signal"] exists, then set signal to options["signal"].
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( add_event_listener_options . signal . has_value ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-28 13:42:07 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            signal  =  add_event_listener_options . signal . value ( ) . ptr ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-19 22:02:32 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // 5. Return capture, passive, once, and signal.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-28 13:42:07 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    return  FlattenedAddEventListenerOptions  {  . capture  =  capture ,  . passive  =  passive ,  . once  =  once ,  . signal  =  signal . ptr ( )  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-19 22:02:32 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								// https://dom.spec.whatwg.org/#dom-eventtarget-addeventlistener
  
						 
					
						
							
								
									
										
										
										
											2022-08-08 14:12:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								void  EventTarget : : add_event_listener ( FlyString  const &  type ,  IDLEventListener *  callback ,  Variant < AddEventListenerOptions ,  bool >  const &  options )  
						 
					
						
							
								
									
										
										
										
											2022-02-19 22:02:32 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // 1. Let capture, passive, once, and signal be the result of flattening more options.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  flattened_options  =  flatten_add_event_listener_options ( options ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-16 20:43:24 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // 2. Add an event listener with this and an event listener whose type is type, callback is callback, capture is capture, passive is passive,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    //    once is once, and signal is signal.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-08 14:12:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // FIXME: Don't use main_thread_internal_window_object() when EventTarget can find its own heap.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto *  event_listener  =  Bindings : : main_thread_internal_window_object ( ) . heap ( ) . allocate_without_realm < DOMEventListener > ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-16 20:43:24 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    event_listener - > type  =  type ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-08 14:12:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    event_listener - > callback  =  callback ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-19 22:02:32 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    event_listener - > signal  =  move ( flattened_options . signal ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    event_listener - > capture  =  flattened_options . capture ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    event_listener - > passive  =  flattened_options . passive ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    event_listener - > once  =  flattened_options . once ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-08 14:12:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    add_an_event_listener ( * event_listener ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-16 20:43:24 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-08-08 14:12:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								void  EventTarget : : add_event_listener_without_options ( FlyString  const &  type ,  IDLEventListener &  callback )  
						 
					
						
							
								
									
										
										
										
											2022-02-19 22:02:32 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2022-08-08 14:12:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    add_event_listener ( type ,  & callback ,  AddEventListenerOptions  { } ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-19 22:02:32 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-04-10 18:51:29 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								// https://dom.spec.whatwg.org/#add-an-event-listener
  
						 
					
						
							
								
									
										
										
										
											2022-08-08 14:12:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								void  EventTarget : : add_an_event_listener ( DOMEventListener &  listener )  
						 
					
						
							
								
									
										
										
										
											2020-03-18 15:22:31 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2022-02-16 20:43:24 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
										 
							
							
								    // FIXME: 1. If eventTarget is a ServiceWorkerGlobalScope object, its service worker’ ’  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
										 
							
							
								    //           and listener’  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    //           that this might not give the expected results. [SERVICE-WORKERS]
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
										 
							
							
								    // 2. If listener’  
							 
						 
					
						
							
								
									
										
										
										
											2022-08-08 14:12:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( listener . signal  & &  listener . signal - > aborted ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-10 18:51:29 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-16 20:43:24 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
										 
							
							
								    // 3. If listener’  
							 
						 
					
						
							
								
									
										
										
										
											2022-08-08 14:12:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! listener . callback ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-21 18:32:39 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-16 20:43:24 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
										 
							
							
								    // 4. If eventTarget’ ’ ’  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
										 
							
							
								    //    and capture is listener’ ’  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  it  =  m_event_listener_list . find_if ( [ & ] ( auto &  entry )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-08 14:12:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  entry - > type  = =  listener . type 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            & &  & entry - > callback - > callback ( ) . callback  = =  & listener . callback - > callback ( ) . callback 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            & &  entry - > capture  = =  listener . capture ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-16 20:43:24 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( it  = =  m_event_listener_list . end ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-28 13:42:07 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        m_event_listener_list . append ( listener ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-16 20:43:24 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-19 22:02:32 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
										 
							
							
								    // 5. If listener’  
							 
						 
					
						
							
								
									
										
										
										
											2022-08-08 14:12:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( listener . signal )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-28 13:42:07 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        listener . signal - > add_abort_algorithm ( [ strong_event_target  =  JS : : make_handle ( * this ) ,  listener  =  JS : : make_handle ( & listener ) ] ( )  mutable  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-19 22:02:32 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            // 1. Remove an event listener with eventTarget and listener.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-08 14:12:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            strong_event_target - > remove_an_event_listener ( * listener ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-19 22:02:32 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-18 15:22:31 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-16 20:43:24 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								// https://dom.spec.whatwg.org/#dom-eventtarget-removeeventlistener
  
						 
					
						
							
								
									
										
										
										
											2022-08-08 14:12:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								void  EventTarget : : remove_event_listener ( FlyString  const &  type ,  IDLEventListener *  callback ,  Variant < EventListenerOptions ,  bool >  const &  options )  
						 
					
						
							
								
									
										
										
										
											2020-06-21 12:37:34 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2022-02-19 22:02:32 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // 1. Let capture be the result of flattening options.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    bool  capture  =  flatten_event_listener_options ( options ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-16 20:43:24 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
										 
							
							
								    // 2. If this’  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    //    then remove an event listener with this and that event listener.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-08 14:12:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  callbacks_match  =  [ & ] ( DOMEventListener &  entry )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! entry . callback  & &  ! callback ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-20 20:17:57 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  true ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-08 14:12:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! entry . callback  | |  ! callback ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-20 20:17:57 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  false ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-08 14:12:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  & entry . callback - > callback ( ) . callback  = =  & callback - > callback ( ) . callback ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-20 20:17:57 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-16 20:43:24 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  it  =  m_event_listener_list . find_if ( [ & ] ( auto &  entry )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  entry - > type  = =  type 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-08 14:12:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            & &  callbacks_match ( * entry ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-16 20:43:24 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            & &  entry - > capture  = =  capture ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-21 18:32:39 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-16 20:43:24 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( it  ! =  m_event_listener_list . end ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-08 14:12:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        remove_an_event_listener ( * * it ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-21 18:32:39 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-08-08 14:12:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								void  EventTarget : : remove_event_listener_without_options ( FlyString  const &  type ,  IDLEventListener &  callback )  
						 
					
						
							
								
									
										
										
										
											2022-02-19 22:02:32 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2022-08-08 14:12:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    remove_event_listener ( type ,  & callback ,  EventListenerOptions  { } ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-19 22:02:32 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-16 20:43:24 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								// https://dom.spec.whatwg.org/#remove-an-event-listener
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								void  EventTarget : : remove_an_event_listener ( DOMEventListener &  listener )  
						 
					
						
							
								
									
										
										
										
											2020-11-21 18:32:39 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2022-02-16 20:43:24 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
										 
							
							
								    // FIXME: 1. If eventTarget is a ServiceWorkerGlobalScope object and its service worker’  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    //           then report a warning to the console that this might not give the expected results. [SERVICE-WORKERS]
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
										 
							
							
								    // 2. Set listener’ ’  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    listener . removed  =  true ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-28 13:42:07 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    m_event_listener_list . remove_first_matching ( [ & ] ( auto &  entry )  {  return  entry . ptr ( )  = =  & listener ;  } ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-16 20:43:24 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								void  EventTarget : : remove_from_event_listener_list ( DOMEventListener &  listener )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2022-08-28 13:42:07 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    m_event_listener_list . remove_first_matching ( [ & ] ( auto &  entry )  {  return  entry . ptr ( )  = =  & listener ;  } ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-21 12:37:34 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-05-04 22:38:36 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								// https://dom.spec.whatwg.org/#dom-eventtarget-dispatchevent
  
						 
					
						
							
								
									
										
										
										
											2022-08-08 22:29:40 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								ExceptionOr < bool >  EventTarget : : dispatch_event_binding ( Event &  event )  
						 
					
						
							
								
									
										
										
										
											2021-05-04 22:38:36 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2022-04-20 00:00:08 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
										 
							
							
								    // 1. If event’  
							 
						 
					
						
							
								
									
										
										
										
											2022-08-08 22:29:40 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( event . dispatched ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-04 16:56:15 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  DOM : : InvalidStateError : : create ( global_object ( ) ,  " The event is already being dispatched. " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-04 22:38:36 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-08-08 22:29:40 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! event . initialized ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-04 16:56:15 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  DOM : : InvalidStateError : : create ( global_object ( ) ,  " Cannot dispatch an uninitialized event. " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-04 22:38:36 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-04-20 00:00:08 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
										 
							
							
								    // 2. Initialize event’  
							 
						 
					
						
							
								
									
										
										
										
											2022-08-08 22:29:40 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    event . set_is_trusted ( false ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-04 22:38:36 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-04-20 00:00:08 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // 3. Return the result of dispatching event to this.
 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-04 22:38:36 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    return  dispatch_event ( event ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-01-24 16:39:02 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								// https://html.spec.whatwg.org/multipage/webappapis.html#window-reflecting-body-element-event-handler-set
  
						 
					
						
							
								
									
										
										
										
											2022-06-27 19:20:09 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								bool  is_window_reflecting_body_element_event_handler ( FlyString  const &  name )  
						 
					
						
							
								
									
										
										
										
											2022-01-24 16:39:02 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  name . is_one_of ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        HTML : : EventNames : : blur , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        HTML : : EventNames : : error , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        HTML : : EventNames : : focus , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        HTML : : EventNames : : load , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        UIEvents : : EventNames : : resize , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        " scroll " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								// https://html.spec.whatwg.org/multipage/webappapis.html#windoweventhandlers
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								static  bool  is_window_event_handler ( FlyString  const &  name )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  name . is_one_of ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        HTML : : EventNames : : afterprint , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        HTML : : EventNames : : beforeprint , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        HTML : : EventNames : : beforeunload , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        HTML : : EventNames : : hashchange , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        HTML : : EventNames : : languagechange , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        HTML : : EventNames : : message , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        HTML : : EventNames : : messageerror , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        HTML : : EventNames : : offline , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        HTML : : EventNames : : online , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        HTML : : EventNames : : pagehide , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        HTML : : EventNames : : pageshow , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        HTML : : EventNames : : popstate , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        HTML : : EventNames : : rejectionhandled , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        HTML : : EventNames : : storage , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        HTML : : EventNames : : unhandledrejection , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        HTML : : EventNames : : unload ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-09-19 12:49:27 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								// https://html.spec.whatwg.org/multipage/webappapis.html#determining-the-target-of-an-event-handler
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								static  EventTarget *  determine_target_of_event_handler ( EventTarget &  event_target ,  FlyString  const &  name )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // To determine the target of an event handler, given an EventTarget object eventTarget on which the event handler is exposed,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // and an event handler name name, the following steps are taken:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // 1. If eventTarget is not a body element or a frameset element, then return eventTarget.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! is < HTML : : HTMLBodyElement > ( event_target )  & &  ! is < HTML : : HTMLFrameSetElement > ( event_target ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  & event_target ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto &  event_target_element  =  static_cast < HTML : : HTMLElement & > ( event_target ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-01-24 16:39:02 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // 2. If name is not the name of an attribute member of the WindowEventHandlers interface mixin and the Window-reflecting
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    //    body element event handler set does not contain name, then return eventTarget.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! is_window_event_handler ( name )  & &  ! is_window_reflecting_body_element_event_handler ( name ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  & event_target ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-19 12:49:27 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // 3. If eventTarget's node document is not an active document, then return null.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! event_target_element . document ( ) . is_active ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-04-20 00:00:08 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // 4. Return eventTarget's node document's relevant global object.
 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-19 12:49:27 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    return  & event_target_element . document ( ) . window ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-14 18:03:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								// https://html.spec.whatwg.org/multipage/webappapis.html#event-handler-attributes:event-handler-idl-attributes-2
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								Bindings : : CallbackType *  EventTarget : : event_handler_attribute ( FlyString  const &  name )  
						 
					
						
							
								
									
										
										
										
											2021-09-19 01:38:14 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-10-14 18:03:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // 1. Let eventTarget be the result of determining the target of an event handler given this object and name.
 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-19 12:49:27 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  target  =  determine_target_of_event_handler ( * this ,  name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-14 18:03:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // 2. If eventTarget is null, then return null.
 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-19 12:49:27 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! target ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-14 18:03:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-19 12:49:27 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-14 18:03:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // 3. Return the result of getting the current value of the event handler given eventTarget and name.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  target - > get_current_value_of_event_handler ( name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-19 01:38:14 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-14 18:03:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								// https://html.spec.whatwg.org/multipage/webappapis.html#getting-the-current-value-of-the-event-handler
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								Bindings : : CallbackType *  EventTarget : : get_current_value_of_event_handler ( FlyString  const &  name )  
						 
					
						
							
								
									
										
										
										
											2021-09-19 01:38:14 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-10-14 18:03:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // 1. Let handlerMap be eventTarget's event handler map. (NOTE: Not necessary)
 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-19 12:49:27 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-14 18:03:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // 2. Let eventHandler be handlerMap[name].
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  event_handler_iterator  =  m_event_handler_map . find ( name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // Optimization: The spec creates all the event handlers exposed on an object up front and has the initial value of the handler set to null.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    //               If the event handler hasn't been set, null would be returned in step 4.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    //               However, this would be very allocation heavy. For example, each DOM::Element includes GlobalEventHandlers, which defines 60+(!) event handler attributes.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    //               Plus, the vast majority of these allocations would be likely wasted, as I imagine web content will only use a handful of these attributes on certain elements, if any at all.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    //               Thus, we treat the event handler not being in the event handler map as being equivalent to an event handler with an initial null value.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( event_handler_iterator  = =  m_event_handler_map . end ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto &  event_handler  =  event_handler_iterator - > value ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // 3. If eventHandler's value is an internal raw uncompiled handler, then:
 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-08 14:12:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( event_handler - > value . has < String > ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-14 18:03:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        // 1. If eventTarget is an element, then let element be eventTarget, and document be element's node document.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        //    Otherwise, eventTarget is a Window object, let element be null, and document be eventTarget's associated Document.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-28 13:42:07 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        JS : : GCPtr < Element >  element ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        JS : : GCPtr < Document >  document ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-14 18:03:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( is < Element > ( this ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            auto *  element_event_target  =  verify_cast < Element > ( this ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            element  =  element_event_target ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-28 13:42:07 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            document  =  & element_event_target - > document ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-14 18:03:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        }  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-07 23:08:26 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            VERIFY ( is < HTML : : Window > ( this ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            auto *  window_event_target  =  verify_cast < HTML : : Window > ( this ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-28 13:42:07 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            document  =  & window_event_target - > associated_document ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-14 18:03:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        VERIFY ( document ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // 2. If scripting is disabled for document, then return null.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( document - > is_scripting_disabled ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // 3. Let body be the uncompiled script body in eventHandler's value.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-08 14:12:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto &  body  =  event_handler - > value . get < String > ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-14 18:03:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // FIXME: 4. Let location be the location where the script body originated, as given by eventHandler's value.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // 5. If element is not null and element has a form owner, let form owner be that form owner. Otherwise, let form owner be null.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-28 13:42:07 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        JS : : GCPtr < HTML : : HTMLFormElement >  form_owner ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-14 18:03:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( is < HTML : : FormAssociatedElement > ( element . ptr ( ) ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-23 18:55:54 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            auto *  form_associated_element  =  dynamic_cast < HTML : : FormAssociatedElement * > ( element . ptr ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            VERIFY ( form_associated_element ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( form_associated_element - > form ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                form_owner  =  form_associated_element - > form ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-14 18:03:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // 6. Let settings object be the relevant settings object of document.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto &  settings_object  =  document - > relevant_settings_object ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // NOTE: ECMAScriptFunctionObject::create expects a parsed body as input, so we must do the spec's sourceText steps here.
 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-19 01:38:14 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        StringBuilder  builder ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-14 18:03:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // sourceText
 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-07 23:08:26 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( name  = =  HTML : : EventNames : : error  & &  is < HTML : : Window > ( this ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-14 18:03:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            //  -> If name is onerror and eventTarget is a Window object
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            //      The string formed by concatenating "function ", name, "(event, source, lineno, colno, error) {", U+000A LF, body, U+000A LF, and "}".
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            builder . appendff ( " function {}(event, source, lineno, colno, error) {{ \n {} \n }} " ,  name ,  body ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            //  -> Otherwise
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            //      The string formed by concatenating "function ", name, "(event) {", U+000A LF, body, U+000A LF, and "}".
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            builder . appendff ( " function {}(event) {{ \n {} \n }} " ,  name ,  body ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  source_text  =  builder . to_string ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  parser  =  JS : : Parser ( JS : : Lexer ( source_text ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // FIXME: This should only be parsing the `body` instead of `source_text` and therefore use `JS::FunctionBody` instead of `JS::FunctionExpression`.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        //        However, JS::ECMAScriptFunctionObject::create wants parameters and length and JS::FunctionBody does not inherit JS::FunctionNode.
 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-19 01:38:14 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto  program  =  parser . parse_function_node < JS : : FunctionExpression > ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-14 18:03:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // 7. If body is not parsable as FunctionBody or if parsing detects an early error, then follow these substeps:
 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-19 01:38:14 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( parser . has_errors ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-14 18:03:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            // 1. Set eventHandler's value to null.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            //    Note: This does not deactivate the event handler, which additionally removes the event handler's listener (if present).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            m_event_handler_map . remove ( event_handler_iterator ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            // FIXME: 2. Report the error for the appropriate script and with the appropriate position (line number and column number) given by location, using settings object's global object.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            //           If the error is still not handled after this, then the error may be reported to a developer console.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            // 3. Return null.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-19 01:38:14 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-14 18:03:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-08-22 18:31:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto &  vm  =  Bindings : : main_thread_vm ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-17 22:40:17 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // 8. Push settings object's realm execution context onto the JavaScript execution context stack; it is now the running JavaScript execution context.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-22 18:31:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        vm . push_execution_context ( settings_object . realm_execution_context ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-14 18:03:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // 9. Let function be the result of calling OrdinaryFunctionCreate, with arguments:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // functionPrototype
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        //  %Function.prototype% (This is enforced by using JS::ECMAScriptFunctionObject)
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // sourceText was handled above.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // ParameterList
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        //  If name is onerror and eventTarget is a Window object
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        //    Let the function have five arguments, named event, source, lineno, colno, and error.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        //  Otherwise
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        //    Let the function have a single argument called event.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // (This was handled above for us by the parser using sourceText)
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // body
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        //  The result of parsing body above. (This is given by program->body())
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // thisMode
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        //  non-lexical-this (For JS::ECMAScriptFunctionObject, this means passing is_arrow_function as false)
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        constexpr  bool  is_arrow_function  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // scope
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        //  1. Let realm be settings object's Realm.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto &  realm  =  settings_object . realm ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        //  2. Let scope be realm.[[GlobalEnv]].
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        JS : : Environment *  scope  =  & realm . global_environment ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // 3. If eventHandler is an element's event handler, then set scope to NewObjectEnvironment(document, true, scope).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        //    (Otherwise, eventHandler is a Window object's event handler.)
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( is < Element > ( this ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-22 18:31:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            auto *  wrapped_document  =  Bindings : : wrap ( realm ,  * document ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-14 18:03:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            scope  =  JS : : new_object_environment ( * wrapped_document ,  true ,  scope ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        //  4. If form owner is not null, then set scope to NewObjectEnvironment(form owner, true, scope).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( form_owner )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-22 18:31:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            auto *  wrapped_form_owner  =  Bindings : : wrap ( realm ,  * form_owner ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-14 18:03:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            scope  =  JS : : new_object_environment ( * wrapped_form_owner ,  true ,  scope ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        //  5. If element is not null, then set scope to NewObjectEnvironment(element, true, scope).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( element )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-22 18:31:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            auto *  wrapped_element  =  Bindings : : wrap ( realm ,  * element ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-14 18:03:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            scope  =  JS : : new_object_environment ( * wrapped_element ,  true ,  scope ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        //  6. Return scope. (NOTE: Not necessary)
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-08-16 00:20:49 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto *  function  =  JS : : ECMAScriptFunctionObject : : create ( realm ,  name ,  builder . to_string ( ) ,  program - > body ( ) ,  program - > parameters ( ) ,  program - > function_length ( ) ,  scope ,  nullptr ,  JS : : FunctionKind : : Normal ,  program - > is_strict_mode ( ) ,  program - > might_need_arguments_object ( ) ,  is_arrow_function ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-19 01:38:14 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        VERIFY ( function ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-14 18:03:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // 10. Remove settings object's realm execution context from the JavaScript execution context stack.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-22 18:31:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        VERIFY ( vm . execution_context_stack ( ) . last ( )  = =  & settings_object . realm_execution_context ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        vm . pop_execution_context ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-14 18:03:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // 11. Set function.[[ScriptOrModule]] to null.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        function - > set_script_or_module ( { } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // 12. Set eventHandler's value to the result of creating a Web IDL EventHandler callback function object whose object reference is function and whose callback context is settings object.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-08 14:12:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        event_handler - > value  =  realm . heap ( ) . allocate_without_realm < Bindings : : CallbackType > ( * function ,  settings_object ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-14 18:03:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // 4. Return eventHandler's value.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-08 14:12:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    VERIFY ( event_handler - > value . has < Bindings : : CallbackType * > ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  * event_handler - > value . get_pointer < Bindings : : CallbackType * > ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-14 18:03:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								// https://html.spec.whatwg.org/multipage/webappapis.html#event-handler-attributes:event-handler-idl-attributes-3
  
						 
					
						
							
								
									
										
										
										
											2022-08-08 14:12:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								void  EventTarget : : set_event_handler_attribute ( FlyString  const &  name ,  Bindings : : CallbackType *  value )  
						 
					
						
							
								
									
										
										
										
											2021-10-14 18:03:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // 1. Let eventTarget be the result of determining the target of an event handler given this object and name.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  event_target  =  determine_target_of_event_handler ( * this ,  name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // 2. If eventTarget is null, then return.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! event_target ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // 3. If the given value is null, then deactivate an event handler given eventTarget and name.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-08 14:12:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! value )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-14 18:03:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        event_target - > deactivate_event_handler ( name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // 4. Otherwise:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    //  1. Let handlerMap be eventTarget's event handler map.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto &  handler_map  =  event_target - > m_event_handler_map ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    //  2. Let eventHandler be handlerMap[name].
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  event_handler_iterator  =  handler_map . find ( name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    //  3. Set eventHandler's value to the given value.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( event_handler_iterator  = =  handler_map . end ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // NOTE: See the optimization comment in get_current_value_of_event_handler about why this is done.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-08 14:12:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto *  new_event_handler  =  Bindings : : main_thread_internal_window_object ( ) . heap ( ) . allocate_without_realm < HTML : : EventHandler > ( * value ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-14 18:03:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        //  4. Activate an event handler given eventTarget and name.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // Optimization: We pass in the event handler here instead of having activate_event_handler do another hash map lookup just to get the same object.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        //               This handles a new event handler while the other path handles an existing event handler. As such, both paths must have their own
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        //               unique call to activate_event_handler.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-08 14:12:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        event_target - > activate_event_handler ( name ,  * new_event_handler ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-14 18:03:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-08-28 13:42:07 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        handler_map . set ( name ,  new_event_handler ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-14 18:03:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-19 01:38:14 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-14 18:03:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto &  event_handler  =  event_handler_iterator - > value ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-08-08 14:12:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    event_handler - > value  =  value ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-14 18:03:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    //  4. Activate an event handler given eventTarget and name.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    //  NOTE: See the optimization comment above.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-08 14:12:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    event_target - > activate_event_handler ( name ,  * event_handler ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-14 18:03:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								// https://html.spec.whatwg.org/multipage/webappapis.html#activate-an-event-handler
  
						 
					
						
							
								
									
										
										
										
											2022-08-16 00:20:49 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								void  EventTarget : : activate_event_handler ( FlyString  const &  name ,  HTML : : EventHandler &  event_handler )  
						 
					
						
							
								
									
										
										
										
											2021-10-14 18:03:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // 1. Let handlerMap be eventTarget's event handler map.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // 2. Let eventHandler be handlerMap[name].
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // NOTE: These are achieved by using the passed in event handler.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // 3. If eventHandler's listener is not null, then return.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( event_handler . listener ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-08-28 13:42:07 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    JS : : Realm &  realm  =  shape ( ) . realm ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-23 17:44:31 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-14 18:03:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // 4. Let callback be the result of creating a Web IDL EventListener instance representing a reference to a function of one argument that executes the steps of the event handler processing algorithm, given eventTarget, name, and its argument.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    //    The EventListener's callback context can be arbitrary; it does not impact the steps of the event handler processing algorithm. [DOM]
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // NOTE: The callback must keep `this` alive. For example:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    //          document.body.onunload = () => { console.log("onunload called!"); }
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    //          document.body.remove();
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    //          location.reload();
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    //       The body element is no longer in the DOM and there is no variable holding onto it. However, the onunload handler is still called, meaning the callback keeps the body element alive.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-23 17:44:31 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  callback_function  =  JS : : NativeFunction : : create ( 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-28 13:42:07 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        realm ,  [ event_target  =  JS : : make_handle ( * this ) ,  name ] ( JS : : VM &  vm )  mutable  - >  JS : : ThrowCompletionOr < JS : : Value >  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-23 17:44:31 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            // The event dispatcher should only call this with one argument.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            VERIFY ( vm . argument_count ( )  = =  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-08-28 13:42:07 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            // The argument must be an object and it must be an Event.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-23 17:44:31 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            auto  event_wrapper_argument  =  vm . argument ( 0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            VERIFY ( event_wrapper_argument . is_object ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-28 13:42:07 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            auto &  event_wrapper  =  verify_cast < DOM : : Event > ( event_wrapper_argument . as_object ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-23 17:44:31 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            auto &  event  =  event_wrapper . impl ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            TRY ( event_target - > process_event_handler_for_event ( name ,  event ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  JS : : js_undefined ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } , 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-28 13:42:07 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        0 ,  " " ,  & realm ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-14 18:03:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // NOTE: As per the spec, the callback context is arbitrary.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-28 13:42:07 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto *  callback  =  realm . heap ( ) . allocate_without_realm < Bindings : : CallbackType > ( * callback_function ,  verify_cast < HTML : : EnvironmentSettingsObject > ( * realm . host_defined ( ) ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-14 18:03:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // 5. Let listener be a new event listener whose type is the event handler event type corresponding to eventHandler and callback is callback.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-28 13:42:07 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto *  listener  =  realm . heap ( ) . allocate_without_realm < DOMEventListener > ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-16 20:43:24 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    listener - > type  =  name ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-28 13:42:07 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    listener - > callback  =  IDLEventListener : : create ( realm ,  * callback ) . ptr ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-14 18:03:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // 6. Add an event listener with eventTarget and listener.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-08 14:12:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    add_an_event_listener ( * listener ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-14 18:03:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // 7. Set eventHandler's listener to listener.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    event_handler . listener  =  listener ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								void  EventTarget : : deactivate_event_handler ( FlyString  const &  name )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // 1. Let handlerMap be eventTarget's event handler map. (NOTE: Not necessary)
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // 2. Let eventHandler be handlerMap[name].
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  event_handler_iterator  =  m_event_handler_map . find ( name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // NOTE: See the optimization comment in get_current_value_of_event_handler about why this is done.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( event_handler_iterator  = =  m_event_handler_map . end ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto &  event_handler  =  event_handler_iterator - > value ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // 4. Let listener be eventHandler's listener. (NOTE: Not necessary)
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // 5. If listener is not null, then remove an event listener with eventTarget and listener.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-08 14:12:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( event_handler - > listener )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        remove_an_event_listener ( * event_handler - > listener ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-14 18:03:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // 6. Set eventHandler's listener to null.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-08 14:12:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    event_handler - > listener  =  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-14 18:03:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // 3. Set eventHandler's value to null.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // NOTE: This is done out of order since our equivalent of setting value to null is removing the event handler from the map.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    //       Given that event_handler is a reference to an entry, this would invalidate event_handler if we did it in order.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    m_event_handler_map . remove ( event_handler_iterator ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								// https://html.spec.whatwg.org/multipage/webappapis.html#the-event-handler-processing-algorithm
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								JS : : ThrowCompletionOr < void >  EventTarget : : process_event_handler_for_event ( FlyString  const &  name ,  Event &  event )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // 1. Let callback be the result of getting the current value of the event handler given eventTarget and name.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto *  callback  =  get_current_value_of_event_handler ( name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // 2. If callback is null, then return.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! callback ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // 3. Let special error event handling be true if event is an ErrorEvent object, event's type is error, and event's currentTarget implements the WindowOrWorkerGlobalScope mixin.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    //    Otherwise, let special error event handling be false.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // FIXME: This doesn't check for WorkerGlobalScape as we don't currently have it.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-07 23:08:26 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    bool  special_error_event_handling  =  is < HTML : : ErrorEvent > ( event )  & &  event . type ( )  = =  HTML : : EventNames : : error  & &  is < HTML : : Window > ( event . current_target ( ) . ptr ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-14 18:03:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // 4. Process the Event object event as follows:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    JS : : Completion  return_value_or_error ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // Needed for wrapping.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-08 14:12:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto *  callback_object  =  & callback - > callback ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-22 18:31:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto &  realm  =  callback_object - > shape ( ) . realm ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-14 18:03:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( special_error_event_handling )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // -> If special error event handling is true
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        //    Invoke callback with five arguments, the first one having the value of event's message attribute, the second having the value of event's filename attribute, the third having the value of event's lineno attribute,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        //    the fourth having the value of event's colno attribute, the fifth having the value of event's error attribute, and with the callback this value set to event's currentTarget.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        //    Let return value be the callback's return value. [WEBIDL]
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto &  error_event  =  verify_cast < HTML : : ErrorEvent > ( event ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto *  wrapped_message  =  JS : : js_string ( callback_object - > heap ( ) ,  error_event . message ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto *  wrapped_filename  =  JS : : js_string ( callback_object - > heap ( ) ,  error_event . filename ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  wrapped_lineno  =  JS : : Value ( error_event . lineno ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  wrapped_colno  =  JS : : Value ( error_event . colno ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // NOTE: error_event.error() is a JS::Value, so it does not require wrapping.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // NOTE: current_target is always non-null here, as the event dispatcher takes care to make sure it's non-null (and uses it as the this value for the callback!)
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // FIXME: This is rewrapping the this value of the callback defined in activate_event_handler. While I don't think this is observable as the event dispatcher
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        //        calls directly into the callback without considering things such as proxies, it is a waste. However, if it observable, then we must reuse the this_value that was given to the callback.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-22 18:31:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto *  this_value  =  Bindings : : wrap ( realm ,  * error_event . current_target ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-14 18:03:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return_value_or_error  =  Bindings : : IDL : : invoke_callback ( * callback ,  this_value ,  wrapped_message ,  wrapped_filename ,  wrapped_lineno ,  wrapped_colno ,  error_event . error ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // -> Otherwise
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // Invoke callback with one argument, the value of which is the Event object event, with the callback this value set to event's currentTarget. Let return value be the callback's return value. [WEBIDL]
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // FIXME: This has the same rewrapping issue as this_value.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-22 18:31:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto *  wrapped_event  =  Bindings : : wrap ( realm ,  event ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-14 18:03:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // FIXME: The comments about this in the special_error_event_handling path also apply here.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-22 18:31:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto *  this_value  =  Bindings : : wrap ( realm ,  * event . current_target ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-14 18:03:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return_value_or_error  =  Bindings : : IDL : : invoke_callback ( * callback ,  this_value ,  wrapped_event ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // If an exception gets thrown by the callback, end these steps and allow the exception to propagate. (It will propagate to the DOM event dispatch logic, which will then report the exception.)
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( return_value_or_error . is_error ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  return_value_or_error . release_error ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // FIXME: Ideally, invoke_callback would convert JS::Value to the appropriate return type for us as per the spec, but it doesn't currently.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  return_value  =  * return_value_or_error . value ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // FIXME: If event is a BeforeUnloadEvent object and event's type is beforeunload
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    //          If return value is not null, then: (NOTE: When implementing, if we still return a JS::Value from invoke_callback, use is_nullish instead of is_null, as "null" refers to IDL null, which is JS null or undefined)
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    //              1. Set event's canceled flag.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    //              2. If event's returnValue attribute's value is the empty string, then set event's returnValue attribute's value to return value.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( special_error_event_handling )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // -> If special error event handling is true
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        //      If return value is true, then set event's canceled flag.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // NOTE: the return type of EventHandler is `any`, so no coercion happens, meaning we have to check if it's a boolean first.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( return_value . is_boolean ( )  & &  return_value . as_bool ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            event . set_cancelled ( true ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // -> Otherwise
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        //      If return value is false, then set event's canceled flag.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // NOTE: the return type of EventHandler is `any`, so no coercion happens, meaning we have to check if it's a boolean first.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( return_value . is_boolean ( )  & &  ! return_value . as_bool ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            event . set_cancelled ( true ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								// https://html.spec.whatwg.org/multipage/webappapis.html#event-handler-attributes:concept-element-attributes-change-ext
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								void  EventTarget : : element_event_handler_attribute_changed ( FlyString  const &  local_name ,  String  const &  value )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // NOTE: Step 1 of this algorithm was handled in HTMLElement::parse_attribute.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // 2. Let eventTarget be the result of determining the target of an event handler given element and localName.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // NOTE: element is `this`.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto *  event_target  =  determine_target_of_event_handler ( * this ,  local_name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // 3. If eventTarget is null, then return.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! event_target ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // 4. If value is null, then deactivate an event handler given eventTarget and localName.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( value . is_null ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        event_target - > deactivate_event_handler ( local_name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // 5. Otherwise:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    //  FIXME: 1. If the Should element's inline behavior be blocked by Content Security Policy? algorithm returns "Blocked" when executed upon element, "script attribute", and value, then return. [CSP]
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    //  2. Let handlerMap be eventTarget's event handler map.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto &  handler_map  =  event_target - > m_event_handler_map ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    //  3. Let eventHandler be handlerMap[localName].
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  event_handler_iterator  =  handler_map . find ( local_name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    //  FIXME: 4. Let location be the script location that triggered the execution of these steps.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    //  FIXME: 5. Set eventHandler's value to the internal raw uncompiled handler value/location.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    //            (This currently sets the value to the uncompiled source code instead of the named struct)
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // NOTE: See the optimization comments in set_event_handler_attribute.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( event_handler_iterator  = =  handler_map . end ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-08 14:12:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto *  new_event_handler  =  Bindings : : main_thread_internal_window_object ( ) . heap ( ) . allocate_without_realm < HTML : : EventHandler > ( value ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-14 18:03:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        //  6. Activate an event handler given eventTarget and name.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-08 14:12:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        event_target - > activate_event_handler ( local_name ,  * new_event_handler ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-14 18:03:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-08-28 13:42:07 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        handler_map . set ( local_name ,  new_event_handler ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-14 18:03:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto &  event_handler  =  event_handler_iterator - > value ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    //  6. Activate an event handler given eventTarget and name.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-08 14:12:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    event_handler - > value  =  value ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    event_target - > activate_event_handler ( local_name ,  * event_handler ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-19 01:38:14 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2021-09-25 23:11:51 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-08-08 22:29:40 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								bool  EventTarget : : dispatch_event ( Event &  event )  
						 
					
						
							
								
									
										
										
										
											2021-09-25 23:11:51 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2022-08-08 22:29:40 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    return  EventDispatcher : : dispatch ( * this ,  event ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-25 23:11:51 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-18 15:22:31 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}