2020-06-07 14:40:38 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								/*
  
						 
					
						
							
								
									
										
										
										
											2024-10-04 13:19:50 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								 *  Copyright  ( c )  2020 - 2021 ,  Andreas  Kling  < andreas @ ladybird . org > 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-18 13:13:58 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								 *  Copyright  ( c )  2021 ,  Max  Wipfli  < mail @ maxwipfli . ch > 
							 
						 
					
						
							
								
									
										
										
										
											2024-11-09 05:48:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								 *  Copyright  ( c )  2024 ,  Aliaksandr  Kalenik  < kalenik . aliaksandr @ gmail . com > 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-07 14:40:38 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								 * 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-22 01:24:48 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								 *  SPDX - License - Identifier :  BSD - 2 - Clause 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-07 14:40:38 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-10-08 17:15:55 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibUnicode/CharacterTypes.h> 
  
						 
					
						
							
								
									
										
										
										
											2024-08-27 08:19:03 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibUnicode/Segmenter.h> 
  
						 
					
						
							
								
									
										
										
										
											2020-08-02 12:10:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/DOM/Text.h> 
  
						 
					
						
							
								
									
										
										
										
											2024-06-21 22:53:05 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/HTML/CloseWatcherManager.h> 
  
						 
					
						
							
								
									
										
										
										
											2022-11-05 14:34:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/HTML/Focus.h> 
  
						 
					
						
							
								
									
										
										
										
											2020-07-28 17:21:23 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/HTML/HTMLAnchorElement.h> 
  
						 
					
						
							
								
									
										
										
										
											2024-01-31 13:26:01 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/HTML/HTMLFormElement.h> 
  
						 
					
						
							
								
									
										
										
										
											2020-07-28 17:21:23 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/HTML/HTMLIFrameElement.h> 
  
						 
					
						
							
								
									
										
										
										
											2020-10-02 19:01:51 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/HTML/HTMLImageElement.h> 
  
						 
					
						
							
								
									
										
										
										
											2023-06-16 10:51:38 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/HTML/HTMLMediaElement.h> 
  
						 
					
						
							
								
									
										
										
										
											2023-05-15 09:42:56 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/HTML/HTMLVideoElement.h> 
  
						 
					
						
							
								
									
										
										
										
											2024-11-20 21:31:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/Layout/Label.h> 
  
						 
					
						
							
								
									
										
										
										
											2023-02-25 11:04:29 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/Layout/Viewport.h> 
  
						 
					
						
							
								
									
										
										
										
											2024-08-17 13:29:55 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/Page/DragAndDropEventHandler.h> 
  
						 
					
						
							
								
									
										
										
										
											2020-07-28 19:27:41 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/Page/EventHandler.h> 
  
						 
					
						
							
								
									
										
										
										
											2021-08-24 16:28:08 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/Page/Page.h> 
  
						 
					
						
							
								
									
										
										
										
											2022-03-10 23:13:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/Painting/PaintableBox.h> 
  
						 
					
						
							
								
									
										
										
										
											2024-03-18 10:25:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/Painting/TextPaintable.h> 
  
						 
					
						
							
								
									
										
											 
										
											
												LibWeb: Separate text control input events handling from contenteditable
This input event handling change is intended to address the following
design issues:
- Having `DOM::Position` is unnecessary complexity when `Selection`
  exists because caret position could be described by the selection
  object with a collapsed state. Before this change, we had to
  synchronize those whenever one of them was modified, and there were
  already bugs caused by that, i.e., caret position was not changed when
  selection offset was modified from the JS side.
- Selection API exposes selection offset within `<textarea>` and
  `<input>`, which is not supposed to happen. These objects should
  manage their selection state by themselves and have selection offset
  even when they are not displayed.
- `EventHandler` looks only at `DOM::Text` owned by `DOM::Position`
  while doing text manipulations. It works fine for `<input>` and
  `<textarea>`, but `contenteditable` needs to consider all text
  descendant text nodes; i.e., if the cursor is moved outside of
  `DOM::Text`, we need to look for an adjacent text node to move the
  cursor there.
With this change, `EventHandler` no longer does direct manipulations on
caret position or text content, but instead delegates them to the active
`InputEventsTarget`, which could be either
`FormAssociatedTextControlElement` (for `<input>` and `<textarea>`) or
`EditingHostManager` (for `contenteditable`). The `Selection` object is
used to manage both selection and caret position for `contenteditable`,
and text control elements manage their own selection state that is not
exposed by Selection API.
This change improves text editing on Discord, as now we don't have to
refocus the `contenteditable` element after character input. The problem
was that selection manipulations from the JS side were not propagated
to `DOM::Position`.
I expect this change to make future correctness improvements for
`contenteditable` (and `designMode`) easier, as now it's decoupled from
`<input>` and `<textarea>` and separated from `EventHandler`, which is
quite a busy file.
											 
										 
										
											2024-10-23 21:26:58 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/Selection/Selection.h> 
  
						 
					
						
							
								
									
										
										
										
											2020-11-21 19:15:57 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/UIEvents/EventNames.h> 
  
						 
					
						
							
								
									
										
										
										
											2024-02-24 06:08:26 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/UIEvents/InputEvent.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/UIEvents/InputTypes.h> 
  
						 
					
						
							
								
									
										
										
										
											2021-09-27 23:22:21 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/UIEvents/KeyboardEvent.h> 
  
						 
					
						
							
								
									
										
										
										
											2024-06-02 19:00:42 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/UIEvents/MouseButton.h> 
  
						 
					
						
							
								
									
										
										
										
											2020-07-28 17:21:23 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/UIEvents/MouseEvent.h> 
  
						 
					
						
							
								
									
										
										
										
											2024-11-21 21:35:49 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/UIEvents/PointerEvent.h> 
  
						 
					
						
							
								
									
										
										
										
											2022-10-17 20:54:01 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/UIEvents/WheelEvent.h> 
  
						 
					
						
							
								
									
										
										
										
											2020-06-07 14:40:38 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								namespace  Web  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-10-22 23:09:27 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# define FIRE(expression)                                                          \ 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( auto  event_result  =  ( expression ) ;  event_result  = =  EventResult : : Cancelled )  \
							 
						 
					
						
							
								
									
										
										
										
											2024-02-24 06:08:26 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  event_result ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-11-15 04:01:23 +13:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								static  GC : : Ptr < DOM : : Node >  dom_node_for_event_dispatch ( Painting : : Paintable &  paintable )  
						 
					
						
							
								
									
										
										
										
											2022-10-23 17:53:02 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( auto  node  =  paintable . dom_node ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  node ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-02-12 14:58:10 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto *  layout_parent  =  paintable . layout_node ( ) . parent ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    while  ( layout_parent )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( auto *  node  =  layout_parent - > dom_node ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  node ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        layout_parent  =  layout_parent - > parent ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-23 17:53:02 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-11-20 21:31:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								static  DOM : : Node *  input_control_associated_with_ancestor_label_element ( Painting : : Paintable &  paintable )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( is < Layout : : Label > ( paintable . layout_node ( ) ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2025-01-21 09:12:05 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto  const &  label  =  as < Layout : : Label > ( paintable . layout_node ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-11-20 21:31:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  label . dom_node ( ) . control ( ) . ptr ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( auto  const *  label  =  paintable . layout_node ( ) . first_ancestor_of_type < Layout : : Label > ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  label - > dom_node ( ) . control ( ) . ptr ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-11-15 04:01:23 +13:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								static  bool  parent_element_for_event_dispatch ( Painting : : Paintable &  paintable ,  GC : : Ptr < DOM : : Node > &  node ,  Layout : : Node * &  layout_node )  
						 
					
						
							
								
									
										
										
										
											2022-10-24 03:24:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2024-07-12 11:06:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto *  current_ancestor_node  =  node . ptr ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    do  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( is < HTML : : FormAssociatedElement > ( current_ancestor_node )  & &  ! dynamic_cast < HTML : : FormAssociatedElement * > ( current_ancestor_node ) - > enabled ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    }  while  ( ( current_ancestor_node  =  current_ancestor_node - > parent ( ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-10-24 03:24:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    layout_node  =  & paintable . layout_node ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    while  ( layout_node  & &  node  & &  ! node - > is_element ( )  & &  layout_node - > parent ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        layout_node  =  layout_node - > parent ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-06 21:45:30 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( layout_node - > is_anonymous ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            continue ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-24 03:24:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        node  =  layout_node - > dom_node ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  node  & &  layout_node ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2025-02-20 12:17:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								static  Gfx : : Cursor  resolve_cursor ( Layout : : NodeWithStyle  const &  layout_node ,  Vector < CSS : : CursorData >  const &  cursor_data ,  Gfx : : StandardCursor  auto_cursor )  
						 
					
						
							
								
									
										
										
										
											2021-02-21 20:15:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2025-02-20 12:17:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    for  ( auto  const &  cursor  :  cursor_data )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  result  =  cursor . visit ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            [ auto_cursor ] ( CSS : : Cursor  css_cursor )  - >  Optional < Gfx : : Cursor >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                switch  ( css_cursor )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                case  CSS : : Cursor : : Crosshair : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                case  CSS : : Cursor : : Cell : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    return  Gfx : : StandardCursor : : Crosshair ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                case  CSS : : Cursor : : Grab : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                case  CSS : : Cursor : : Grabbing : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    return  Gfx : : StandardCursor : : Drag ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                case  CSS : : Cursor : : Pointer : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    return  Gfx : : StandardCursor : : Hand ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                case  CSS : : Cursor : : Help : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    return  Gfx : : StandardCursor : : Help ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                case  CSS : : Cursor : : None : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    return  Gfx : : StandardCursor : : Hidden ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                case  CSS : : Cursor : : NotAllowed : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    return  Gfx : : StandardCursor : : Disallowed ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                case  CSS : : Cursor : : Text : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                case  CSS : : Cursor : : VerticalText : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    return  Gfx : : StandardCursor : : IBeam ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                case  CSS : : Cursor : : Move : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                case  CSS : : Cursor : : AllScroll : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    return  Gfx : : StandardCursor : : Move ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                case  CSS : : Cursor : : Progress : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                case  CSS : : Cursor : : Wait : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    return  Gfx : : StandardCursor : : Wait ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                case  CSS : : Cursor : : ColResize : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    return  Gfx : : StandardCursor : : ResizeColumn ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                case  CSS : : Cursor : : EResize : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                case  CSS : : Cursor : : WResize : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                case  CSS : : Cursor : : EwResize : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    return  Gfx : : StandardCursor : : ResizeHorizontal ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                case  CSS : : Cursor : : RowResize : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    return  Gfx : : StandardCursor : : ResizeRow ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                case  CSS : : Cursor : : NResize : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                case  CSS : : Cursor : : SResize : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                case  CSS : : Cursor : : NsResize : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    return  Gfx : : StandardCursor : : ResizeVertical ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                case  CSS : : Cursor : : NeResize : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                case  CSS : : Cursor : : SwResize : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                case  CSS : : Cursor : : NeswResize : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    return  Gfx : : StandardCursor : : ResizeDiagonalBLTR ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                case  CSS : : Cursor : : NwResize : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                case  CSS : : Cursor : : SeResize : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                case  CSS : : Cursor : : NwseResize : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    return  Gfx : : StandardCursor : : ResizeDiagonalTLBR ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                case  CSS : : Cursor : : ZoomIn : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                case  CSS : : Cursor : : ZoomOut : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    return  Gfx : : StandardCursor : : Zoom ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                case  CSS : : Cursor : : Auto : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    return  auto_cursor ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                case  CSS : : Cursor : : ContextMenu : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                case  CSS : : Cursor : : Alias : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                case  CSS : : Cursor : : Copy : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                case  CSS : : Cursor : : NoDrop : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    // FIXME: No corresponding GFX Standard Cursor, fallthrough to None
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                case  CSS : : Cursor : : Default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    return  Gfx : : StandardCursor : : None ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            [ & layout_node ] ( NonnullRefPtr < CSS : : CursorStyleValue >  const &  cursor_style_value )  - >  Optional < Gfx : : Cursor >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                if  ( auto  image_cursor  =  cursor_style_value - > make_image_cursor ( layout_node ) ;  image_cursor . has_value ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    return  image_cursor . release_value ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( result . has_value ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  result . release_value ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-02-21 20:15:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2025-02-20 12:17:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // We should never get here
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  Gfx : : StandardCursor : : None ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-02-21 20:15:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-11-19 22:26:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								// https://drafts.csswg.org/cssom-view/#dom-mouseevent-offsetx
  
						 
					
						
							
								
									
										
										
										
											2024-12-20 15:52:47 +11:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								static  CSSPixelPoint  compute_mouse_event_offset ( CSSPixelPoint  position ,  Painting : : Paintable  const &  paintable )  
						 
					
						
							
								
									
										
										
										
											2020-06-07 14:40:38 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2024-11-19 22:26:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
										 
							
							
								    // If the event’  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // FIXME: Is this guaranteed to be dispatched?
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // return the x-coordinate of the position where the event occurred,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    Gfx : : Point < float >  precision_offset  =  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        position . x ( ) . to_double ( ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        position . y ( ) . to_double ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // ignoring the transforms that apply to the element and its ancestors,
 
							 
						 
					
						
							
								
									
										
										
										
											2024-12-20 15:52:47 +11:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( paintable . layout_node ( ) . has_css_transform ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  const &  paintable_box  =  static_cast < Painting : : PaintableBox  const & > ( paintable ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  const  affine_transform  =  Gfx : : extract_2d_affine_transform ( paintable_box . transform ( ) . inverse ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-11-19 22:26:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-12-20 15:52:47 +11:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto  const &  origin  =  paintable_box . transform_origin ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-11-19 22:26:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        Gfx : : Point < float >  const  precision_origin  =  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            origin . x ( ) . to_double ( ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            origin . y ( ) . to_double ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        precision_offset . translate_by ( - precision_origin ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        precision_offset . transform_by ( affine_transform ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        precision_offset . translate_by ( precision_origin ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // relative to the origin of the padding edge of the target node
 
							 
						 
					
						
							
								
									
										
										
										
											2024-12-20 15:52:47 +11:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  const  top_left_of_layout_node  =  paintable . box_type_agnostic_position ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-11-19 22:26:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    CSSPixelPoint  offset  =  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        CSSPixels ( precision_offset . x ( ) ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        CSSPixels ( precision_offset . y ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-07 14:40:38 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-11-19 22:26:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    offset  - =  top_left_of_layout_node ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // and terminate these steps.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  offset ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-07 14:40:38 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2025-01-08 01:51:29 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								// https://drafts.csswg.org/css-ui/#propdef-user-select
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								static  void  set_user_selection ( GC : : Ptr < DOM : : Node >  anchor_node ,  unsigned  anchor_offset ,  GC : : Ptr < DOM : : Node >  focus_node ,  unsigned  focus_offset ,  Selection : : Selection *  selection ,  CSS : : UserSelect  user_select )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // https://drafts.csswg.org/css-ui/#valdef-user-select-contain
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // NOTE: This is clamping the focus node to any node with user-select: contain that stands between it and the anchor node.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( focus_node  ! =  anchor_node )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // UAs must not allow a selection which is started in this element to be extended outside of this element.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  potential_contain_node  =  anchor_node ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // NOTE: The way we do this is searching up the tree from the anchor, to find 'this element', i.e. its nearest contain ancestor.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        //       We stop the search early when we reach an element that contains both the anchor and the focus node, as this means they
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        //       are inside the same contain element, or not in a contain element at all.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        //       This takes care of the "selection trying to escape from a contain" case.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        while  ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            ( ! potential_contain_node - > is_element ( )  | |  potential_contain_node - > layout_node ( ) - > user_select_used_value ( )  ! =  CSS : : UserSelect : : Contain )  & &  potential_contain_node - > parent ( )  & &  ! potential_contain_node - > is_inclusive_ancestor_of ( * focus_node ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            potential_contain_node  =  potential_contain_node - > parent ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            potential_contain_node - > layout_node ( ) - > user_select_used_value ( )  = =  CSS : : UserSelect : : Contain  & &  ! potential_contain_node - > is_inclusive_ancestor_of ( * focus_node ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( focus_node - > is_before ( * potential_contain_node ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                focus_offset  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                focus_offset  =  potential_contain_node - > length ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            focus_node  =  potential_contain_node ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            // NOTE: Prevents this from being handled again further down
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            user_select  =  CSS : : UserSelect : : Contain ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            // A selection started outside of this element must not end in this element. If the user attempts to create such a
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            // selection, the UA must instead end the selection range at the element boundary.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            // NOTE: This branch takes care of the "selection trying to intrude into a contain" case.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            //       This is done by searching up the tree from the focus node, to see if there is a
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            //       contain element between it and the common ancestor that also includes the anchor.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            //       We stop once reaching target_node, which is the common ancestor identified in step 1.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            //       If target_node wasn't a common ancestor, we would not be here.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            auto  target_node  =  potential_contain_node ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            potential_contain_node  =  focus_node ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            while  ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                ( ! potential_contain_node - > is_element ( )  | |  potential_contain_node - > layout_node ( ) - > user_select_used_value ( )  ! =  CSS : : UserSelect : : Contain )  & &  potential_contain_node - > parent ( )  & &  potential_contain_node  ! =  target_node )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                potential_contain_node  =  potential_contain_node - > parent ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                potential_contain_node - > layout_node ( ) - > user_select_used_value ( )  = =  CSS : : UserSelect : : Contain  & &  ! potential_contain_node - > is_inclusive_ancestor_of ( * anchor_node ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                if  ( potential_contain_node - > is_before ( * anchor_node ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    focus_node  =  potential_contain_node - > next_in_pre_order ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    while  ( potential_contain_node - > is_inclusive_ancestor_of ( * focus_node ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                        focus_node  =  focus_node - > next_in_pre_order ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    focus_offset  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    focus_node  =  potential_contain_node - > previous_in_pre_order ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    while  ( potential_contain_node - > is_inclusive_ancestor_of ( * focus_node ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                        focus_node  =  focus_node - > previous_in_pre_order ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    focus_offset  =  focus_node - > length ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                // NOTE: Prevents this from being handled again further down
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                user_select  =  CSS : : UserSelect : : Contain ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    switch  ( user_select )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    case  CSS : : UserSelect : : None : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // https://drafts.csswg.org/css-ui/#valdef-user-select-none
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // The UA must not allow selections to be started in this element.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( anchor_node  = =  focus_node )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // A selection started outside of this element must not end in this element. If the user attempts to create such a
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // selection, the UA must instead end the selection range at the element boundary.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        while  ( focus_node - > parent ( )  & &  focus_node - > parent ( ) - > layout_node ( ) - > user_select_used_value ( )  = =  CSS : : UserSelect : : None )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            focus_node  =  focus_node - > parent ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( focus_node - > is_before ( * anchor_node ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            auto  none_element  =  focus_node ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            do  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                focus_node  =  focus_node - > next_in_pre_order ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            }  while  ( none_element - > is_inclusive_ancestor_of ( * focus_node ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            focus_offset  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            focus_node  =  focus_node - > previous_in_pre_order ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            focus_offset  =  focus_node - > length ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    case  CSS : : UserSelect : : All : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // https://drafts.csswg.org/css-ui/#valdef-user-select-all
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // The content of the element must be selected atomically: If a selection would contain part of the element,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // then the selection must contain the entire element including all its descendants. If the element is selected
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // and the used value of 'user-select' on its parent is 'all', then the parent must be included in the selection,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // recursively.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        while  ( focus_node - > parent ( )  & &  focus_node - > parent ( ) - > layout_node ( ) - > user_select_used_value ( )  = =  CSS : : UserSelect : : All )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( anchor_node  = =  focus_node )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                anchor_node  =  focus_node - > parent ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            focus_node  =  focus_node - > parent ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( focus_node  = =  anchor_node )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( anchor_offset  >  focus_offset )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                anchor_offset  =  focus_node - > length ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                focus_offset  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                anchor_offset  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                focus_offset  =  focus_node - > length ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        }  else  if  ( focus_node - > is_before ( * anchor_node ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            focus_offset  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            focus_offset  =  focus_node - > length ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    case  CSS : : UserSelect : : Contain : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // NOTE: This is handled at the start of this function
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    case  CSS : : UserSelect : : Text : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // https://drafts.csswg.org/css-ui/#valdef-user-select-text
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // The element imposes no constraint on the selection.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    case  CSS : : UserSelect : : Auto : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        VERIFY_NOT_REACHED ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    ( void ) selection - > set_base_and_extent ( * anchor_node ,  anchor_offset ,  * focus_node ,  focus_offset ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-04-26 16:59:04 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								EventHandler : : EventHandler ( Badge < HTML : : Navigable > ,  HTML : : Navigable &  navigable )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    :  m_navigable ( navigable ) 
							 
						 
					
						
							
								
									
										
										
										
											2024-08-17 13:29:55 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    ,  m_drag_and_drop_event_handler ( make < DragAndDropEventHandler > ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-07 14:40:38 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-14 13:21:51 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								EventHandler : : ~ EventHandler ( )  =  default ;  
						 
					
						
							
								
									
										
										
										
											2020-06-07 14:40:38 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-11 00:03:28 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								Painting : : PaintableBox *  EventHandler : : paint_root ( )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2024-04-26 16:59:04 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! m_navigable - > active_document ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-11 00:03:28 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-04-26 16:59:04 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    return  m_navigable - > active_document ( ) - > paintable_box ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-11 00:03:28 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								Painting : : PaintableBox  const *  EventHandler : : paint_root ( )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2024-04-26 16:59:04 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! m_navigable - > active_document ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-11 00:03:28 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-04-26 16:59:04 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    return  m_navigable - > active_document ( ) - > paintable_box ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-11 00:03:28 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-09-12 12:56:31 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								EventResult  EventHandler : : handle_mousewheel ( CSSPixelPoint  viewport_position ,  CSSPixelPoint  screen_position ,  u32  button ,  u32  buttons ,  u32  modifiers ,  int  wheel_delta_x ,  int  wheel_delta_y )  
						 
					
						
							
								
									
										
										
										
											2021-02-22 19:45:41 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2024-08-17 13:29:55 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( should_ignore_device_input_event ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2024-09-12 12:56:31 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  EventResult : : Dropped ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-08-17 13:29:55 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-04-26 16:59:04 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! m_navigable - > active_document ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2024-09-12 12:56:31 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  EventResult : : Dropped ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-04-26 16:59:04 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! m_navigable - > active_document ( ) - > is_fully_active ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2024-09-12 12:56:31 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  EventResult : : Dropped ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-10-03 15:35:07 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-04-26 16:59:04 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    m_navigable - > active_document ( ) - > update_layout ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-16 18:50:56 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-11 00:03:28 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! paint_root ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2024-09-12 12:56:31 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  EventResult : : Dropped ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-02-22 19:48:24 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-06-06 13:29:08 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( modifiers  &  UIEvents : : KeyModifier : : Mod_Shift ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-20 22:35:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        swap ( wheel_delta_x ,  wheel_delta_y ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-09-12 12:56:31 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  handled_event  =  EventResult : : Dropped ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-02-22 19:48:24 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-11-15 04:01:23 +13:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    GC : : Ptr < Painting : : Paintable >  paintable ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-11-15 17:36:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( auto  result  =  target_for_mouse_position ( viewport_position ) ;  result . has_value ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-04-27 09:19:20 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        paintable  =  result - > paintable ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-02 08:39:07 +11:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-08-09 22:36:46 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( paintable )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto *  containing_block  =  paintable - > containing_block ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        while  ( containing_block )  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-11-15 17:36:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            auto  handled_scroll_event  =  containing_block - > handle_mousewheel ( { } ,  viewport_position ,  buttons ,  modifiers ,  wheel_delta_x ,  wheel_delta_y ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-02-29 10:35:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( handled_scroll_event ) 
							 
						 
					
						
							
								
									
										
										
										
											2024-09-12 12:56:31 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                return  EventResult : : Handled ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-08-09 22:36:46 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            containing_block  =  containing_block - > containing_block ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-06 14:36:02 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-11-15 17:36:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( paintable - > handle_mousewheel ( { } ,  viewport_position ,  buttons ,  modifiers ,  wheel_delta_x ,  wheel_delta_y ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2024-09-12 12:56:31 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  EventResult : : Handled ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-17 20:54:01 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-10-23 17:53:02 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto  node  =  dom_node_for_event_dispatch ( * paintable ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-17 20:54:01 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( node )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            // FIXME: Support wheel events in nested browsing contexts.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( is < HTML : : HTMLIFrameElement > ( * node ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-02-03 11:01:31 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                auto &  iframe  =  static_cast < HTML : : HTMLIFrameElement & > ( * node ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-12-20 15:52:47 +11:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                auto  position_in_iframe  =  viewport_position . translated ( compute_mouse_event_offset ( { } ,  * paintable ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-04-26 16:59:04 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                iframe . content_navigable ( ) - > event_handler ( ) . handle_mousewheel ( position_in_iframe ,  screen_position ,  button ,  buttons ,  modifiers ,  wheel_delta_x ,  wheel_delta_y ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-09-12 12:56:31 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                return  EventResult : : Dropped ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-17 20:54:01 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            // Search for the first parent of the hit target that's an element.
 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-25 10:44:51 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            Layout : : Node *  layout_node ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-24 03:24:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( ! parent_element_for_event_dispatch ( * paintable ,  node ,  layout_node ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2024-09-12 12:56:31 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                return  EventResult : : Dropped ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-17 20:54:01 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-11-15 17:36:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            auto  page_offset  =  compute_mouse_event_page_offset ( viewport_position ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-12-20 15:52:47 +11:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            auto  offset  =  compute_mouse_event_offset ( page_offset ,  * layout_node - > first_paintable ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-11-15 17:36:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( node - > dispatch_event ( UIEvents : : WheelEvent : : create_from_platform_event ( node - > realm ( ) ,  UIEvents : : EventNames : : wheel ,  screen_position ,  page_offset ,  viewport_position ,  offset ,  wheel_delta_x ,  wheel_delta_y ,  button ,  buttons ,  modifiers ) . release_value_but_fixme_should_propagate_errors ( ) ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-04-26 16:59:04 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                m_navigable - > active_window ( ) - > scroll_by ( wheel_delta_x ,  wheel_delta_y ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-17 20:54:01 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-09-12 12:56:31 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            handled_event  =  EventResult : : Handled ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-17 20:54:01 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2021-02-22 19:48:24 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-10-17 20:54:01 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    return  handled_event ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-02-22 19:45:41 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-09-12 12:56:31 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								EventResult  EventHandler : : handle_mouseup ( CSSPixelPoint  viewport_position ,  CSSPixelPoint  screen_position ,  u32  button ,  u32  buttons ,  u32  modifiers )  
						 
					
						
							
								
									
										
										
										
											2020-06-07 14:40:38 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2024-08-17 13:29:55 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( should_ignore_device_input_event ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2024-09-12 12:56:31 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  EventResult : : Dropped ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-08-17 13:29:55 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-04-26 16:59:04 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! m_navigable - > active_document ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2024-09-12 12:56:31 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  EventResult : : Dropped ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-04-26 16:59:04 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! m_navigable - > active_document ( ) - > is_fully_active ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2024-09-12 12:56:31 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  EventResult : : Dropped ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-10-03 15:35:07 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-04-26 16:59:04 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    m_navigable - > active_document ( ) - > update_layout ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-16 18:50:56 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-11 00:03:28 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! paint_root ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2024-09-12 12:56:31 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  EventResult : : Dropped ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-07 14:40:38 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-11-15 04:01:23 +13:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    GC : : Ptr < Painting : : Paintable >  paintable ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-11-15 17:36:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( auto  result  =  target_for_mouse_position ( viewport_position ) ;  result . has_value ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-04-27 09:19:20 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        paintable  =  result - > paintable ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-11 18:15:47 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-14 23:05:55 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( paintable  & &  paintable - > wants_mouse_events ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-11-15 17:36:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( paintable - > handle_mouseup ( { } ,  viewport_position ,  button ,  modifiers )  = =  Painting : : Paintable : : DispatchEventOfSameName : : No ) 
							 
						 
					
						
							
								
									
										
										
										
											2024-09-12 12:56:31 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  EventResult : : Cancelled ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-12 17:55:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-11-22 15:53:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        // Things may have changed as a consequence of Layout::Node::handle_mouseup(). Hit test again.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-11 00:03:28 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! paint_root ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2024-09-12 12:56:31 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  EventResult : : Handled ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-11-15 17:36:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( auto  result  =  paint_root ( ) - > hit_test ( viewport_position ,  Painting : : HitTestType : : Exact ) ;  result . has_value ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-21 11:11:05 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            paintable  =  result - > paintable ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-11 18:15:47 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-09-12 12:56:31 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  handled_event  =  EventResult : : Dropped ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-14 23:05:55 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( paintable )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-23 17:53:02 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto  node  =  dom_node_for_event_dispatch ( * paintable ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-07 13:27:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-14 23:05:55 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( node )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( is < HTML : : HTMLIFrameElement > ( * node ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-04-26 16:59:04 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                if  ( auto  content_navigable  =  static_cast < HTML : : HTMLIFrameElement & > ( * node ) . content_navigable ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2024-12-20 15:52:47 +11:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                    return  content_navigable - > event_handler ( ) . handle_mouseup ( viewport_position . translated ( compute_mouse_event_offset ( { } ,  * paintable ) ) ,  screen_position ,  button ,  buttons ,  modifiers ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-09-12 12:56:31 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                return  EventResult : : Dropped ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-14 23:05:55 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
									
										
										
										
											2022-05-03 16:50:38 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            // Search for the first parent of the hit target that's an element.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            // "The click event type MUST be dispatched on the topmost event target indicated by the pointer." (https://www.w3.org/TR/uievents/#event-type-click)
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            // "The topmost event target MUST be the element highest in the rendering order which is capable of being an event target." (https://www.w3.org/TR/uievents/#topmost-event-target)
 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-25 10:44:51 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            Layout : : Node *  layout_node ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-24 03:24:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( ! parent_element_for_event_dispatch ( * paintable ,  node ,  layout_node ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-05-03 16:50:38 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                // FIXME: This is pretty ugly but we need to bail out here.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                goto  after_node_use ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-11-15 17:36:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            auto  page_offset  =  compute_mouse_event_page_offset ( viewport_position ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-12-20 15:52:47 +11:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            auto  offset  =  compute_mouse_event_offset ( page_offset ,  * layout_node - > first_paintable ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-11-21 21:35:49 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            node - > dispatch_event ( UIEvents : : PointerEvent : : create_from_platform_event ( node - > realm ( ) ,  UIEvents : : EventNames : : pointerup ,  screen_position ,  page_offset ,  viewport_position ,  offset ,  { } ,  button ,  buttons ,  modifiers ) . release_value_but_fixme_should_propagate_errors ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-11-15 17:36:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            node - > dispatch_event ( UIEvents : : MouseEvent : : create_from_platform_event ( node - > realm ( ) ,  UIEvents : : EventNames : : mouseup ,  screen_position ,  page_offset ,  viewport_position ,  offset ,  { } ,  button ,  buttons ,  modifiers ) . release_value_but_fixme_should_propagate_errors ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-09-12 12:56:31 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            handled_event  =  EventResult : : Handled ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-14 23:05:55 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-07-21 16:42:48 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            bool  run_activation_behavior  =  false ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-21 20:29:30 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( node . ptr ( )  = =  m_mousedown_target )  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-06-02 19:00:42 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                if  ( button  = =  UIEvents : : MouseButton : : Primary )  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-11-15 17:36:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                    run_activation_behavior  =  node - > dispatch_event ( UIEvents : : MouseEvent : : create_from_platform_event ( node - > realm ( ) ,  UIEvents : : EventNames : : click ,  screen_position ,  page_offset ,  viewport_position ,  offset ,  { } ,  button ,  buttons ,  modifiers ) . release_value_but_fixme_should_propagate_errors ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-06-21 22:00:19 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                }  else  if  ( button  = =  UIEvents : : MouseButton : : Middle )  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-11-15 17:36:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                    run_activation_behavior  =  node - > dispatch_event ( UIEvents : : MouseEvent : : create_from_platform_event ( node - > realm ( ) ,  UIEvents : : EventNames : : auxclick ,  screen_position ,  page_offset ,  viewport_position ,  offset ,  { } ,  button ,  buttons ,  modifiers ) . release_value_but_fixme_should_propagate_errors ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-06-02 19:00:42 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                }  else  if  ( button  = =  UIEvents : : MouseButton : : Secondary )  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-04-25 10:04:11 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                    // Allow the user to bypass custom context menus by holding shift, like Firefox.
 
							 
						 
					
						
							
								
									
										
										
										
											2024-06-06 13:29:08 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                    if  ( ( modifiers  &  UIEvents : : Mod_Shift )  = =  0 ) 
							 
						 
					
						
							
								
									
										
										
										
											2024-11-15 17:36:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                        run_activation_behavior  =  node - > dispatch_event ( UIEvents : : MouseEvent : : create_from_platform_event ( node - > realm ( ) ,  UIEvents : : EventNames : : contextmenu ,  screen_position ,  page_offset ,  viewport_position ,  offset ,  { } ,  button ,  buttons ,  modifiers ) . release_value_but_fixme_should_propagate_errors ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-04-25 10:04:11 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                    else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                        run_activation_behavior  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                } 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-08 21:48:00 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( run_activation_behavior )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-09-13 15:25:45 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                // FIXME: Currently cannot spawn a new top-level
 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-08 21:48:00 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                //        browsing context for new tab operations, because the new
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                //        top-level browsing context would be in another process. To
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                //        fix this, there needs to be some way to be able to
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                //        communicate with browsing contexts in remote WebContent
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                //        processes, and then step 8 of this algorithm needs to be
 
							 
						 
					
						
							
								
									
										
										
										
											2023-09-13 15:25:45 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                //        implemented in Navigable::choose_a_navigable:
 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-08 21:48:00 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                //
 
							 
						 
					
						
							
								
									
										
										
										
											2023-09-13 15:25:45 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                //        https://html.spec.whatwg.org/multipage/document-sequences.html#the-rules-for-choosing-a-navigable
 
							 
						 
					
						
							
								
									
										
										
										
											2024-02-04 03:36:24 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2025-01-14 03:14:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                auto  top_level_viewport_position  =  m_navigable - > to_top_level_position ( viewport_position ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-11-15 04:01:23 +13:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                if  ( GC : : Ptr < HTML : : HTMLAnchorElement  const >  link  =  node - > enclosing_link_element ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    GC : : Ref < DOM : : Document >  document  =  * m_navigable - > active_document ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-08 21:48:00 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                    auto  href  =  link - > href ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-12-06 16:24:08 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                    auto  url  =  document - > encoding_parse_url ( href ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2025-01-23 19:40:57 +13:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                    if  ( url . has_value ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                        if  ( button  = =  UIEvents : : MouseButton : : Primary  & &  ( modifiers  &  UIEvents : : Mod_PlatformCtrl )  ! =  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                            m_navigable - > page ( ) . client ( ) . page_did_click_link ( * url ,  link - > target ( ) . to_byte_string ( ) ,  modifiers ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                        }  else  if  ( button  = =  UIEvents : : MouseButton : : Middle )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                            m_navigable - > page ( ) . client ( ) . page_did_middle_click_link ( * url ,  link - > target ( ) . to_byte_string ( ) ,  modifiers ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                        }  else  if  ( button  = =  UIEvents : : MouseButton : : Secondary )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                            m_navigable - > page ( ) . client ( ) . page_did_request_link_context_menu ( top_level_viewport_position ,  * url ,  link - > target ( ) . to_byte_string ( ) ,  modifiers ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                        } 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-15 14:37:58 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                    } 
							 
						 
					
						
							
								
									
										
										
										
											2024-06-02 19:00:42 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                }  else  if  ( button  = =  UIEvents : : MouseButton : : Secondary )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-08 21:48:00 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                    if  ( is < HTML : : HTMLImageElement > ( * node ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2025-01-21 09:12:05 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                        auto &  image_element  =  as < HTML : : HTMLImageElement > ( * node ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-12-06 16:24:08 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                        auto  image_url  =  image_element . document ( ) . encoding_parse_url ( image_element . src ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2025-01-23 19:40:57 +13:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                        if  ( image_url . has_value ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                            Optional < Gfx : : Bitmap  const * >  bitmap ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                            if  ( image_element . immutable_bitmap ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                                bitmap  =  image_element . immutable_bitmap ( ) - > bitmap ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2025-01-10 20:33:27 +11:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2025-01-23 19:40:57 +13:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                            m_navigable - > page ( ) . client ( ) . page_did_request_image_context_menu ( top_level_viewport_position ,  * image_url ,  " " ,  modifiers ,  bitmap ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                        } 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-16 10:51:38 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                    }  else  if  ( is < HTML : : HTMLMediaElement > ( * node ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2025-01-21 09:12:05 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                        auto &  media_element  =  as < HTML : : HTMLMediaElement > ( * node ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-15 09:42:56 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-06-16 10:51:38 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                        Page : : MediaContextMenu  menu  { 
							 
						 
					
						
							
								
									
										
										
										
											2025-01-23 19:40:57 +13:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                            . media_url  =  * media_element . document ( ) . encoding_parse_url ( media_element . current_src ( ) ) , 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-16 10:51:38 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                            . is_video  =  is < HTML : : HTMLVideoElement > ( * node ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                            . is_playing  =  media_element . potentially_playing ( ) , 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-16 11:29:54 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                            . is_muted  =  media_element . muted ( ) , 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-16 10:51:38 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                            . has_user_agent_controls  =  media_element . has_attribute ( HTML : : AttributeNames : : controls ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                            . is_looping  =  media_element . has_attribute ( HTML : : AttributeNames : : loop ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                        } ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-15 09:42:56 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2025-01-14 03:14:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                        m_navigable - > page ( ) . did_request_media_context_menu ( media_element . unique_id ( ) ,  top_level_viewport_position ,  " " ,  modifiers ,  move ( menu ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-12-03 20:29:37 +13:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                    }  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2025-01-14 03:14:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                        m_navigable - > page ( ) . client ( ) . page_did_request_context_menu ( top_level_viewport_position ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-08 21:48:00 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                    } 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-07 22:43:30 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                } 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-15 14:37:58 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
									
										
										
										
											2024-11-20 21:31:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( auto *  input_control  =  input_control_associated_with_ancestor_label_element ( * paintable ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                if  ( button  = =  UIEvents : : MouseButton : : Primary )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    input_control - > dispatch_event ( UIEvents : : MouseEvent : : create_from_platform_event ( node - > realm ( ) ,  UIEvents : : EventNames : : click ,  screen_position ,  page_offset ,  viewport_position ,  offset ,  { } ,  button ,  buttons ,  modifiers ) . release_value_but_fixme_should_propagate_errors ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-07 13:27:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-07 14:40:38 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-05-03 16:50:38 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								after_node_use :  
						 
					
						
							
								
									
										
										
										
											2024-08-26 13:07:57 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( button  = =  UIEvents : : MouseButton : : Primary )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-07 14:40:38 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        m_in_mouse_selection  =  false ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												LibWeb: Separate text control input events handling from contenteditable
This input event handling change is intended to address the following
design issues:
- Having `DOM::Position` is unnecessary complexity when `Selection`
  exists because caret position could be described by the selection
  object with a collapsed state. Before this change, we had to
  synchronize those whenever one of them was modified, and there were
  already bugs caused by that, i.e., caret position was not changed when
  selection offset was modified from the JS side.
- Selection API exposes selection offset within `<textarea>` and
  `<input>`, which is not supposed to happen. These objects should
  manage their selection state by themselves and have selection offset
  even when they are not displayed.
- `EventHandler` looks only at `DOM::Text` owned by `DOM::Position`
  while doing text manipulations. It works fine for `<input>` and
  `<textarea>`, but `contenteditable` needs to consider all text
  descendant text nodes; i.e., if the cursor is moved outside of
  `DOM::Text`, we need to look for an adjacent text node to move the
  cursor there.
With this change, `EventHandler` no longer does direct manipulations on
caret position or text content, but instead delegates them to the active
`InputEventsTarget`, which could be either
`FormAssociatedTextControlElement` (for `<input>` and `<textarea>`) or
`EditingHostManager` (for `contenteditable`). The `Selection` object is
used to manage both selection and caret position for `contenteditable`,
and text control elements manage their own selection state that is not
exposed by Selection API.
This change improves text editing on Discord, as now we don't have to
refocus the `contenteditable` element after character input. The problem
was that selection manipulations from the JS side were not propagated
to `DOM::Position`.
I expect this change to make future correctness improvements for
`contenteditable` (and `designMode`) easier, as now it's decoupled from
`<input>` and `<textarea>` and separated from `EventHandler`, which is
quite a busy file.
											 
										 
										
											2024-10-23 21:26:58 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        m_mouse_selection_target  =  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-08-26 13:07:57 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-07 14:40:38 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  handled_event ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-09-12 12:56:31 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								EventResult  EventHandler : : handle_mousedown ( CSSPixelPoint  viewport_position ,  CSSPixelPoint  screen_position ,  u32  button ,  u32  buttons ,  u32  modifiers )  
						 
					
						
							
								
									
										
										
										
											2020-06-07 14:40:38 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2024-08-17 13:29:55 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( should_ignore_device_input_event ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2024-09-12 12:56:31 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  EventResult : : Dropped ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-08-17 13:29:55 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-04-26 16:59:04 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! m_navigable - > active_document ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2024-09-12 12:56:31 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  EventResult : : Dropped ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-04-26 16:59:04 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! m_navigable - > active_document ( ) - > is_fully_active ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2024-09-12 12:56:31 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  EventResult : : Dropped ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-10-03 15:35:07 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-04-26 16:59:04 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    m_navigable - > active_document ( ) - > update_layout ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-16 18:50:56 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-11 00:03:28 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! paint_root ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2024-09-12 12:56:31 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  EventResult : : Dropped ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-11 18:15:47 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-11-15 04:01:23 +13:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    GC : : Ref < DOM : : Document >  document  =  * m_navigable - > active_document ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    GC : : Ptr < DOM : : Node >  node ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-07 14:40:38 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-11-29 16:39:56 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    { 
							 
						 
					
						
							
								
									
										
										
										
											2024-11-15 04:01:23 +13:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        GC : : Ptr < Painting : : Paintable >  paintable ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-11-15 17:36:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( auto  result  =  target_for_mouse_position ( viewport_position ) ;  result . has_value ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-21 11:11:05 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            paintable  =  result - > paintable ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-04-27 09:19:20 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        else 
							 
						 
					
						
							
								
									
										
										
										
											2024-09-12 12:56:31 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  EventResult : : Dropped ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-07 14:40:38 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-14 23:05:55 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto  pointer_events  =  paintable - > computed_values ( ) . pointer_events ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-07 17:19:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        // FIXME: Handle other values for pointer-events.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-19 13:46:48 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        VERIFY ( pointer_events  ! =  CSS : : PointerEvents : : None ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-19 12:53:22 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-10-23 17:53:02 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        node  =  dom_node_for_event_dispatch ( * paintable ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-29 16:39:56 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        document - > set_hovered_node ( node ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-12 17:55:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-14 23:05:55 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( paintable - > wants_mouse_events ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-11-15 17:36:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( paintable - > handle_mousedown ( { } ,  viewport_position ,  button ,  modifiers )  = =  Painting : : Paintable : : DispatchEventOfSameName : : No ) 
							 
						 
					
						
							
								
									
										
										
										
											2024-09-12 12:56:31 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                return  EventResult : : Cancelled ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-29 16:39:56 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-11 18:15:47 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-11-29 16:39:56 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! node ) 
							 
						 
					
						
							
								
									
										
										
										
											2024-09-12 12:56:31 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  EventResult : : Dropped ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-07 14:40:38 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-11-29 16:39:56 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( is < HTML : : HTMLIFrameElement > ( * node ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-04-26 16:59:04 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( auto  content_navigable  =  static_cast < HTML : : HTMLIFrameElement & > ( * node ) . content_navigable ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2024-12-20 15:52:47 +11:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                return  content_navigable - > event_handler ( ) . handle_mousedown ( viewport_position . translated ( compute_mouse_event_offset ( { } ,  * paintable ) ) ,  screen_position ,  button ,  buttons ,  modifiers ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-09-12 12:56:31 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  EventResult : : Dropped ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-29 16:39:56 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-07 14:40:38 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-04-26 16:59:04 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        m_navigable - > page ( ) . set_focused_navigable ( { } ,  m_navigable ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-08-14 11:33:20 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-05-03 16:50:38 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        // Search for the first parent of the hit target that's an element.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // "The click event type MUST be dispatched on the topmost event target indicated by the pointer." (https://www.w3.org/TR/uievents/#event-type-click)
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // "The topmost event target MUST be the element highest in the rendering order which is capable of being an event target." (https://www.w3.org/TR/uievents/#topmost-event-target)
 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-25 10:44:51 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        Layout : : Node *  layout_node ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-24 03:24:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! parent_element_for_event_dispatch ( * paintable ,  node ,  layout_node ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2024-09-12 12:56:31 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  EventResult : : Dropped ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-05-03 16:50:38 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-08-28 13:42:07 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        m_mousedown_target  =  node . ptr ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-11-15 17:36:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto  page_offset  =  compute_mouse_event_page_offset ( viewport_position ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-12-20 15:52:47 +11:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto  offset  =  compute_mouse_event_offset ( page_offset ,  * layout_node - > first_paintable ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-11-21 21:35:49 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        node - > dispatch_event ( UIEvents : : PointerEvent : : create_from_platform_event ( node - > realm ( ) ,  UIEvents : : EventNames : : pointerdown ,  screen_position ,  page_offset ,  viewport_position ,  offset ,  { } ,  button ,  buttons ,  modifiers ) . release_value_but_fixme_should_propagate_errors ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-11-15 17:36:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        node - > dispatch_event ( UIEvents : : MouseEvent : : create_from_platform_event ( node - > realm ( ) ,  UIEvents : : EventNames : : mousedown ,  screen_position ,  page_offset ,  viewport_position ,  offset ,  { } ,  button ,  buttons ,  modifiers ) . release_value_but_fixme_should_propagate_errors ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-29 16:39:56 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // NOTE: Dispatching an event may have disturbed the world.
 
							 
						 
					
						
							
								
									
										
										
										
											2023-04-20 16:01:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! paint_root ( )  | |  paint_root ( )  ! =  node - > document ( ) . paintable_box ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2024-09-12 12:56:31 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  EventResult : : Accepted ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-10 23:43:25 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-06-02 19:00:42 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( button  = =  UIEvents : : MouseButton : : Primary )  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-11-15 17:36:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( auto  result  =  paint_root ( ) - > hit_test ( viewport_position ,  Painting : : HitTestType : : TextCursor ) ;  result . has_value ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-15 14:37:58 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            auto  paintable  =  result - > paintable ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-08-19 16:22:31 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            auto  dom_node  =  paintable - > dom_node ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( dom_node )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-06 19:28:09 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                // See if we want to focus something.
 
							 
						 
					
						
							
								
									
										
										
										
											2024-11-15 04:01:23 +13:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                GC : : Ptr < DOM : : Node >  focus_candidate ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-11-20 21:31:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                if  ( auto *  input_control  =  input_control_associated_with_ancestor_label_element ( * paintable ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    focus_candidate  =  input_control ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    for  ( auto  candidate  =  node ;  candidate ;  candidate  =  candidate - > parent_or_shadow_host ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                        if  ( candidate - > is_focusable ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                            focus_candidate  =  candidate ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                            break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                        } 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-06 19:28:09 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												LibWeb: Separate text control input events handling from contenteditable
This input event handling change is intended to address the following
design issues:
- Having `DOM::Position` is unnecessary complexity when `Selection`
  exists because caret position could be described by the selection
  object with a collapsed state. Before this change, we had to
  synchronize those whenever one of them was modified, and there were
  already bugs caused by that, i.e., caret position was not changed when
  selection offset was modified from the JS side.
- Selection API exposes selection offset within `<textarea>` and
  `<input>`, which is not supposed to happen. These objects should
  manage their selection state by themselves and have selection offset
  even when they are not displayed.
- `EventHandler` looks only at `DOM::Text` owned by `DOM::Position`
  while doing text manipulations. It works fine for `<input>` and
  `<textarea>`, but `contenteditable` needs to consider all text
  descendant text nodes; i.e., if the cursor is moved outside of
  `DOM::Text`, we need to look for an adjacent text node to move the
  cursor there.
With this change, `EventHandler` no longer does direct manipulations on
caret position or text content, but instead delegates them to the active
`InputEventsTarget`, which could be either
`FormAssociatedTextControlElement` (for `<input>` and `<textarea>`) or
`EditingHostManager` (for `contenteditable`). The `Selection` object is
used to manage both selection and caret position for `contenteditable`,
and text control elements manage their own selection state that is not
exposed by Selection API.
This change improves text editing on Discord, as now we don't have to
refocus the `contenteditable` element after character input. The problem
was that selection manipulations from the JS side were not propagated
to `DOM::Position`.
I expect this change to make future correctness improvements for
`contenteditable` (and `designMode`) easier, as now it's decoupled from
`<input>` and `<textarea>` and separated from `EventHandler`, which is
quite a busy file.
											 
										 
										
											2024-10-23 21:26:58 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                // When a user activates a click focusable focusable area, the user agent must run the focusing steps on the focusable area with focus trigger set to "click".
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                // Spec Note: Note that focusing is not an activation behavior, i.e. calling the click() method on an element or dispatching a synthetic click event on it won't cause the element to get focused.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                if  ( focus_candidate ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    HTML : : run_focusing_steps ( focus_candidate ,  nullptr ,  " click " sv ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                else  if  ( auto *  focused_element  =  document - > focused_element ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    HTML : : run_unfocusing_steps ( focused_element ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2025-01-08 01:51:29 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                // https://drafts.csswg.org/css-ui/#valdef-user-select-none
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                // Attempting to start a selection in an element where user-select is none, such as by clicking in it or starting
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                // a drag in it, must not cause a pre-existing selection to become unselected or to be affected in any way.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                auto  user_select  =  paintable - > layout_node ( ) . user_select_used_value ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                if  ( user_select  ! =  CSS : : UserSelect : : None )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    auto  target  =  document - > active_input_events_target ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    if  ( target )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                        m_in_mouse_selection  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                        m_mouse_selection_target  =  target ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                        if  ( modifiers  &  UIEvents : : KeyModifier : : Mod_Shift )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                            target - > set_selection_focus ( * dom_node ,  result - > index_in_node ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-06-05 16:01:31 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                        }  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2025-01-08 01:51:29 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                            target - > set_selection_anchor ( * dom_node ,  result - > index_in_node ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    }  else  if  ( ! focus_candidate )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                        m_in_mouse_selection  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                        if  ( auto  selection  =  document - > get_selection ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                            auto  anchor_node  =  selection - > anchor_node ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                            if  ( anchor_node  & &  modifiers  &  UIEvents : : KeyModifier : : Mod_Shift )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                                set_user_selection ( * anchor_node ,  selection - > anchor_offset ( ) ,  * dom_node ,  result - > index_in_node ,  selection ,  user_select ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                            }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                                set_user_selection ( * dom_node ,  result - > index_in_node ,  * dom_node ,  result - > index_in_node ,  selection ,  user_select ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                            } 
							 
						 
					
						
							
								
									
										
										
										
											2024-06-05 16:01:31 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                        } 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-11 19:48:53 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                    } 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-06 19:28:09 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                } 
							 
						 
					
						
							
								
									
										
										
										
											2020-08-05 16:55:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-27 14:21:58 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-07 14:40:38 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2024-09-12 12:56:31 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  EventResult : : Handled ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-07 14:40:38 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-09-12 12:56:31 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								EventResult  EventHandler : : handle_mousemove ( CSSPixelPoint  viewport_position ,  CSSPixelPoint  screen_position ,  u32  buttons ,  u32  modifiers )  
						 
					
						
							
								
									
										
										
										
											2020-06-07 14:40:38 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2024-08-17 13:29:55 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( should_ignore_device_input_event ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2024-09-12 12:56:31 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  EventResult : : Dropped ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-08-17 13:29:55 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-04-26 16:59:04 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! m_navigable - > active_document ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2024-09-12 12:56:31 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  EventResult : : Dropped ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-04-26 16:59:04 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! m_navigable - > active_document ( ) - > is_fully_active ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2024-09-12 12:56:31 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  EventResult : : Dropped ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-10-03 15:35:07 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-04-26 16:59:04 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    m_navigable - > active_document ( ) - > update_layout ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-16 18:50:56 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-11 00:03:28 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! paint_root ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2024-09-12 12:56:31 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  EventResult : : Dropped ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-11 18:15:47 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-04-26 16:59:04 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto &  document  =  * m_navigable - > active_document ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-07 14:40:38 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    bool  hovered_node_changed  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    bool  is_hovering_link  =  false ; 
							 
						 
					
						
							
								
									
										
										
										
											2025-02-20 12:17:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    Gfx : : Cursor  hovered_node_cursor  =  Gfx : : StandardCursor : : None ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-14 23:05:55 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-11-15 04:01:23 +13:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    GC : : Ptr < Painting : : Paintable >  paintable ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-14 23:05:55 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    Optional < int >  start_index ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-04-27 09:19:20 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-11-15 17:36:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( auto  result  =  target_for_mouse_position ( viewport_position ) ;  result . has_value ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-04-27 09:19:20 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        paintable  =  result - > paintable ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        start_index  =  result - > index_in_node ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-14 23:05:55 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-07-28 18:20:36 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    const  HTML : : HTMLAnchorElement *  hovered_link_element  =  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-14 23:05:55 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( paintable )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( paintable - > wants_mouse_events ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-21 11:19:02 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            document . set_hovered_node ( paintable - > dom_node ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-11-15 17:36:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( paintable - > handle_mousemove ( { } ,  viewport_position ,  buttons ,  modifiers )  = =  Painting : : Paintable : : DispatchEventOfSameName : : No ) 
							 
						 
					
						
							
								
									
										
										
										
											2024-09-12 12:56:31 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                return  EventResult : : Cancelled ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-14 23:05:55 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-09-11 18:15:47 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            // FIXME: It feels a bit aggressive to always update the cursor like this.
 
							 
						 
					
						
							
								
									
										
										
										
											2024-04-26 16:59:04 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            m_navigable - > page ( ) . client ( ) . page_did_request_cursor_change ( Gfx : : StandardCursor : : None ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-11 18:15:47 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-10-23 17:53:02 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto  node  =  dom_node_for_event_dispatch ( * paintable ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-07 14:40:38 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-07-28 18:20:36 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( node  & &  is < HTML : : HTMLIFrameElement > ( * node ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-04-26 16:59:04 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( auto  content_navigable  =  static_cast < HTML : : HTMLIFrameElement & > ( * node ) . content_navigable ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2024-12-20 15:52:47 +11:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                return  content_navigable - > event_handler ( ) . handle_mousemove ( viewport_position . translated ( compute_mouse_event_offset ( { } ,  * paintable ) ) ,  screen_position ,  buttons ,  modifiers ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-09-12 12:56:31 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  EventResult : : Dropped ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-07 14:40:38 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2025-02-20 12:17:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto  cursor_data  =  paintable - > computed_values ( ) . cursor ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-14 23:05:55 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto  pointer_events  =  paintable - > computed_values ( ) . pointer_events ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-07 17:19:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        // FIXME: Handle other values for pointer-events.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-19 13:46:48 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        VERIFY ( pointer_events  ! =  CSS : : PointerEvents : : None ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-05 19:47:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-11-07 18:22:33 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        // Search for the first parent of the hit target that's an element.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // "The click event type MUST be dispatched on the topmost event target indicated by the pointer." (https://www.w3.org/TR/uievents/#event-type-click)
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // "The topmost event target MUST be the element highest in the rendering order which is capable of being an event target." (https://www.w3.org/TR/uievents/#topmost-event-target)
 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-25 10:44:51 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        Layout : : Node *  layout_node ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-07 18:22:33 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        bool  found_parent_element  =  parent_element_for_event_dispatch ( * paintable ,  node ,  layout_node ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-28 13:42:07 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        hovered_node_changed  =  node . ptr ( )  ! =  document . hovered_node ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-07 14:40:38 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        document . set_hovered_node ( node ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-07 18:22:33 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( found_parent_element )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-07 14:40:38 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            hovered_link_element  =  node - > enclosing_link_element ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-19 22:21:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( hovered_link_element ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-07 14:40:38 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                is_hovering_link  =  true ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-02-21 20:15:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-02-12 18:34:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( paintable - > layout_node ( ) . is_text_node ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2025-02-20 12:17:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                hovered_node_cursor  =  resolve_cursor ( * paintable - > layout_node ( ) . parent ( ) ,  cursor_data ,  Gfx : : StandardCursor : : IBeam ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-15 21:48:48 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            }  else  if  ( node - > is_element ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2025-02-20 12:17:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                hovered_node_cursor  =  resolve_cursor ( static_cast < Layout : : NodeWithStyle & > ( * layout_node ) ,  cursor_data ,  Gfx : : StandardCursor : : Arrow ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-05 19:47:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
									
										
										
										
											2021-02-21 20:15:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-11-15 17:36:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            auto  page_offset  =  compute_mouse_event_page_offset ( viewport_position ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-12-20 15:52:47 +11:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            auto  offset  =  compute_mouse_event_offset ( page_offset ,  * layout_node - > first_paintable ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-09-08 18:48:44 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            auto  movement  =  compute_mouse_event_movement ( screen_position ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-12-02 10:54:17 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-09-08 18:48:44 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            m_mousemove_previous_screen_position  =  screen_position ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-12-02 10:54:17 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-11-21 21:35:49 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            bool  continue_  =  node - > dispatch_event ( UIEvents : : PointerEvent : : create_from_platform_event ( node - > realm ( ) ,  UIEvents : : EventNames : : pointermove ,  screen_position ,  page_offset ,  viewport_position ,  offset ,  movement ,  UIEvents : : MouseButton : : Primary ,  buttons ,  modifiers ) . release_value_but_fixme_should_propagate_errors ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( ! continue_ ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  EventResult : : Cancelled ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            continue_  =  node - > dispatch_event ( UIEvents : : MouseEvent : : create_from_platform_event ( node - > realm ( ) ,  UIEvents : : EventNames : : mousemove ,  screen_position ,  page_offset ,  viewport_position ,  offset ,  movement ,  UIEvents : : MouseButton : : Primary ,  buttons ,  modifiers ) . release_value_but_fixme_should_propagate_errors ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-12-02 10:54:17 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( ! continue_ ) 
							 
						 
					
						
							
								
									
										
										
										
											2024-09-12 12:56:31 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                return  EventResult : : Cancelled ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-12-02 10:54:17 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-11-29 16:39:56 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            // NOTE: Dispatching an event may have disturbed the world.
 
							 
						 
					
						
							
								
									
										
										
										
											2023-04-20 16:01:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( ! paint_root ( )  | |  paint_root ( )  ! =  node - > document ( ) . paintable_box ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2024-09-12 12:56:31 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                return  EventResult : : Accepted ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-07 14:40:38 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2024-09-12 12:56:31 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-06-07 14:40:38 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( m_in_mouse_selection )  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-11-15 17:36:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            auto  hit  =  paint_root ( ) - > hit_test ( viewport_position ,  Painting : : HitTestType : : TextCursor ) ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												LibWeb: Separate text control input events handling from contenteditable
This input event handling change is intended to address the following
design issues:
- Having `DOM::Position` is unnecessary complexity when `Selection`
  exists because caret position could be described by the selection
  object with a collapsed state. Before this change, we had to
  synchronize those whenever one of them was modified, and there were
  already bugs caused by that, i.e., caret position was not changed when
  selection offset was modified from the JS side.
- Selection API exposes selection offset within `<textarea>` and
  `<input>`, which is not supposed to happen. These objects should
  manage their selection state by themselves and have selection offset
  even when they are not displayed.
- `EventHandler` looks only at `DOM::Text` owned by `DOM::Position`
  while doing text manipulations. It works fine for `<input>` and
  `<textarea>`, but `contenteditable` needs to consider all text
  descendant text nodes; i.e., if the cursor is moved outside of
  `DOM::Text`, we need to look for an adjacent text node to move the
  cursor there.
With this change, `EventHandler` no longer does direct manipulations on
caret position or text content, but instead delegates them to the active
`InputEventsTarget`, which could be either
`FormAssociatedTextControlElement` (for `<input>` and `<textarea>`) or
`EditingHostManager` (for `contenteditable`). The `Selection` object is
used to manage both selection and caret position for `contenteditable`,
and text control elements manage their own selection state that is not
exposed by Selection API.
This change improves text editing on Discord, as now we don't have to
refocus the `contenteditable` element after character input. The problem
was that selection manipulations from the JS side were not propagated
to `DOM::Position`.
I expect this change to make future correctness improvements for
`contenteditable` (and `designMode`) easier, as now it's decoupled from
`<input>` and `<textarea>` and separated from `EventHandler`, which is
quite a busy file.
											 
										 
										
											2024-10-23 21:26:58 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( m_mouse_selection_target )  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-12-06 16:32:20 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                if  ( hit . has_value ( )  & &  hit - > paintable - > dom_node ( ) ) 
							 
						 
					
						
							
								
									
										
											 
										
											
												LibWeb: Separate text control input events handling from contenteditable
This input event handling change is intended to address the following
design issues:
- Having `DOM::Position` is unnecessary complexity when `Selection`
  exists because caret position could be described by the selection
  object with a collapsed state. Before this change, we had to
  synchronize those whenever one of them was modified, and there were
  already bugs caused by that, i.e., caret position was not changed when
  selection offset was modified from the JS side.
- Selection API exposes selection offset within `<textarea>` and
  `<input>`, which is not supposed to happen. These objects should
  manage their selection state by themselves and have selection offset
  even when they are not displayed.
- `EventHandler` looks only at `DOM::Text` owned by `DOM::Position`
  while doing text manipulations. It works fine for `<input>` and
  `<textarea>`, but `contenteditable` needs to consider all text
  descendant text nodes; i.e., if the cursor is moved outside of
  `DOM::Text`, we need to look for an adjacent text node to move the
  cursor there.
With this change, `EventHandler` no longer does direct manipulations on
caret position or text content, but instead delegates them to the active
`InputEventsTarget`, which could be either
`FormAssociatedTextControlElement` (for `<input>` and `<textarea>`) or
`EditingHostManager` (for `contenteditable`). The `Selection` object is
used to manage both selection and caret position for `contenteditable`,
and text control elements manage their own selection state that is not
exposed by Selection API.
This change improves text editing on Discord, as now we don't have to
refocus the `contenteditable` element after character input. The problem
was that selection manipulations from the JS side were not propagated
to `DOM::Position`.
I expect this change to make future correctness improvements for
`contenteditable` (and `designMode`) easier, as now it's decoupled from
`<input>` and `<textarea>` and separated from `EventHandler`, which is
quite a busy file.
											 
										 
										
											2024-10-23 21:26:58 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                    m_mouse_selection_target - > set_selection_focus ( * hit - > paintable - > dom_node ( ) ,  hit - > index_in_node ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                if  ( start_index . has_value ( )  & &  hit . has_value ( )  & &  hit - > dom_node ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    if  ( auto  selection  =  document . get_selection ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                        auto  anchor_node  =  selection - > anchor_node ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                        if  ( anchor_node )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                            if  ( & anchor_node - > root ( )  = =  & hit - > dom_node ( ) - > root ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2025-01-08 01:51:29 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                                set_user_selection ( * anchor_node ,  selection - > anchor_offset ( ) ,  * hit - > paintable - > dom_node ( ) ,  hit - > index_in_node ,  selection ,  hit - > paintable - > layout_node ( ) . user_select_used_value ( ) ) ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												LibWeb: Separate text control input events handling from contenteditable
This input event handling change is intended to address the following
design issues:
- Having `DOM::Position` is unnecessary complexity when `Selection`
  exists because caret position could be described by the selection
  object with a collapsed state. Before this change, we had to
  synchronize those whenever one of them was modified, and there were
  already bugs caused by that, i.e., caret position was not changed when
  selection offset was modified from the JS side.
- Selection API exposes selection offset within `<textarea>` and
  `<input>`, which is not supposed to happen. These objects should
  manage their selection state by themselves and have selection offset
  even when they are not displayed.
- `EventHandler` looks only at `DOM::Text` owned by `DOM::Position`
  while doing text manipulations. It works fine for `<input>` and
  `<textarea>`, but `contenteditable` needs to consider all text
  descendant text nodes; i.e., if the cursor is moved outside of
  `DOM::Text`, we need to look for an adjacent text node to move the
  cursor there.
With this change, `EventHandler` no longer does direct manipulations on
caret position or text content, but instead delegates them to the active
`InputEventsTarget`, which could be either
`FormAssociatedTextControlElement` (for `<input>` and `<textarea>`) or
`EditingHostManager` (for `contenteditable`). The `Selection` object is
used to manage both selection and caret position for `contenteditable`,
and text control elements manage their own selection state that is not
exposed by Selection API.
This change improves text editing on Discord, as now we don't have to
refocus the `contenteditable` element after character input. The problem
was that selection manipulations from the JS side were not propagated
to `DOM::Position`.
I expect this change to make future correctness improvements for
`contenteditable` (and `designMode`) easier, as now it's decoupled from
`<input>` and `<textarea>` and separated from `EventHandler`, which is
quite a busy file.
											 
										 
										
											2024-10-23 21:26:58 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                        }  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2025-01-08 01:51:29 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                            set_user_selection ( * hit - > paintable - > dom_node ( ) ,  hit - > index_in_node ,  * hit - > paintable - > dom_node ( ) ,  hit - > index_in_node ,  selection ,  hit - > paintable - > layout_node ( ) . user_select_used_value ( ) ) ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												LibWeb: Separate text control input events handling from contenteditable
This input event handling change is intended to address the following
design issues:
- Having `DOM::Position` is unnecessary complexity when `Selection`
  exists because caret position could be described by the selection
  object with a collapsed state. Before this change, we had to
  synchronize those whenever one of them was modified, and there were
  already bugs caused by that, i.e., caret position was not changed when
  selection offset was modified from the JS side.
- Selection API exposes selection offset within `<textarea>` and
  `<input>`, which is not supposed to happen. These objects should
  manage their selection state by themselves and have selection offset
  even when they are not displayed.
- `EventHandler` looks only at `DOM::Text` owned by `DOM::Position`
  while doing text manipulations. It works fine for `<input>` and
  `<textarea>`, but `contenteditable` needs to consider all text
  descendant text nodes; i.e., if the cursor is moved outside of
  `DOM::Text`, we need to look for an adjacent text node to move the
  cursor there.
With this change, `EventHandler` no longer does direct manipulations on
caret position or text content, but instead delegates them to the active
`InputEventsTarget`, which could be either
`FormAssociatedTextControlElement` (for `<input>` and `<textarea>`) or
`EditingHostManager` (for `contenteditable`). The `Selection` object is
used to manage both selection and caret position for `contenteditable`,
and text control elements manage their own selection state that is not
exposed by Selection API.
This change improves text editing on Discord, as now we don't have to
refocus the `contenteditable` element after character input. The problem
was that selection manipulations from the JS side were not propagated
to `DOM::Position`.
I expect this change to make future correctness improvements for
`contenteditable` (and `designMode`) easier, as now it's decoupled from
`<input>` and `<textarea>` and separated from `EventHandler`, which is
quite a busy file.
											 
										 
										
											2024-10-23 21:26:58 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    } 
							 
						 
					
						
							
								
									
										
										
										
											2024-07-02 10:17:47 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												LibWeb: Separate text control input events handling from contenteditable
This input event handling change is intended to address the following
design issues:
- Having `DOM::Position` is unnecessary complexity when `Selection`
  exists because caret position could be described by the selection
  object with a collapsed state. Before this change, we had to
  synchronize those whenever one of them was modified, and there were
  already bugs caused by that, i.e., caret position was not changed when
  selection offset was modified from the JS side.
- Selection API exposes selection offset within `<textarea>` and
  `<input>`, which is not supposed to happen. These objects should
  manage their selection state by themselves and have selection offset
  even when they are not displayed.
- `EventHandler` looks only at `DOM::Text` owned by `DOM::Position`
  while doing text manipulations. It works fine for `<input>` and
  `<textarea>`, but `contenteditable` needs to consider all text
  descendant text nodes; i.e., if the cursor is moved outside of
  `DOM::Text`, we need to look for an adjacent text node to move the
  cursor there.
With this change, `EventHandler` no longer does direct manipulations on
caret position or text content, but instead delegates them to the active
`InputEventsTarget`, which could be either
`FormAssociatedTextControlElement` (for `<input>` and `<textarea>`) or
`EditingHostManager` (for `contenteditable`). The `Selection` object is
used to manage both selection and caret position for `contenteditable`,
and text control elements manage their own selection state that is not
exposed by Selection API.
This change improves text editing on Discord, as now we don't have to
refocus the `contenteditable` element after character input. The problem
was that selection manipulations from the JS side were not propagated
to `DOM::Position`.
I expect this change to make future correctness improvements for
`contenteditable` (and `designMode`) easier, as now it's decoupled from
`<input>` and `<textarea>` and separated from `EventHandler`, which is
quite a busy file.
											 
										 
										
											2024-10-23 21:26:58 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                    document . set_needs_display ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                } 
							 
						 
					
						
							
								
									
										
										
										
											2020-08-05 16:55:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-07 14:40:38 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2020-08-17 12:54:41 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-04-26 16:59:04 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto &  page  =  m_navigable - > page ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-12 18:23:05 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2025-02-20 12:17:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // FIXME: This check is only approximate. ImageCursors from the same CursorStyleValue share bitmaps, but may repaint them.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    //        So comparing them does not tell you if they are the same image. Also, the image may change even if the hovered
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    //        node does not.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( page . current_cursor ( )  ! =  hovered_node_cursor  | |  hovered_node_changed )  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-04-20 10:13:39 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        page . set_current_cursor ( hovered_node_cursor ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        page . client ( ) . page_did_request_cursor_change ( hovered_node_cursor ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2023-12-03 20:29:37 +13:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( hovered_node_changed )  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-11-15 04:01:23 +13:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        GC : : Ptr < HTML : : HTMLElement  const >  hovered_html_element  =  document . hovered_node ( )  ?  document . hovered_node ( ) - > enclosing_html_element_with_attribute ( HTML : : AttributeNames : : title )  :  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-04-20 10:14:31 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-12-03 20:29:37 +13:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( hovered_html_element  & &  hovered_html_element - > title ( ) . has_value ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-04-20 10:14:31 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            page . set_is_in_tooltip_area ( true ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-07-02 14:16:24 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            page . client ( ) . page_did_enter_tooltip_area ( hovered_html_element - > title ( ) - > to_byte_string ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-04-20 10:14:31 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        }  else  if  ( page . is_in_tooltip_area ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            page . set_is_in_tooltip_area ( false ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-12-03 20:29:37 +13:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            page . client ( ) . page_did_leave_tooltip_area ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-12 18:23:05 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2024-04-20 10:14:31 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( is_hovering_link )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            page . set_is_hovering_link ( true ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2025-01-23 19:40:57 +13:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            page . client ( ) . page_did_hover_link ( * document . encoding_parse_url ( hovered_link_element - > href ( ) ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-04-20 10:14:31 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        }  else  if  ( page . is_hovering_link ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            page . set_is_hovering_link ( false ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-12-03 20:29:37 +13:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            page . client ( ) . page_did_unhover_link ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-04-20 10:14:31 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-07 14:40:38 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2023-12-03 20:29:37 +13:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-09-12 12:56:31 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    return  EventResult : : Handled ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-07 14:40:38 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-09-12 12:56:31 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								EventResult  EventHandler : : handle_doubleclick ( CSSPixelPoint  viewport_position ,  CSSPixelPoint  screen_position ,  u32  button ,  u32  buttons ,  u32  modifiers )  
						 
					
						
							
								
									
										
										
										
											2022-06-14 19:38:00 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2024-08-17 13:29:55 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( should_ignore_device_input_event ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2024-09-12 12:56:31 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  EventResult : : Dropped ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-08-17 13:29:55 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-04-26 16:59:04 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! m_navigable - > active_document ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2024-09-12 12:56:31 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  EventResult : : Dropped ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-04-26 16:59:04 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! m_navigable - > active_document ( ) - > is_fully_active ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2024-09-12 12:56:31 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  EventResult : : Dropped ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-10-03 15:35:07 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-08-02 07:31:40 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto &  document  =  * m_navigable - > active_document ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    document . update_layout ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-14 19:38:00 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! paint_root ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2024-09-12 12:56:31 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  EventResult : : Dropped ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-14 19:38:00 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-11-15 04:01:23 +13:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    GC : : Ptr < Painting : : Paintable >  paintable ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-11-15 17:36:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( auto  result  =  target_for_mouse_position ( viewport_position ) ;  result . has_value ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-14 19:38:00 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        paintable  =  result - > paintable ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-04-27 09:19:20 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    else 
							 
						 
					
						
							
								
									
										
										
										
											2024-09-12 12:56:31 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  EventResult : : Dropped ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-14 19:38:00 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  pointer_events  =  paintable - > computed_values ( ) . pointer_events ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // FIXME: Handle other values for pointer-events.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( pointer_events  = =  CSS : : PointerEvents : : None ) 
							 
						 
					
						
							
								
									
										
										
										
											2024-09-12 12:56:31 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  EventResult : : Cancelled ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-14 19:38:00 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-10-23 17:53:02 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  node  =  dom_node_for_event_dispatch ( * paintable ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-14 19:38:00 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( paintable - > wants_mouse_events ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // FIXME: Handle double clicks.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! node ) 
							 
						 
					
						
							
								
									
										
										
										
											2024-09-12 12:56:31 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  EventResult : : Dropped ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-14 19:38:00 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( is < HTML : : HTMLIFrameElement > ( * node ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-04-26 16:59:04 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( auto  content_navigable  =  static_cast < HTML : : HTMLIFrameElement & > ( * node ) . content_navigable ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2024-12-20 15:52:47 +11:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  content_navigable - > event_handler ( ) . handle_doubleclick ( viewport_position . translated ( compute_mouse_event_offset ( { } ,  * paintable ) ) ,  screen_position ,  button ,  buttons ,  modifiers ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-09-12 12:56:31 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  EventResult : : Dropped ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-14 19:38:00 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // Search for the first parent of the hit target that's an element.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // "The topmost event target MUST be the element highest in the rendering order which is capable of being an event target." (https://www.w3.org/TR/uievents/#topmost-event-target)
 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-25 10:44:51 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    Layout : : Node *  layout_node ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-24 03:24:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! parent_element_for_event_dispatch ( * paintable ,  node ,  layout_node ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2024-09-12 12:56:31 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  EventResult : : Dropped ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-14 19:38:00 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-11-15 17:36:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  page_offset  =  compute_mouse_event_page_offset ( viewport_position ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-12-20 15:52:47 +11:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  offset  =  compute_mouse_event_offset ( page_offset ,  * layout_node - > first_paintable ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-11-15 17:36:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    node - > dispatch_event ( UIEvents : : MouseEvent : : create_from_platform_event ( node - > realm ( ) ,  UIEvents : : EventNames : : dblclick ,  screen_position ,  page_offset ,  viewport_position ,  offset ,  { } ,  button ,  buttons ,  modifiers ) . release_value_but_fixme_should_propagate_errors ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-14 19:38:00 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-06-14 21:57:29 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // NOTE: Dispatching an event may have disturbed the world.
 
							 
						 
					
						
							
								
									
										
										
										
											2023-04-20 16:01:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! paint_root ( )  | |  paint_root ( )  ! =  node - > document ( ) . paintable_box ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2024-09-12 12:56:31 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  EventResult : : Accepted ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-14 21:57:29 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-06-02 19:00:42 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( button  = =  UIEvents : : MouseButton : : Primary )  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-11-15 17:36:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( auto  result  =  paint_root ( ) - > hit_test ( viewport_position ,  Painting : : HitTestType : : TextCursor ) ;  result . has_value ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-03-18 10:25:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( ! result - > paintable - > dom_node ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2024-09-12 12:56:31 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                return  EventResult : : Accepted ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-03-18 10:25:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( ! is < Painting : : TextPaintable > ( * result - > paintable ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2024-09-12 12:56:31 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                return  EventResult : : Accepted ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-03-18 10:25:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            auto &  hit_paintable  =  static_cast < Painting : : TextPaintable  const & > ( * result - > paintable ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2025-01-21 09:12:05 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            auto &  hit_dom_node  =  const_cast < DOM : : Text & > ( as < DOM : : Text > ( * hit_paintable . dom_node ( ) ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-10-30 17:16:12 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            auto  previous_boundary  =  hit_dom_node . word_segmenter ( ) . previous_boundary ( result - > index_in_node ,  Unicode : : Segmenter : : Inclusive : : Yes ) . value_or ( 0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            auto  next_boundary  =  hit_dom_node . word_segmenter ( ) . next_boundary ( result - > index_in_node ) . value_or ( hit_dom_node . length ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-14 21:57:29 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												LibWeb: Separate text control input events handling from contenteditable
This input event handling change is intended to address the following
design issues:
- Having `DOM::Position` is unnecessary complexity when `Selection`
  exists because caret position could be described by the selection
  object with a collapsed state. Before this change, we had to
  synchronize those whenever one of them was modified, and there were
  already bugs caused by that, i.e., caret position was not changed when
  selection offset was modified from the JS side.
- Selection API exposes selection offset within `<textarea>` and
  `<input>`, which is not supposed to happen. These objects should
  manage their selection state by themselves and have selection offset
  even when they are not displayed.
- `EventHandler` looks only at `DOM::Text` owned by `DOM::Position`
  while doing text manipulations. It works fine for `<input>` and
  `<textarea>`, but `contenteditable` needs to consider all text
  descendant text nodes; i.e., if the cursor is moved outside of
  `DOM::Text`, we need to look for an adjacent text node to move the
  cursor there.
With this change, `EventHandler` no longer does direct manipulations on
caret position or text content, but instead delegates them to the active
`InputEventsTarget`, which could be either
`FormAssociatedTextControlElement` (for `<input>` and `<textarea>`) or
`EditingHostManager` (for `contenteditable`). The `Selection` object is
used to manage both selection and caret position for `contenteditable`,
and text control elements manage their own selection state that is not
exposed by Selection API.
This change improves text editing on Discord, as now we don't have to
refocus the `contenteditable` element after character input. The problem
was that selection manipulations from the JS side were not propagated
to `DOM::Position`.
I expect this change to make future correctness improvements for
`contenteditable` (and `designMode`) easier, as now it's decoupled from
`<input>` and `<textarea>` and separated from `EventHandler`, which is
quite a busy file.
											 
										 
										
											2024-10-23 21:26:58 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            auto  target  =  document . active_input_events_target ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( target )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                target - > set_selection_anchor ( hit_dom_node ,  previous_boundary ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                target - > set_selection_focus ( hit_dom_node ,  next_boundary ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            }  else  if  ( auto  selection  =  node - > document ( ) . get_selection ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2025-01-08 01:51:29 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                set_user_selection ( hit_dom_node ,  previous_boundary ,  hit_dom_node ,  next_boundary ,  selection ,  hit_paintable . layout_node ( ) . user_select_used_value ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-11 19:48:53 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-14 21:57:29 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-14 19:38:00 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-09-12 12:56:31 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    return  EventResult : : Handled ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-14 19:38:00 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-09-12 12:56:31 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								EventResult  EventHandler : : handle_drag_and_drop_event ( DragEvent : : Type  type ,  CSSPixelPoint  viewport_position ,  CSSPixelPoint  screen_position ,  u32  button ,  u32  buttons ,  u32  modifiers ,  Vector < HTML : : SelectedFile >  files )  
						 
					
						
							
								
									
										
										
										
											2024-08-17 13:29:55 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! m_navigable - > active_document ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2024-09-12 12:56:31 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  EventResult : : Dropped ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-08-17 13:29:55 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! m_navigable - > active_document ( ) - > is_fully_active ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2024-09-12 12:56:31 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  EventResult : : Dropped ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-08-17 13:29:55 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto &  document  =  * m_navigable - > active_document ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    document . update_layout ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! paint_root ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2024-09-12 12:56:31 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  EventResult : : Dropped ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-08-17 13:29:55 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-11-15 04:01:23 +13:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    GC : : Ptr < Painting : : Paintable >  paintable ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-08-17 13:29:55 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( auto  result  =  target_for_mouse_position ( viewport_position ) ;  result . has_value ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        paintable  =  result - > paintable ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    else 
							 
						 
					
						
							
								
									
										
										
										
											2024-09-12 12:56:31 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  EventResult : : Dropped ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-08-17 13:29:55 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  node  =  dom_node_for_event_dispatch ( * paintable ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! node ) 
							 
						 
					
						
							
								
									
										
										
										
											2024-09-12 12:56:31 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  EventResult : : Dropped ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-08-17 13:29:55 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( is < HTML : : HTMLIFrameElement > ( * node ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( auto  content_navigable  =  static_cast < HTML : : HTMLIFrameElement & > ( * node ) . content_navigable ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2024-12-20 15:52:47 +11:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  content_navigable - > event_handler ( ) . handle_drag_and_drop_event ( type ,  viewport_position . translated ( compute_mouse_event_offset ( { } ,  * paintable ) ) ,  screen_position ,  button ,  buttons ,  modifiers ,  move ( files ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-09-12 12:56:31 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  EventResult : : Dropped ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-08-17 13:29:55 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-11-15 17:36:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  page_offset  =  compute_mouse_event_page_offset ( viewport_position ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-12-20 15:52:47 +11:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  offset  =  compute_mouse_event_offset ( page_offset ,  * paintable ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-08-17 13:29:55 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    switch  ( type )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    case  DragEvent : : Type : : DragStart : 
							 
						 
					
						
							
								
									
										
										
										
											2024-11-15 17:36:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  m_drag_and_drop_event_handler - > handle_drag_start ( document . realm ( ) ,  screen_position ,  page_offset ,  viewport_position ,  offset ,  button ,  buttons ,  modifiers ,  move ( files ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-08-17 13:29:55 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    case  DragEvent : : Type : : DragMove : 
							 
						 
					
						
							
								
									
										
										
										
											2024-11-15 17:36:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  m_drag_and_drop_event_handler - > handle_drag_move ( document . realm ( ) ,  document ,  * node ,  screen_position ,  page_offset ,  viewport_position ,  offset ,  button ,  buttons ,  modifiers ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-08-17 13:29:55 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    case  DragEvent : : Type : : DragEnd : 
							 
						 
					
						
							
								
									
										
										
										
											2024-11-15 17:36:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  m_drag_and_drop_event_handler - > handle_drag_leave ( document . realm ( ) ,  screen_position ,  page_offset ,  viewport_position ,  offset ,  button ,  buttons ,  modifiers ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-08-17 13:29:55 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    case  DragEvent : : Type : : Drop : 
							 
						 
					
						
							
								
									
										
										
										
											2024-11-15 17:36:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  m_drag_and_drop_event_handler - > handle_drop ( document . realm ( ) ,  screen_position ,  page_offset ,  viewport_position ,  offset ,  button ,  buttons ,  modifiers ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-08-17 13:29:55 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    VERIFY_NOT_REACHED ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-08-14 19:40:37 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								bool  EventHandler : : focus_next_element ( )  
						 
					
						
							
								
									
										
										
										
											2020-08-02 12:10:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2024-04-26 16:59:04 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! m_navigable - > active_document ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-08-14 19:40:37 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  false ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-04-26 16:59:04 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! m_navigable - > active_document ( ) - > is_fully_active ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-10-03 15:35:07 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-10-09 17:06:05 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  set_focus_to_first_focusable_element  =  [ & ] ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto *  element  =  m_navigable - > active_document ( ) - > first_child_of_type < DOM : : Element > ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        for  ( ;  element ;  element  =  element - > next_element_in_pre_order ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( element - > is_focusable ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                m_navigable - > active_document ( ) - > set_focused_element ( element ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
									
										
										
										
											2020-08-14 19:40:37 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2024-10-09 17:06:05 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto *  element  =  m_navigable - > active_document ( ) - > focused_element ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! element ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  set_focus_to_first_focusable_element ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-08-14 19:40:37 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    for  ( element  =  element - > next_element_in_pre_order ( ) ;  element  & &  ! element - > is_focusable ( ) ;  element  =  element - > next_element_in_pre_order ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-10-09 17:06:05 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! element ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  set_focus_to_first_focusable_element ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-04-26 16:59:04 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    m_navigable - > active_document ( ) - > set_focused_element ( element ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-10-09 17:06:05 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    return  true ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-08-14 19:40:37 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								bool  EventHandler : : focus_previous_element ( )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2024-04-26 16:59:04 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! m_navigable - > active_document ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-08 21:23:43 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  false ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-04-26 16:59:04 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! m_navigable - > active_document ( ) - > is_fully_active ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-10-03 15:35:07 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-10-09 17:06:05 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  set_focus_to_last_focusable_element  =  [ & ] ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // FIXME: This often returns the HTML element itself, which has no previous sibling.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto *  element  =  m_navigable - > active_document ( ) - > last_child_of_type < DOM : : Element > ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        for  ( ;  element ;  element  =  element - > previous_element_in_pre_order ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( element - > is_focusable ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                m_navigable - > active_document ( ) - > set_focused_element ( element ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-08 21:23:43 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2024-10-09 17:06:05 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto *  element  =  m_navigable - > active_document ( ) - > focused_element ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! element ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  set_focus_to_last_focusable_element ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-08 21:23:43 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    for  ( element  =  element - > previous_element_in_pre_order ( ) ;  element  & &  ! element - > is_focusable ( ) ;  element  =  element - > previous_element_in_pre_order ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-10-09 17:06:05 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! element ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  set_focus_to_last_focusable_element ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-04-26 16:59:04 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    m_navigable - > active_document ( ) - > set_focused_element ( element ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-10-09 17:06:05 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    return  true ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-08-14 19:40:37 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-01-30 20:09:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								constexpr  bool  should_ignore_keydown_event ( u32  code_point ,  u32  modifiers )  
						 
					
						
							
								
									
										
										
										
											2021-05-18 13:13:58 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2024-06-06 13:29:08 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( modifiers  &  ( UIEvents : : KeyModifier : : Mod_Ctrl  |  UIEvents : : KeyModifier : : Mod_Alt  |  UIEvents : : KeyModifier : : Mod_Super ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2024-01-30 20:09:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-01 10:01:11 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // FIXME: There are probably also keys with non-zero code points that should be filtered out.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-19 22:22:45 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    return  code_point  = =  0  | |  code_point  = =  27 ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-18 13:13:58 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-10-22 15:32:42 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								EventResult  EventHandler : : fire_keyboard_event ( FlyString  const &  event_name ,  HTML : : Navigable &  navigable ,  UIEvents : : KeyCode  key ,  u32  modifiers ,  u32  code_point ,  bool  repeat )  
						 
					
						
							
								
									
										
										
										
											2022-11-05 15:36:03 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2024-11-15 04:01:23 +13:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    GC : : Ptr < DOM : : Document >  document  =  navigable . active_document ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-05 15:36:03 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! document ) 
							 
						 
					
						
							
								
									
										
										
										
											2024-09-12 12:56:31 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  EventResult : : Dropped ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-10-03 15:35:07 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! document - > is_fully_active ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2024-09-12 12:56:31 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  EventResult : : Dropped ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-05 15:36:03 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-11-15 04:01:23 +13:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( GC : : Ptr < DOM : : Element >  focused_element  =  document - > focused_element ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-12 12:20:02 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( is < HTML : : NavigableContainer > ( * focused_element ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2025-01-21 09:12:05 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            auto &  navigable_container  =  as < HTML : : NavigableContainer > ( * focused_element ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-04-26 16:59:04 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( navigable_container . content_navigable ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2024-10-22 15:32:42 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                return  fire_keyboard_event ( event_name ,  * navigable_container . content_navigable ( ) ,  key ,  modifiers ,  code_point ,  repeat ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-05 15:36:03 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-10-22 15:32:42 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto  event  =  UIEvents : : KeyboardEvent : : create_from_platform_event ( document - > realm ( ) ,  event_name ,  key ,  modifiers ,  code_point ,  repeat ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-09-12 12:56:31 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  focused_element - > dispatch_event ( event )  ?  EventResult : : Accepted  :  EventResult : : Cancelled ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-05 15:36:03 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-11-09 10:56:12 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // FIXME: De-duplicate this. This is just to prevent wasting a KeyboardEvent allocation when recursing into an (i)frame.
 
							 
						 
					
						
							
								
									
										
										
										
											2024-10-22 15:32:42 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  event  =  UIEvents : : KeyboardEvent : : create_from_platform_event ( document - > realm ( ) ,  event_name ,  key ,  modifiers ,  code_point ,  repeat ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-05 15:36:03 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-11-15 04:01:23 +13:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    GC : : Ptr  target  =  document - > body ( )  ? :  & document - > root ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-09-12 12:56:31 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    return  target - > dispatch_event ( event )  ?  EventResult : : Accepted  :  EventResult : : Cancelled ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-05 15:36:03 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-10-08 17:15:55 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								// https://w3c.github.io/uievents/#unicode-character-categories
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								static  bool  produces_character_value ( u32  code_point )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // A subset of the General Category values that are defined for each Unicode code point. This subset contains all
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // the Letter (Ll, Lm, Lo, Lt, Lu), Number (Nd, Nl, No), Punctuation (Pc, Pd, Pe, Pf, Pi, Po, Ps) and Symbol (Sc,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // Sk, Sm, So) category values.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  Unicode : : code_point_has_letter_general_category ( code_point ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        | |  Unicode : : code_point_has_number_general_category ( code_point ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        | |  Unicode : : code_point_has_punctuation_general_category ( code_point ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        | |  Unicode : : code_point_has_symbol_general_category ( code_point ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2025-01-24 16:25:59 +09:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								// https://github.com/w3c/uievents/issues/183#issuecomment-448091687
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								static  bool  is_enter_key_or_interoperable_enter_key_combo ( UIEvents : : KeyCode  key ,  u32  modifiers )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( key  ! =  UIEvents : : KeyCode : : Key_Return ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! modifiers ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( modifiers  &  ( UIEvents : : KeyModifier : : Mod_Shift  |  UIEvents : : KeyModifier : : Mod_Ctrl ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-02-24 06:08:26 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								EventResult  EventHandler : : input_event ( FlyString  const &  event_name ,  FlyString  const &  input_type ,  HTML : : Navigable &  navigable ,  u32  code_point )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  document  =  navigable . active_document ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! document ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  EventResult : : Dropped ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! document - > is_fully_active ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  EventResult : : Dropped ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    UIEvents : : InputEventInit  input_event_init ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! is_unicode_control ( code_point ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        input_event_init . data  =  String : : from_code_point ( code_point ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    input_event_init . input_type  =  input_type ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( auto *  focused_element  =  document - > focused_element ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( is < HTML : : NavigableContainer > ( * focused_element ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2025-01-21 09:12:05 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            auto &  navigable_container  =  as < HTML : : NavigableContainer > ( * focused_element ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-02-24 06:08:26 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( navigable_container . content_navigable ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  input_event ( event_name ,  input_type ,  * navigable_container . content_navigable ( ) ,  code_point ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  event  =  UIEvents : : InputEvent : : create_from_platform_event ( document - > realm ( ) ,  event_name ,  input_event_init ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  focused_element - > dispatch_event ( event )  ?  EventResult : : Accepted  :  EventResult : : Cancelled ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  event  =  UIEvents : : InputEvent : : create_from_platform_event ( document - > realm ( ) ,  event_name ,  input_event_init ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( auto *  body  =  document - > body ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  body - > dispatch_event ( event )  ?  EventResult : : Accepted  :  EventResult : : Cancelled ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  document - > root ( ) . dispatch_event ( event )  ?  EventResult : : Accepted  :  EventResult : : Cancelled ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-10-22 15:32:42 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								EventResult  EventHandler : : handle_keydown ( UIEvents : : KeyCode  key ,  u32  modifiers ,  u32  code_point ,  bool  repeat )  
						 
					
						
							
								
									
										
										
										
											2020-08-14 19:40:37 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2024-04-26 16:59:04 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! m_navigable - > active_document ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2024-09-12 12:56:31 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  EventResult : : Dropped ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-04-26 16:59:04 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! m_navigable - > active_document ( ) - > is_fully_active ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2024-09-12 12:56:31 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  EventResult : : Dropped ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-12 14:44:00 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-10-22 15:32:42 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  dispatch_result  =  fire_keyboard_event ( UIEvents : : EventNames : : keydown ,  m_navigable ,  key ,  modifiers ,  code_point ,  repeat ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-10-09 07:39:08 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( dispatch_result  ! =  EventResult : : Accepted ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  dispatch_result ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-10-08 17:15:55 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // https://w3c.github.io/uievents/#event-type-keypress
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // If supported by a user agent, this event MUST be dispatched when a key is pressed down, if and only if that key
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // normally produces a character value.
 
							 
						 
					
						
							
								
									
										
										
										
											2025-01-24 16:25:59 +09:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // AD-HOC: For web compat and for interop with other engines, we make an exception here for the Enter key. See:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    //         https://github.com/w3c/uievents/issues/183#issuecomment-448091687 and
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    //         https://github.com/w3c/uievents/issues/266#issuecomment-1887917756
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( produces_character_value ( code_point )  | |  is_enter_key_or_interoperable_enter_key_combo ( key ,  modifiers ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-10-22 15:32:42 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        dispatch_result  =  fire_keyboard_event ( UIEvents : : EventNames : : keypress ,  m_navigable ,  key ,  modifiers ,  code_point ,  repeat ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-10-08 17:15:55 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( dispatch_result  ! =  EventResult : : Accepted ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  dispatch_result ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2024-10-09 07:39:08 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-11-15 04:01:23 +13:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    GC : : Ref < DOM : : Document >  document  =  * m_navigable - > active_document ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-12 14:44:00 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-06-06 13:29:08 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( key  = =  UIEvents : : KeyCode : : Key_Tab )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( modifiers  &  UIEvents : : KeyModifier : : Mod_Shift ) 
							 
						 
					
						
							
								
									
										
										
										
											2024-09-12 12:56:31 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  focus_previous_element ( )  ?  EventResult : : Handled  :  EventResult : : Dropped ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  focus_next_element ( )  ?  EventResult : : Handled  :  EventResult : : Dropped ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-08-14 19:40:37 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-08-19 22:50:55 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // https://html.spec.whatwg.org/multipage/interaction.html#close-requests
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( key  = =  UIEvents : : KeyCode : : Key_Escape )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // 7. Let closedSomething be the result of processing close watchers on document's relevant global object.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  closed_something  =  document - > window ( ) - > close_watcher_manager ( ) - > process_close_watchers ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // 8. If closedSomething is true, then return.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( closed_something ) 
							 
						 
					
						
							
								
									
										
										
										
											2024-09-12 12:56:31 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  EventResult : : Handled ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-08-19 22:50:55 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // 9. Alternative processing: Otherwise, there was nothing watching for a close request. The user agent may
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        //    instead interpret this interaction as some other action, instead of interpreting it as a close request.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2024-06-21 22:53:05 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-04-26 16:59:04 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( auto *  element  =  m_navigable - > active_document ( ) - > focused_element ( ) ;  is < HTML : : HTMLMediaElement > ( element ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-07-02 21:40:46 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto &  media_element  =  static_cast < HTML : : HTMLMediaElement & > ( * element ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-09-04 04:30:44 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( media_element . handle_keydown ( { } ,  key ,  modifiers ) . release_value_but_fixme_should_propagate_errors ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2024-09-12 12:56:31 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  EventResult : : Handled ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-07-02 21:40:46 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												LibWeb: Separate text control input events handling from contenteditable
This input event handling change is intended to address the following
design issues:
- Having `DOM::Position` is unnecessary complexity when `Selection`
  exists because caret position could be described by the selection
  object with a collapsed state. Before this change, we had to
  synchronize those whenever one of them was modified, and there were
  already bugs caused by that, i.e., caret position was not changed when
  selection offset was modified from the JS side.
- Selection API exposes selection offset within `<textarea>` and
  `<input>`, which is not supposed to happen. These objects should
  manage their selection state by themselves and have selection offset
  even when they are not displayed.
- `EventHandler` looks only at `DOM::Text` owned by `DOM::Position`
  while doing text manipulations. It works fine for `<input>` and
  `<textarea>`, but `contenteditable` needs to consider all text
  descendant text nodes; i.e., if the cursor is moved outside of
  `DOM::Text`, we need to look for an adjacent text node to move the
  cursor there.
With this change, `EventHandler` no longer does direct manipulations on
caret position or text content, but instead delegates them to the active
`InputEventsTarget`, which could be either
`FormAssociatedTextControlElement` (for `<input>` and `<textarea>`) or
`EditingHostManager` (for `contenteditable`). The `Selection` object is
used to manage both selection and caret position for `contenteditable`,
and text control elements manage their own selection state that is not
exposed by Selection API.
This change improves text editing on Discord, as now we don't have to
refocus the `contenteditable` element after character input. The problem
was that selection manipulations from the JS side were not propagated
to `DOM::Position`.
I expect this change to make future correctness improvements for
`contenteditable` (and `designMode`) easier, as now it's decoupled from
`<input>` and `<textarea>` and separated from `EventHandler`, which is
quite a busy file.
											 
										 
										
											2024-10-23 21:26:58 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto *  target  =  document - > active_input_events_target ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( target )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( key  = =  UIEvents : : KeyCode : : Key_Backspace )  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-10-20 21:54:32 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            FIRE ( input_event ( UIEvents : : EventNames : : beforeinput ,  UIEvents : : InputTypes : : deleteContentBackward ,  m_navigable ,  code_point ) ) ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												LibWeb: Separate text control input events handling from contenteditable
This input event handling change is intended to address the following
design issues:
- Having `DOM::Position` is unnecessary complexity when `Selection`
  exists because caret position could be described by the selection
  object with a collapsed state. Before this change, we had to
  synchronize those whenever one of them was modified, and there were
  already bugs caused by that, i.e., caret position was not changed when
  selection offset was modified from the JS side.
- Selection API exposes selection offset within `<textarea>` and
  `<input>`, which is not supposed to happen. These objects should
  manage their selection state by themselves and have selection offset
  even when they are not displayed.
- `EventHandler` looks only at `DOM::Text` owned by `DOM::Position`
  while doing text manipulations. It works fine for `<input>` and
  `<textarea>`, but `contenteditable` needs to consider all text
  descendant text nodes; i.e., if the cursor is moved outside of
  `DOM::Text`, we need to look for an adjacent text node to move the
  cursor there.
With this change, `EventHandler` no longer does direct manipulations on
caret position or text content, but instead delegates them to the active
`InputEventsTarget`, which could be either
`FormAssociatedTextControlElement` (for `<input>` and `<textarea>`) or
`EditingHostManager` (for `contenteditable`). The `Selection` object is
used to manage both selection and caret position for `contenteditable`,
and text control elements manage their own selection state that is not
exposed by Selection API.
This change improves text editing on Discord, as now we don't have to
refocus the `contenteditable` element after character input. The problem
was that selection manipulations from the JS side were not propagated
to `DOM::Position`.
I expect this change to make future correctness improvements for
`contenteditable` (and `designMode`) easier, as now it's decoupled from
`<input>` and `<textarea>` and separated from `EventHandler`, which is
quite a busy file.
											 
										 
										
											2024-10-23 21:26:58 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            target - > handle_delete ( InputEventsTarget : : DeleteDirection : : Backward ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-02-24 06:08:26 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            FIRE ( input_event ( UIEvents : : EventNames : : input ,  UIEvents : : InputTypes : : deleteContentBackward ,  m_navigable ,  code_point ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-09-12 12:56:31 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  EventResult : : Handled ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-12 14:44:52 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2024-09-07 17:56:32 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												LibWeb: Separate text control input events handling from contenteditable
This input event handling change is intended to address the following
design issues:
- Having `DOM::Position` is unnecessary complexity when `Selection`
  exists because caret position could be described by the selection
  object with a collapsed state. Before this change, we had to
  synchronize those whenever one of them was modified, and there were
  already bugs caused by that, i.e., caret position was not changed when
  selection offset was modified from the JS side.
- Selection API exposes selection offset within `<textarea>` and
  `<input>`, which is not supposed to happen. These objects should
  manage their selection state by themselves and have selection offset
  even when they are not displayed.
- `EventHandler` looks only at `DOM::Text` owned by `DOM::Position`
  while doing text manipulations. It works fine for `<input>` and
  `<textarea>`, but `contenteditable` needs to consider all text
  descendant text nodes; i.e., if the cursor is moved outside of
  `DOM::Text`, we need to look for an adjacent text node to move the
  cursor there.
With this change, `EventHandler` no longer does direct manipulations on
caret position or text content, but instead delegates them to the active
`InputEventsTarget`, which could be either
`FormAssociatedTextControlElement` (for `<input>` and `<textarea>`) or
`EditingHostManager` (for `contenteditable`). The `Selection` object is
used to manage both selection and caret position for `contenteditable`,
and text control elements manage their own selection state that is not
exposed by Selection API.
This change improves text editing on Discord, as now we don't have to
refocus the `contenteditable` element after character input. The problem
was that selection manipulations from the JS side were not propagated
to `DOM::Position`.
I expect this change to make future correctness improvements for
`contenteditable` (and `designMode`) easier, as now it's decoupled from
`<input>` and `<textarea>` and separated from `EventHandler`, which is
quite a busy file.
											 
										 
										
											2024-10-23 21:26:58 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( key  = =  UIEvents : : KeyCode : : Key_Delete )  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-10-20 21:54:32 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            FIRE ( input_event ( UIEvents : : EventNames : : beforeinput ,  UIEvents : : InputTypes : : deleteContentForward ,  m_navigable ,  code_point ) ) ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												LibWeb: Separate text control input events handling from contenteditable
This input event handling change is intended to address the following
design issues:
- Having `DOM::Position` is unnecessary complexity when `Selection`
  exists because caret position could be described by the selection
  object with a collapsed state. Before this change, we had to
  synchronize those whenever one of them was modified, and there were
  already bugs caused by that, i.e., caret position was not changed when
  selection offset was modified from the JS side.
- Selection API exposes selection offset within `<textarea>` and
  `<input>`, which is not supposed to happen. These objects should
  manage their selection state by themselves and have selection offset
  even when they are not displayed.
- `EventHandler` looks only at `DOM::Text` owned by `DOM::Position`
  while doing text manipulations. It works fine for `<input>` and
  `<textarea>`, but `contenteditable` needs to consider all text
  descendant text nodes; i.e., if the cursor is moved outside of
  `DOM::Text`, we need to look for an adjacent text node to move the
  cursor there.
With this change, `EventHandler` no longer does direct manipulations on
caret position or text content, but instead delegates them to the active
`InputEventsTarget`, which could be either
`FormAssociatedTextControlElement` (for `<input>` and `<textarea>`) or
`EditingHostManager` (for `contenteditable`). The `Selection` object is
used to manage both selection and caret position for `contenteditable`,
and text control elements manage their own selection state that is not
exposed by Selection API.
This change improves text editing on Discord, as now we don't have to
refocus the `contenteditable` element after character input. The problem
was that selection manipulations from the JS side were not propagated
to `DOM::Position`.
I expect this change to make future correctness improvements for
`contenteditable` (and `designMode`) easier, as now it's decoupled from
`<input>` and `<textarea>` and separated from `EventHandler`, which is
quite a busy file.
											 
										 
										
											2024-10-23 21:26:58 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            target - > handle_delete ( InputEventsTarget : : DeleteDirection : : Forward ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-02-24 06:08:26 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            FIRE ( input_event ( UIEvents : : EventNames : : input ,  UIEvents : : InputTypes : : deleteContentForward ,  m_navigable ,  code_point ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-09-12 12:56:31 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  EventResult : : Handled ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-12 14:44:52 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2024-09-04 20:03:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-09-05 12:43:07 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# if defined(AK_OS_MACOS) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ( modifiers  &  UIEvents : : Mod_Super )  ! =  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( key  = =  UIEvents : : KeyCode : : Key_Left )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                key  =  UIEvents : : KeyCode : : Key_Home ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                modifiers  & =  ~ UIEvents : : Mod_Super ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( key  = =  UIEvents : : KeyCode : : Key_Right )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                key  =  UIEvents : : KeyCode : : Key_End ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                modifiers  & =  ~ UIEvents : : Mod_Super ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								# endif 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-09-04 20:03:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( key  = =  UIEvents : : KeyCode : : Key_Left  | |  key  = =  UIEvents : : KeyCode : : Key_Right )  { 
							 
						 
					
						
							
								
									
										
											 
										
											
												LibWeb: Separate text control input events handling from contenteditable
This input event handling change is intended to address the following
design issues:
- Having `DOM::Position` is unnecessary complexity when `Selection`
  exists because caret position could be described by the selection
  object with a collapsed state. Before this change, we had to
  synchronize those whenever one of them was modified, and there were
  already bugs caused by that, i.e., caret position was not changed when
  selection offset was modified from the JS side.
- Selection API exposes selection offset within `<textarea>` and
  `<input>`, which is not supposed to happen. These objects should
  manage their selection state by themselves and have selection offset
  even when they are not displayed.
- `EventHandler` looks only at `DOM::Text` owned by `DOM::Position`
  while doing text manipulations. It works fine for `<input>` and
  `<textarea>`, but `contenteditable` needs to consider all text
  descendant text nodes; i.e., if the cursor is moved outside of
  `DOM::Text`, we need to look for an adjacent text node to move the
  cursor there.
With this change, `EventHandler` no longer does direct manipulations on
caret position or text content, but instead delegates them to the active
`InputEventsTarget`, which could be either
`FormAssociatedTextControlElement` (for `<input>` and `<textarea>`) or
`EditingHostManager` (for `contenteditable`). The `Selection` object is
used to manage both selection and caret position for `contenteditable`,
and text control elements manage their own selection state that is not
exposed by Selection API.
This change improves text editing on Discord, as now we don't have to
refocus the `contenteditable` element after character input. The problem
was that selection manipulations from the JS side were not propagated
to `DOM::Position`.
I expect this change to make future correctness improvements for
`contenteditable` (and `designMode`) easier, as now it's decoupled from
`<input>` and `<textarea>` and separated from `EventHandler`, which is
quite a busy file.
											 
										 
										
											2024-10-23 21:26:58 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            auto  collapse  =  modifiers  &  UIEvents : : Mod_Shift  ?  InputEventsTarget : : CollapseSelection : : No  :  InputEventsTarget : : CollapseSelection : : Yes ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( ( modifiers  &  UIEvents : : Mod_PlatformWordJump )  = =  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                if  ( key  = =  UIEvents : : KeyCode : : Key_Left )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    target - > decrement_cursor_position_offset ( collapse ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    target - > increment_cursor_position_offset ( collapse ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-09-04 20:03:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                } 
							 
						 
					
						
							
								
									
										
											 
										
											
												LibWeb: Separate text control input events handling from contenteditable
This input event handling change is intended to address the following
design issues:
- Having `DOM::Position` is unnecessary complexity when `Selection`
  exists because caret position could be described by the selection
  object with a collapsed state. Before this change, we had to
  synchronize those whenever one of them was modified, and there were
  already bugs caused by that, i.e., caret position was not changed when
  selection offset was modified from the JS side.
- Selection API exposes selection offset within `<textarea>` and
  `<input>`, which is not supposed to happen. These objects should
  manage their selection state by themselves and have selection offset
  even when they are not displayed.
- `EventHandler` looks only at `DOM::Text` owned by `DOM::Position`
  while doing text manipulations. It works fine for `<input>` and
  `<textarea>`, but `contenteditable` needs to consider all text
  descendant text nodes; i.e., if the cursor is moved outside of
  `DOM::Text`, we need to look for an adjacent text node to move the
  cursor there.
With this change, `EventHandler` no longer does direct manipulations on
caret position or text content, but instead delegates them to the active
`InputEventsTarget`, which could be either
`FormAssociatedTextControlElement` (for `<input>` and `<textarea>`) or
`EditingHostManager` (for `contenteditable`). The `Selection` object is
used to manage both selection and caret position for `contenteditable`,
and text control elements manage their own selection state that is not
exposed by Selection API.
This change improves text editing on Discord, as now we don't have to
refocus the `contenteditable` element after character input. The problem
was that selection manipulations from the JS side were not propagated
to `DOM::Position`.
I expect this change to make future correctness improvements for
`contenteditable` (and `designMode`) easier, as now it's decoupled from
`<input>` and `<textarea>` and separated from `EventHandler`, which is
quite a busy file.
											 
										 
										
											2024-10-23 21:26:58 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                if  ( key  = =  UIEvents : : KeyCode : : Key_Left )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    target - > decrement_cursor_position_to_previous_word ( collapse ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-09-07 17:56:32 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                }  else  { 
							 
						 
					
						
							
								
									
										
											 
										
											
												LibWeb: Separate text control input events handling from contenteditable
This input event handling change is intended to address the following
design issues:
- Having `DOM::Position` is unnecessary complexity when `Selection`
  exists because caret position could be described by the selection
  object with a collapsed state. Before this change, we had to
  synchronize those whenever one of them was modified, and there were
  already bugs caused by that, i.e., caret position was not changed when
  selection offset was modified from the JS side.
- Selection API exposes selection offset within `<textarea>` and
  `<input>`, which is not supposed to happen. These objects should
  manage their selection state by themselves and have selection offset
  even when they are not displayed.
- `EventHandler` looks only at `DOM::Text` owned by `DOM::Position`
  while doing text manipulations. It works fine for `<input>` and
  `<textarea>`, but `contenteditable` needs to consider all text
  descendant text nodes; i.e., if the cursor is moved outside of
  `DOM::Text`, we need to look for an adjacent text node to move the
  cursor there.
With this change, `EventHandler` no longer does direct manipulations on
caret position or text content, but instead delegates them to the active
`InputEventsTarget`, which could be either
`FormAssociatedTextControlElement` (for `<input>` and `<textarea>`) or
`EditingHostManager` (for `contenteditable`). The `Selection` object is
used to manage both selection and caret position for `contenteditable`,
and text control elements manage their own selection state that is not
exposed by Selection API.
This change improves text editing on Discord, as now we don't have to
refocus the `contenteditable` element after character input. The problem
was that selection manipulations from the JS side were not propagated
to `DOM::Position`.
I expect this change to make future correctness improvements for
`contenteditable` (and `designMode`) easier, as now it's decoupled from
`<input>` and `<textarea>` and separated from `EventHandler`, which is
quite a busy file.
											 
										 
										
											2024-10-23 21:26:58 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                    target - > increment_cursor_position_to_next_word ( collapse ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-09-07 17:56:32 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                } 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-18 13:08:25 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
									
										
										
										
											2024-09-12 12:56:31 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  EventResult : : Handled ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-12 14:44:52 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2024-09-04 20:03:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												LibWeb: Separate text control input events handling from contenteditable
This input event handling change is intended to address the following
design issues:
- Having `DOM::Position` is unnecessary complexity when `Selection`
  exists because caret position could be described by the selection
  object with a collapsed state. Before this change, we had to
  synchronize those whenever one of them was modified, and there were
  already bugs caused by that, i.e., caret position was not changed when
  selection offset was modified from the JS side.
- Selection API exposes selection offset within `<textarea>` and
  `<input>`, which is not supposed to happen. These objects should
  manage their selection state by themselves and have selection offset
  even when they are not displayed.
- `EventHandler` looks only at `DOM::Text` owned by `DOM::Position`
  while doing text manipulations. It works fine for `<input>` and
  `<textarea>`, but `contenteditable` needs to consider all text
  descendant text nodes; i.e., if the cursor is moved outside of
  `DOM::Text`, we need to look for an adjacent text node to move the
  cursor there.
With this change, `EventHandler` no longer does direct manipulations on
caret position or text content, but instead delegates them to the active
`InputEventsTarget`, which could be either
`FormAssociatedTextControlElement` (for `<input>` and `<textarea>`) or
`EditingHostManager` (for `contenteditable`). The `Selection` object is
used to manage both selection and caret position for `contenteditable`,
and text control elements manage their own selection state that is not
exposed by Selection API.
This change improves text editing on Discord, as now we don't have to
refocus the `contenteditable` element after character input. The problem
was that selection manipulations from the JS side were not propagated
to `DOM::Position`.
I expect this change to make future correctness improvements for
`contenteditable` (and `designMode`) easier, as now it's decoupled from
`<input>` and `<textarea>` and separated from `EventHandler`, which is
quite a busy file.
											 
										 
										
											2024-10-23 21:26:58 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( key  = =  UIEvents : : KeyCode : : Key_Home )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            auto  collapse  =  modifiers  &  UIEvents : : Mod_Shift  ?  InputEventsTarget : : CollapseSelection : : No  :  InputEventsTarget : : CollapseSelection : : Yes ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            target - > move_cursor_to_start ( collapse ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  EventResult : : Handled ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2024-09-04 20:03:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												LibWeb: Separate text control input events handling from contenteditable
This input event handling change is intended to address the following
design issues:
- Having `DOM::Position` is unnecessary complexity when `Selection`
  exists because caret position could be described by the selection
  object with a collapsed state. Before this change, we had to
  synchronize those whenever one of them was modified, and there were
  already bugs caused by that, i.e., caret position was not changed when
  selection offset was modified from the JS side.
- Selection API exposes selection offset within `<textarea>` and
  `<input>`, which is not supposed to happen. These objects should
  manage their selection state by themselves and have selection offset
  even when they are not displayed.
- `EventHandler` looks only at `DOM::Text` owned by `DOM::Position`
  while doing text manipulations. It works fine for `<input>` and
  `<textarea>`, but `contenteditable` needs to consider all text
  descendant text nodes; i.e., if the cursor is moved outside of
  `DOM::Text`, we need to look for an adjacent text node to move the
  cursor there.
With this change, `EventHandler` no longer does direct manipulations on
caret position or text content, but instead delegates them to the active
`InputEventsTarget`, which could be either
`FormAssociatedTextControlElement` (for `<input>` and `<textarea>`) or
`EditingHostManager` (for `contenteditable`). The `Selection` object is
used to manage both selection and caret position for `contenteditable`,
and text control elements manage their own selection state that is not
exposed by Selection API.
This change improves text editing on Discord, as now we don't have to
refocus the `contenteditable` element after character input. The problem
was that selection manipulations from the JS side were not propagated
to `DOM::Position`.
I expect this change to make future correctness improvements for
`contenteditable` (and `designMode`) easier, as now it's decoupled from
`<input>` and `<textarea>` and separated from `EventHandler`, which is
quite a busy file.
											 
										 
										
											2024-10-23 21:26:58 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( key  = =  UIEvents : : KeyCode : : Key_End )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            auto  collapse  =  modifiers  &  UIEvents : : Mod_Shift  ?  InputEventsTarget : : CollapseSelection : : No  :  InputEventsTarget : : CollapseSelection : : Yes ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            target - > move_cursor_to_end ( collapse ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-09-12 12:56:31 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  EventResult : : Handled ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-19 18:42:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2024-09-04 20:03:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												LibWeb: Separate text control input events handling from contenteditable
This input event handling change is intended to address the following
design issues:
- Having `DOM::Position` is unnecessary complexity when `Selection`
  exists because caret position could be described by the selection
  object with a collapsed state. Before this change, we had to
  synchronize those whenever one of them was modified, and there were
  already bugs caused by that, i.e., caret position was not changed when
  selection offset was modified from the JS side.
- Selection API exposes selection offset within `<textarea>` and
  `<input>`, which is not supposed to happen. These objects should
  manage their selection state by themselves and have selection offset
  even when they are not displayed.
- `EventHandler` looks only at `DOM::Text` owned by `DOM::Position`
  while doing text manipulations. It works fine for `<input>` and
  `<textarea>`, but `contenteditable` needs to consider all text
  descendant text nodes; i.e., if the cursor is moved outside of
  `DOM::Text`, we need to look for an adjacent text node to move the
  cursor there.
With this change, `EventHandler` no longer does direct manipulations on
caret position or text content, but instead delegates them to the active
`InputEventsTarget`, which could be either
`FormAssociatedTextControlElement` (for `<input>` and `<textarea>`) or
`EditingHostManager` (for `contenteditable`). The `Selection` object is
used to manage both selection and caret position for `contenteditable`,
and text control elements manage their own selection state that is not
exposed by Selection API.
This change improves text editing on Discord, as now we don't have to
refocus the `contenteditable` element after character input. The problem
was that selection manipulations from the JS side were not propagated
to `DOM::Position`.
I expect this change to make future correctness improvements for
`contenteditable` (and `designMode`) easier, as now it's decoupled from
`<input>` and `<textarea>` and separated from `EventHandler`, which is
quite a busy file.
											 
										 
										
											2024-10-23 21:26:58 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( key  = =  UIEvents : : KeyCode : : Key_Return )  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-10-20 21:54:32 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            FIRE ( input_event ( UIEvents : : EventNames : : beforeinput ,  UIEvents : : InputTypes : : insertParagraph ,  m_navigable ,  code_point ) ) ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												LibWeb: Separate text control input events handling from contenteditable
This input event handling change is intended to address the following
design issues:
- Having `DOM::Position` is unnecessary complexity when `Selection`
  exists because caret position could be described by the selection
  object with a collapsed state. Before this change, we had to
  synchronize those whenever one of them was modified, and there were
  already bugs caused by that, i.e., caret position was not changed when
  selection offset was modified from the JS side.
- Selection API exposes selection offset within `<textarea>` and
  `<input>`, which is not supposed to happen. These objects should
  manage their selection state by themselves and have selection offset
  even when they are not displayed.
- `EventHandler` looks only at `DOM::Text` owned by `DOM::Position`
  while doing text manipulations. It works fine for `<input>` and
  `<textarea>`, but `contenteditable` needs to consider all text
  descendant text nodes; i.e., if the cursor is moved outside of
  `DOM::Text`, we need to look for an adjacent text node to move the
  cursor there.
With this change, `EventHandler` no longer does direct manipulations on
caret position or text content, but instead delegates them to the active
`InputEventsTarget`, which could be either
`FormAssociatedTextControlElement` (for `<input>` and `<textarea>`) or
`EditingHostManager` (for `contenteditable`). The `Selection` object is
used to manage both selection and caret position for `contenteditable`,
and text control elements manage their own selection state that is not
exposed by Selection API.
This change improves text editing on Discord, as now we don't have to
refocus the `contenteditable` element after character input. The problem
was that selection manipulations from the JS side were not propagated
to `DOM::Position`.
I expect this change to make future correctness improvements for
`contenteditable` (and `designMode`) easier, as now it's decoupled from
`<input>` and `<textarea>` and separated from `EventHandler`, which is
quite a busy file.
											 
										 
										
											2024-10-23 21:26:58 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            target - > handle_return_key ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-02-24 06:08:26 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            FIRE ( input_event ( UIEvents : : EventNames : : input ,  UIEvents : : InputTypes : : insertParagraph ,  m_navigable ,  code_point ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-11-30 12:54:30 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2024-09-04 20:03:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-01-30 20:09:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        // FIXME: Text editing shortcut keys (copy/paste etc.) should be handled here.
 
							 
						 
					
						
							
								
									
										
											 
										
											
												LibWeb: Separate text control input events handling from contenteditable
This input event handling change is intended to address the following
design issues:
- Having `DOM::Position` is unnecessary complexity when `Selection`
  exists because caret position could be described by the selection
  object with a collapsed state. Before this change, we had to
  synchronize those whenever one of them was modified, and there were
  already bugs caused by that, i.e., caret position was not changed when
  selection offset was modified from the JS side.
- Selection API exposes selection offset within `<textarea>` and
  `<input>`, which is not supposed to happen. These objects should
  manage their selection state by themselves and have selection offset
  even when they are not displayed.
- `EventHandler` looks only at `DOM::Text` owned by `DOM::Position`
  while doing text manipulations. It works fine for `<input>` and
  `<textarea>`, but `contenteditable` needs to consider all text
  descendant text nodes; i.e., if the cursor is moved outside of
  `DOM::Text`, we need to look for an adjacent text node to move the
  cursor there.
With this change, `EventHandler` no longer does direct manipulations on
caret position or text content, but instead delegates them to the active
`InputEventsTarget`, which could be either
`FormAssociatedTextControlElement` (for `<input>` and `<textarea>`) or
`EditingHostManager` (for `contenteditable`). The `Selection` object is
used to manage both selection and caret position for `contenteditable`,
and text control elements manage their own selection state that is not
exposed by Selection API.
This change improves text editing on Discord, as now we don't have to
refocus the `contenteditable` element after character input. The problem
was that selection manipulations from the JS side were not propagated
to `DOM::Position`.
I expect this change to make future correctness improvements for
`contenteditable` (and `designMode`) easier, as now it's decoupled from
`<input>` and `<textarea>` and separated from `EventHandler`, which is
quite a busy file.
											 
										 
										
											2024-10-23 21:26:58 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! should_ignore_keydown_event ( code_point ,  modifiers ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-10-20 21:54:32 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            FIRE ( input_event ( UIEvents : : EventNames : : beforeinput ,  UIEvents : : InputTypes : : insertText ,  m_navigable ,  code_point ) ) ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												LibWeb: Separate text control input events handling from contenteditable
This input event handling change is intended to address the following
design issues:
- Having `DOM::Position` is unnecessary complexity when `Selection`
  exists because caret position could be described by the selection
  object with a collapsed state. Before this change, we had to
  synchronize those whenever one of them was modified, and there were
  already bugs caused by that, i.e., caret position was not changed when
  selection offset was modified from the JS side.
- Selection API exposes selection offset within `<textarea>` and
  `<input>`, which is not supposed to happen. These objects should
  manage their selection state by themselves and have selection offset
  even when they are not displayed.
- `EventHandler` looks only at `DOM::Text` owned by `DOM::Position`
  while doing text manipulations. It works fine for `<input>` and
  `<textarea>`, but `contenteditable` needs to consider all text
  descendant text nodes; i.e., if the cursor is moved outside of
  `DOM::Text`, we need to look for an adjacent text node to move the
  cursor there.
With this change, `EventHandler` no longer does direct manipulations on
caret position or text content, but instead delegates them to the active
`InputEventsTarget`, which could be either
`FormAssociatedTextControlElement` (for `<input>` and `<textarea>`) or
`EditingHostManager` (for `contenteditable`). The `Selection` object is
used to manage both selection and caret position for `contenteditable`,
and text control elements manage their own selection state that is not
exposed by Selection API.
This change improves text editing on Discord, as now we don't have to
refocus the `contenteditable` element after character input. The problem
was that selection manipulations from the JS side were not propagated
to `DOM::Position`.
I expect this change to make future correctness improvements for
`contenteditable` (and `designMode`) easier, as now it's decoupled from
`<input>` and `<textarea>` and separated from `EventHandler`, which is
quite a busy file.
											 
										 
										
											2024-10-23 21:26:58 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            target - > handle_insert ( String : : from_code_point ( code_point ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-02-24 06:08:26 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            FIRE ( input_event ( UIEvents : : EventNames : : input ,  UIEvents : : InputTypes : : insertText ,  m_navigable ,  code_point ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-09-12 12:56:31 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  EventResult : : Handled ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-08-02 16:05:59 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2024-11-01 16:34:28 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    }  else  if  ( auto  selection  =  document - > get_selection ( ) ;  selection  & &  ! selection - > is_collapsed ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( modifiers  &  UIEvents : : Mod_Shift )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( key  = =  UIEvents : : KeyCode : : Key_Right )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                if  ( modifiers  &  UIEvents : : Mod_PlatformWordJump ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    selection - > move_offset_to_next_word ( false ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    selection - > move_offset_to_next_character ( false ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  EventResult : : Handled ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            }  else  if  ( key  = =  UIEvents : : KeyCode : : Key_Left )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                if  ( modifiers  &  UIEvents : : Mod_PlatformWordJump ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    selection - > move_offset_to_previous_word ( false ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    selection - > move_offset_to_previous_character ( false ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  EventResult : : Handled ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2020-08-02 12:10:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-01 23:35:47 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-07-01 16:03:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // FIXME: Implement scroll by line and by page instead of approximating the behavior of other browsers.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  arrow_key_scroll_distance  =  100 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  page_scroll_distance  =  document - > window ( ) - > inner_height ( )  -  ( document - > window ( ) - > outer_height ( )  -  document - > window ( ) - > inner_height ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    switch  ( key )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    case  UIEvents : : KeyCode : : Key_Up : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    case  UIEvents : : KeyCode : : Key_Down : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( modifiers  & &  modifiers  ! =  UIEvents : : KeyModifier : : Mod_Ctrl ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( modifiers ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            key  = =  UIEvents : : KeyCode : : Key_Up  ?  document - > scroll_to_the_beginning_of_the_document ( )  :  document - > window ( ) - > scroll_by ( 0 ,  INT64_MAX ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            document - > window ( ) - > scroll_by ( 0 ,  key  = =  UIEvents : : KeyCode : : Key_Up  ?  - arrow_key_scroll_distance  :  arrow_key_scroll_distance ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-09-12 12:56:31 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  EventResult : : Handled ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-07-01 16:03:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    case  UIEvents : : KeyCode : : Key_Left : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    case  UIEvents : : KeyCode : : Key_Right : 
							 
						 
					
						
							
								
									
										
										
										
											2024-10-09 08:56:55 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( modifiers  & &  modifiers  ! =  UIEvents : : KeyModifier : : Mod_Alt ) 
							 
						 
					
						
							
								
									
										
										
										
											2024-07-01 16:03:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( modifiers ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            document - > page ( ) . traverse_the_history_by_delta ( key  = =  UIEvents : : KeyCode : : Key_Left  ?  - 1  :  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            document - > window ( ) - > scroll_by ( key  = =  UIEvents : : KeyCode : : Key_Left  ?  - arrow_key_scroll_distance  :  arrow_key_scroll_distance ,  0 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-09-12 12:56:31 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  EventResult : : Handled ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-07-01 16:03:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    case  UIEvents : : KeyCode : : Key_PageUp : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    case  UIEvents : : KeyCode : : Key_PageDown : 
							 
						 
					
						
							
								
									
										
										
										
											2024-10-09 08:56:55 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( modifiers  ! =  UIEvents : : KeyModifier : : Mod_None ) 
							 
						 
					
						
							
								
									
										
										
										
											2024-07-01 16:03:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        document - > window ( ) - > scroll_by ( 0 ,  key  = =  UIEvents : : KeyCode : : Key_PageUp  ?  - page_scroll_distance  :  page_scroll_distance ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-09-12 12:56:31 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  EventResult : : Handled ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-07-01 16:03:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    case  UIEvents : : KeyCode : : Key_Home : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        document - > scroll_to_the_beginning_of_the_document ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-09-12 12:56:31 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  EventResult : : Handled ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-07-01 16:03:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    case  UIEvents : : KeyCode : : Key_End : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        document - > window ( ) - > scroll_by ( 0 ,  INT64_MAX ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-09-12 12:56:31 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  EventResult : : Handled ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-07-01 16:03:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-10-09 07:39:08 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    return  EventResult : : Accepted ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-08-02 12:10:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-10-22 15:35:00 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								EventResult  EventHandler : : handle_keyup ( UIEvents : : KeyCode  key ,  u32  modifiers ,  u32  code_point ,  bool  repeat )  
						 
					
						
							
								
									
										
										
										
											2021-09-28 15:39:35 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2024-10-22 15:35:00 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // Keyup events as a result of auto-repeat are not fired.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // See: https://w3c.github.io/uievents/#events-keyboard-event-order
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( repeat ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  EventResult : : Dropped ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-10-22 15:32:42 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    return  fire_keyboard_event ( UIEvents : : EventNames : : keyup ,  m_navigable ,  key ,  modifiers ,  code_point ,  false ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-28 15:39:35 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-03-22 11:56:49 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								void  EventHandler : : handle_paste ( String  const &  text )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2024-04-26 16:59:04 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  active_document  =  m_navigable - > active_document ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-03-22 11:56:49 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! active_document ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! active_document - > is_fully_active ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												LibWeb: Separate text control input events handling from contenteditable
This input event handling change is intended to address the following
design issues:
- Having `DOM::Position` is unnecessary complexity when `Selection`
  exists because caret position could be described by the selection
  object with a collapsed state. Before this change, we had to
  synchronize those whenever one of them was modified, and there were
  already bugs caused by that, i.e., caret position was not changed when
  selection offset was modified from the JS side.
- Selection API exposes selection offset within `<textarea>` and
  `<input>`, which is not supposed to happen. These objects should
  manage their selection state by themselves and have selection offset
  even when they are not displayed.
- `EventHandler` looks only at `DOM::Text` owned by `DOM::Position`
  while doing text manipulations. It works fine for `<input>` and
  `<textarea>`, but `contenteditable` needs to consider all text
  descendant text nodes; i.e., if the cursor is moved outside of
  `DOM::Text`, we need to look for an adjacent text node to move the
  cursor there.
With this change, `EventHandler` no longer does direct manipulations on
caret position or text content, but instead delegates them to the active
`InputEventsTarget`, which could be either
`FormAssociatedTextControlElement` (for `<input>` and `<textarea>`) or
`EditingHostManager` (for `contenteditable`). The `Selection` object is
used to manage both selection and caret position for `contenteditable`,
and text control elements manage their own selection state that is not
exposed by Selection API.
This change improves text editing on Discord, as now we don't have to
refocus the `contenteditable` element after character input. The problem
was that selection manipulations from the JS side were not propagated
to `DOM::Position`.
I expect this change to make future correctness improvements for
`contenteditable` (and `designMode`) easier, as now it's decoupled from
`<input>` and `<textarea>` and separated from `EventHandler`, which is
quite a busy file.
											 
										 
										
											2024-10-23 21:26:58 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto *  target  =  active_document - > active_input_events_target ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! target ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    target - > handle_insert ( text ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-03-22 11:56:49 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-01-14 10:14:36 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								void  EventHandler : : set_mouse_event_tracking_paintable ( Painting : : Paintable *  paintable )  
						 
					
						
							
								
									
										
										
										
											2020-09-11 18:15:47 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2024-01-14 10:14:36 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    m_mouse_event_tracking_paintable  =  paintable ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-11 18:15:47 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2020-12-03 18:46:56 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-12-31 16:40:36 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								CSSPixelPoint  EventHandler : : compute_mouse_event_page_offset ( CSSPixelPoint  event_client_offset )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // https://w3c.github.io/csswg-drafts/cssom-view/#dom-mouseevent-pagex
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
										 
							
							
								    // FIXME: 1. If the event’  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
										 
							
							
								    // 2. Let offset be the value of the scrollX attribute of the event’  
							 
						 
					
						
							
								
									
										
										
										
											2024-04-26 16:59:04 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  scroll_offset  =  m_navigable - > active_document ( ) - > navigable ( ) - > viewport_scroll_offset ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-31 16:40:36 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
										 
							
							
								    // 3. Return the sum of offset and the value of the event’  
							 
						 
					
						
							
								
									
										
										
										
											2022-11-03 12:49:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    return  event_client_offset . translated ( scroll_offset ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-31 16:40:36 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2023-04-27 09:19:20 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-09-08 18:48:44 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								CSSPixelPoint  EventHandler : : compute_mouse_event_movement ( CSSPixelPoint  screen_position )  const  
						 
					
						
							
								
									
										
										
										
											2023-08-24 17:47:13 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // https://w3c.github.io/pointerlock/#dom-mouseevent-movementx
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // The attributes movementX movementY must provide the change in position of the pointer,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // as if the values of screenX, screenY, were stored between two subsequent mousemove events eNow and ePrevious and the difference taken movementX = eNow.screenX-ePrevious.screenX.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-09-08 18:48:44 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! m_mousemove_previous_screen_position . has_value ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-24 17:47:13 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        // When unlocked, the system cursor can exit and re-enter the user agent window.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // If it does so and the user agent was not the target of operating system mouse move events
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // then the most recent pointer position will be unknown to the user agent and movementX/movementY can not be computed and must be set to zero.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // FIXME: For this to actually work, m_mousemove_previous_client_offset needs to be cleared when the mouse leaves the window
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  {  0 ,  0  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-09-08 18:48:44 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    return  {  screen_position . x ( )  -  m_mousemove_previous_screen_position . value ( ) . x ( ) ,  screen_position . y ( )  -  m_mousemove_previous_screen_position . value ( ) . y ( )  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-24 17:47:13 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-04-27 09:19:20 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								Optional < EventHandler : : Target >  EventHandler : : target_for_mouse_position ( CSSPixelPoint  position )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2024-01-14 10:14:36 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( m_mouse_event_tracking_paintable )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( m_mouse_event_tracking_paintable - > wants_mouse_events ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  Target  {  m_mouse_event_tracking_paintable ,  { }  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-04-27 09:19:20 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-01-14 10:14:36 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        m_mouse_event_tracking_paintable  =  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-04-27 09:19:20 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( auto  result  =  paint_root ( ) - > hit_test ( position ,  Painting : : HitTestType : : Exact ) ;  result . has_value ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  Target  {  result - > paintable . ptr ( ) ,  result - > index_in_node  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-08-17 13:29:55 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								bool  EventHandler : : should_ignore_device_input_event ( )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // From the moment that the user agent is to initiate the drag-and-drop operation, until the end of the drag-and-drop
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // operation, device input events (e.g. mouse and keyboard events) must be suppressed.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  m_drag_and_drop_event_handler - > has_ongoing_drag_and_drop_operation ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-01-14 10:14:36 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								void  EventHandler : : visit_edges ( JS : : Cell : : Visitor &  visitor )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2024-08-17 13:29:55 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    m_drag_and_drop_event_handler - > visit_edges ( visitor ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-01-14 10:14:36 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    visitor . visit ( m_mouse_event_tracking_paintable ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2025-02-26 20:40:10 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( m_mouse_selection_target ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        visitor . visit ( m_mouse_selection_target - > as_cell ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-01-14 10:14:36 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-08-27 08:19:03 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								Unicode : : Segmenter &  EventHandler : : word_segmenter ( )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! m_word_segmenter ) 
							 
						 
					
						
							
								
									
										
										
										
											2024-09-22 10:03:23 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        m_word_segmenter  =  m_navigable - > active_document ( ) - > word_segmenter ( ) . clone ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-08-27 08:19:03 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    return  * m_word_segmenter ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-06-07 14:40:38 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}