2020-01-18 09:38:21 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								/*
  
						 
					
						
							
								
									
										
										
										
											2021-04-27 13:05:50 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  Copyright  ( c )  2018 - 2021 ,  Andreas  Kling  < kling @ serenityos . org > 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-18 09:38:21 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-22 01:24:48 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  SPDX - License - Identifier :  BSD - 2 - Clause 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-18 09:38:21 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-01 21:18:08 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <AK/CharacterTypes.h> 
  
						 
					
						
							
								
									
										
										
										
											2021-04-27 13:05:50 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <AK/ScopeGuard.h> 
  
						 
					
						
							
								
									
										
										
										
											2019-09-25 12:36:44 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <AK/StringBuilder.h> 
  
						 
					
						
							
								
									
										
										
										
											2021-02-10 08:25:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <LibGfx/Painter.h> 
  
						 
					
						
							
								
									
										
										
										
											2020-03-07 10:32:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <LibWeb/DOM/Document.h> 
  
						 
					
						
							
								
									
										
										
										
											2020-11-22 15:53:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <LibWeb/Layout/BlockBox.h> 
  
						 
					
						
							
								
									
										
										
										
											2020-12-05 20:10:39 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <LibWeb/Layout/InlineFormattingContext.h> 
  
						 
					
						
							
								
									
										
										
										
											2021-04-03 21:48:05 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <LibWeb/Layout/Label.h> 
  
						 
					
						
							
								
									
										
										
										
											2020-11-22 15:53:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <LibWeb/Layout/TextNode.h> 
  
						 
					
						
							
								
									
										
										
										
											2021-05-30 12:36:53 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <LibWeb/Page/BrowsingContext.h> 
  
						 
					
						
							
								
									
										
										
										
											2019-06-15 22:49:44 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-11-22 15:53:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								namespace  Web : : Layout  {  
						 
					
						
							
								
									
										
										
										
											2020-03-07 10:27:02 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-11-22 15:53:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								TextNode : : TextNode ( DOM : : Document &  document ,  DOM : : Text &  text )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    :  Node ( document ,  & text ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-15 22:49:44 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2019-10-06 11:09:38 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    set_inline ( true ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-15 22:49:44 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-11-22 15:53:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								TextNode : : ~ TextNode ( )  
						 
					
						
							
								
									
										
										
										
											2019-06-15 22:49:44 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2019-06-15 23:17:08 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-06-13 14:59:17 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  bool  is_all_whitespace ( const  StringView &  string )  
						 
					
						
							
								
									
										
										
										
											2019-06-15 23:17:08 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2019-12-09 17:45:40 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    for  ( size_t  i  =  0 ;  i  <  string . length ( ) ;  + + i )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-01 21:18:08 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( ! is_ascii_space ( string [ i ] ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-15 23:17:08 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-12-03 19:18:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  TextNode : : paint_fragment ( PaintContext &  context ,  const  LineBoxFragment &  fragment ,  PaintPhase  phase )  const  
						 
					
						
							
								
									
										
										
										
											2019-09-25 12:36:44 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2019-10-03 15:20:13 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto &  painter  =  context . painter ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-03 19:18:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( phase  = =  PaintPhase : : Background )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-06 11:07:02 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        painter . fill_rect ( enclosing_int_rect ( fragment . absolute_rect ( ) ) ,  computed_values ( ) . background_color ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-29 00:09:32 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2020-08-02 11:52:35 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-12-03 19:18:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( phase  = =  PaintPhase : : Foreground )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-06 11:05:23 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        painter . set_font ( font ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-03 19:18:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( document ( ) . inspected_node ( )  = =  & dom_node ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            context . painter ( ) . draw_rect ( enclosing_int_rect ( fragment . absolute_rect ( ) ) ,  Color : : Magenta ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-01-06 11:07:02 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( computed_values ( ) . text_decoration_line ( )  = =  CSS : : TextDecorationLine : : Underline ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            painter . draw_line ( enclosing_int_rect ( fragment . absolute_rect ( ) ) . bottom_left ( ) . translated ( 0 ,  1 ) ,  enclosing_int_rect ( fragment . absolute_rect ( ) ) . bottom_right ( ) . translated ( 0 ,  1 ) ,  computed_values ( ) . color ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-03 19:18:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // FIXME: text-transform should be done already in layout, since uppercase glyphs may be wider than lowercase, etc.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto  text  =  m_text_for_rendering ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-06 11:07:02 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        auto  text_transform  =  computed_values ( ) . text_transform ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-15 14:15:49 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( text_transform  = =  CSS : : TextTransform : : Uppercase ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-03 19:18:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            text  =  m_text_for_rendering . to_uppercase ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-15 14:15:49 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( text_transform  = =  CSS : : TextTransform : : Lowercase ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-03 19:18:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            text  =  m_text_for_rendering . to_lowercase ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-01-06 11:07:02 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        painter . draw_text ( enclosing_int_rect ( fragment . absolute_rect ( ) ) ,  text . substring_view ( fragment . start ( ) ,  fragment . length ( ) ) ,  Gfx : : TextAlignment : : CenterLeft ,  computed_values ( ) . color ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-03 19:18:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-01-06 11:05:23 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        auto  selection_rect  =  fragment . selection_rect ( font ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-03 19:18:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( ! selection_rect . is_empty ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            painter . fill_rect ( enclosing_int_rect ( selection_rect ) ,  context . palette ( ) . selection ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            Gfx : : PainterStateSaver  saver ( painter ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            painter . add_clip_rect ( enclosing_int_rect ( selection_rect ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            painter . draw_text ( enclosing_int_rect ( fragment . absolute_rect ( ) ) ,  text . substring_view ( fragment . start ( ) ,  fragment . length ( ) ) ,  Gfx : : TextAlignment : : CenterLeft ,  context . palette ( ) . selection_text ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        paint_cursor_if_needed ( context ,  fragment ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2020-08-02 11:52:35 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-11-22 15:53:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  TextNode : : paint_cursor_if_needed ( PaintContext &  context ,  const  LineBoxFragment &  fragment )  const  
						 
					
						
							
								
									
										
										
										
											2020-08-02 11:52:35 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-05-30 12:36:53 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( ! browsing_context ( ) . is_focused_context ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-08-14 11:45:46 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-05-30 12:36:53 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( ! browsing_context ( ) . cursor_blink_state ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-08-02 11:52:35 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-05-30 12:36:53 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( browsing_context ( ) . cursor_position ( ) . node ( )  ! =  & dom_node ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-08-02 11:52:35 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-05-18 21:56:20 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // NOTE: This checks if the cursor is before the start or after the end of the fragment. If it is at the end, after all text, it should still be painted.
 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-30 12:36:53 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( browsing_context ( ) . cursor_position ( ) . offset ( )  <  ( unsigned ) fragment . start ( )  | |  browsing_context ( ) . cursor_position ( ) . offset ( )  >  ( unsigned ) ( fragment . start ( )  +  fragment . length ( ) ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-08-02 11:52:35 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-11-22 14:46:36 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( ! fragment . layout_node ( ) . dom_node ( )  | |  ! fragment . layout_node ( ) . dom_node ( ) - > is_editable ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-08-02 16:05:59 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-08-02 11:52:35 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  fragment_rect  =  fragment . absolute_rect ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-05-30 12:36:53 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    float  cursor_x  =  fragment_rect . x ( )  +  font ( ) . width ( fragment . text ( ) . substring_view ( 0 ,  browsing_context ( ) . cursor_position ( ) . offset ( )  -  fragment . start ( ) ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-08-02 11:52:35 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    float  cursor_top  =  fragment_rect . top ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    float  cursor_height  =  fragment_rect . height ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Gfx : : IntRect  cursor_rect ( cursor_x ,  cursor_top ,  1 ,  cursor_height ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-09 21:19:40 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-01-06 11:07:02 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    context . painter ( ) . draw_rect ( cursor_rect ,  computed_values ( ) . color ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-09-25 12:36:44 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-03 22:33:53 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// NOTE: This collapes whitespace into a single ASCII space if collapse is true. If previous_is_empty_or_ends_in_whitespace, it also strips leading whitespace.
  
						 
					
						
							
								
									
										
										
										
											2021-04-29 08:51:31 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  TextNode : : compute_text_for_rendering ( bool  collapse ,  bool  previous_is_empty_or_ends_in_whitespace )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-06-03 22:33:53 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto &  data  =  dom_node ( ) . data ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( ! collapse  | |  data . is_empty ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        m_text_for_rendering  =  data ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-29 08:51:31 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-03 22:33:53 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // NOTE: A couple fast returns to avoid unnecessarily allocating a StringBuilder.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( data . length ( )  = =  1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( is_ascii_space ( data [ 0 ] ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( previous_is_empty_or_ends_in_whitespace ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                m_text_for_rendering  =  String : : empty ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                static  String  s_single_space_string  =  "   " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                m_text_for_rendering  =  s_single_space_string ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            m_text_for_rendering  =  data ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-29 08:51:31 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-03 22:33:53 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    bool  contains_space  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    for  ( auto &  c  :  data )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( is_ascii_space ( c ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            contains_space  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( ! contains_space )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        m_text_for_rendering  =  data ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    StringBuilder  builder ( data . length ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    size_t  index  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  skip_over_whitespace  =  [ & index ,  & data ]  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        while  ( index  <  data . length ( )  & &  is_ascii_space ( data [ index ] ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            + + index ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-29 08:51:31 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-03 22:33:53 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-04-29 08:51:31 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( previous_is_empty_or_ends_in_whitespace ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        skip_over_whitespace ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-03 22:33:53 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    while  ( index  <  data . length ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( is_ascii_space ( data [ index ] ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-29 08:51:31 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            builder . append ( '   ' ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-03 22:33:53 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            + + index ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-29 08:51:31 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            skip_over_whitespace ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-03 22:33:53 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            builder . append ( data [ index ] ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            + + index ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-29 08:51:31 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-03 22:33:53 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-04-29 08:51:31 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    m_text_for_rendering  =  builder . to_string ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-12-05 20:10:39 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  TextNode : : split_into_lines_by_rules ( InlineFormattingContext &  context ,  LayoutMode  layout_mode ,  bool  do_collapse ,  bool  do_wrap_lines ,  bool  do_wrap_breaks )  
						 
					
						
							
								
									
										
										
										
											2019-09-25 12:40:37 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2020-12-06 19:48:02 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto &  containing_block  =  context . containing_block ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-01-06 11:05:23 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto &  font  =  this - > font ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-03 15:20:13 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-12-05 20:10:39 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto &  line_boxes  =  containing_block . line_boxes ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    containing_block . ensure_last_line_box ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-05 22:49:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    float  available_width  =  context . available_width_at_line ( line_boxes . size ( )  -  1 )  -  line_boxes . last ( ) . width ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-03 15:20:13 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-04-29 08:51:31 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    compute_text_for_rendering ( do_collapse ,  line_boxes . last ( ) . is_empty_or_ends_in_whitespace ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-27 13:05:50 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    ChunkIterator  iterator ( m_text_for_rendering ,  layout_mode ,  do_wrap_lines ,  do_wrap_breaks ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-09-28 22:18:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-04-27 13:05:50 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    for  ( ; ; )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-27 19:06:35 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        auto  chunk_opt  =  iterator . next ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( ! chunk_opt . has_value ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-27 13:05:50 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            break ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-27 19:06:35 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        auto &  chunk  =  chunk_opt . value ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-03 15:20:13 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-06-13 14:59:17 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        // Collapse entire fragment into non-existence if previous fragment on line ended in whitespace.
 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-17 20:17:29 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( do_collapse  & &  line_boxes . last ( ) . is_empty_or_ends_in_whitespace ( )  & &  chunk . is_all_whitespace ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-13 14:59:17 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-24 08:49:02 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        float  chunk_width ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( do_wrap_lines )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-01 21:18:08 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  ( do_collapse  & &  is_ascii_space ( * chunk . view . begin ( ) )  & &  line_boxes . last ( ) . is_empty_or_ends_in_whitespace ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-06 00:54:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                // This is a non-empty chunk that starts with collapsible whitespace.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                // We are at either at the start of a new line, or after something that ended in whitespace,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                // so we don't need to contribute our own whitespace to the line. Skip over it instead!
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                + + chunk . start ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                - - chunk . length ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                chunk . view  =  chunk . view . substring_view ( 1 ,  chunk . view . byte_length ( )  -  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-03 15:55:18 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-01-06 00:54:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            chunk_width  =  font . width ( chunk . view )  +  font . glyph_spacing ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-03 15:20:13 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-24 08:49:02 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  ( line_boxes . last ( ) . width ( )  >  0  & &  chunk_width  >  available_width )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-05 20:10:39 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                containing_block . add_line_box ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-05 22:49:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                available_width  =  context . available_width_at_line ( line_boxes . size ( )  -  1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-17 20:17:29 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  ( do_collapse  & &  chunk . is_all_whitespace ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    continue ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-24 08:49:02 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            chunk_width  =  font . width ( chunk . view ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-09-29 11:32:00 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-03 15:20:13 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-01-06 00:54:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        line_boxes . last ( ) . add_fragment ( * this ,  chunk . start ,  chunk . length ,  chunk_width ,  font . glyph_height ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-24 08:49:02 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        available_width  - =  chunk_width ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-03 15:55:18 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-04-27 19:00:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( do_wrap_lines  & &  available_width  <  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            containing_block . add_line_box ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            available_width  =  context . available_width_at_line ( line_boxes . size ( )  -  1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-24 08:49:02 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-03 15:55:18 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-04-27 13:05:50 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( do_wrap_breaks  & &  chunk . has_breaking_newline )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            containing_block . add_line_box ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            available_width  =  context . available_width_at_line ( line_boxes . size ( )  -  1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-03 15:55:18 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-03 15:20:13 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2019-09-25 12:40:37 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2020-03-07 10:27:02 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-12-05 20:10:39 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  TextNode : : split_into_lines ( InlineFormattingContext &  context ,  LayoutMode  layout_mode )  
						 
					
						
							
								
									
										
										
										
											2020-05-24 08:49:02 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    bool  do_collapse  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    bool  do_wrap_lines  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    bool  do_wrap_breaks  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-01-06 11:07:02 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( computed_values ( ) . white_space ( )  = =  CSS : : WhiteSpace : : Nowrap )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-24 08:49:02 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        do_collapse  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        do_wrap_lines  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        do_wrap_breaks  =  false ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-06 11:07:02 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    }  else  if  ( computed_values ( ) . white_space ( )  = =  CSS : : WhiteSpace : : Pre )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-24 08:49:02 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        do_collapse  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        do_wrap_lines  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        do_wrap_breaks  =  true ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-06 11:07:02 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    }  else  if  ( computed_values ( ) . white_space ( )  = =  CSS : : WhiteSpace : : PreLine )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-24 08:49:02 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        do_collapse  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        do_wrap_lines  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        do_wrap_breaks  =  true ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-06 11:07:02 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    }  else  if  ( computed_values ( ) . white_space ( )  = =  CSS : : WhiteSpace : : PreWrap )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-24 08:49:02 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        do_collapse  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        do_wrap_lines  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        do_wrap_breaks  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-12-05 20:10:39 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    split_into_lines_by_rules ( context ,  layout_mode ,  do_collapse ,  do_wrap_lines ,  do_wrap_breaks ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-24 08:49:02 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-04-03 21:48:05 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								bool  TextNode : : wants_mouse_events ( )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  parent ( )  & &  is < Label > ( parent ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  TextNode : : handle_mousedown ( Badge < EventHandler > ,  const  Gfx : : IntPoint &  position ,  unsigned  button ,  unsigned )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( ! parent ( )  | |  ! is < Label > ( * parent ( ) ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    downcast < Label > ( * parent ( ) ) . handle_mousedown_on_label ( { } ,  position ,  button ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-30 12:36:53 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    browsing_context ( ) . event_handler ( ) . set_mouse_event_tracking_layout_node ( this ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-03 21:48:05 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  TextNode : : handle_mouseup ( Badge < EventHandler > ,  const  Gfx : : IntPoint &  position ,  unsigned  button ,  unsigned )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( ! parent ( )  | |  ! is < Label > ( * parent ( ) ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-04 11:45:39 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // NOTE: Changing the state of the DOM node may run arbitrary JS, which could disappear this node.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    NonnullRefPtr  protect  =  * this ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-04-03 21:48:05 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    downcast < Label > ( * parent ( ) ) . handle_mouseup_on_label ( { } ,  position ,  button ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-30 12:36:53 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    browsing_context ( ) . event_handler ( ) . set_mouse_event_tracking_layout_node ( nullptr ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-03 21:48:05 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  TextNode : : handle_mousemove ( Badge < EventHandler > ,  const  Gfx : : IntPoint &  position ,  unsigned  button ,  unsigned )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( ! parent ( )  | |  ! is < Label > ( * parent ( ) ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    downcast < Label > ( * parent ( ) ) . handle_mousemove_on_label ( { } ,  position ,  button ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-04-27 13:05:50 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								TextNode : : ChunkIterator : : ChunkIterator ( StringView  const &  text ,  LayoutMode  layout_mode ,  bool  wrap_lines ,  bool  wrap_breaks )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    :  m_layout_mode ( layout_mode ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ,  m_wrap_lines ( wrap_lines ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ,  m_wrap_breaks ( wrap_breaks ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ,  m_utf8_view ( text ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ,  m_start_of_chunk ( m_utf8_view . begin ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ,  m_iterator ( m_utf8_view . begin ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-06-01 21:18:08 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    m_last_was_space  =  ! text . is_empty ( )  & &  is_ascii_space ( * m_utf8_view . begin ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-27 13:05:50 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								Optional < TextNode : : Chunk >  TextNode : : ChunkIterator : : next ( )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    while  ( m_iterator  ! =  m_utf8_view . end ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto  guard  =  ScopeGuard ( [ & ]  {  + + m_iterator ;  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( m_layout_mode  = =  LayoutMode : : AllPossibleLineBreaks )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( auto  result  =  try_commit_chunk ( m_iterator ,  false ) ;  result . has_value ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                return  result . release_value ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( m_last_was_newline )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            m_last_was_newline  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( auto  result  =  try_commit_chunk ( m_iterator ,  true ) ;  result . has_value ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                return  result . release_value ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( m_wrap_breaks  & &  * m_iterator  = =  ' \n ' )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            m_last_was_newline  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( auto  result  =  try_commit_chunk ( m_iterator ,  false ) ;  result . has_value ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                return  result . release_value ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( m_wrap_lines )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-01 21:18:08 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            bool  is_space  =  is_ascii_space ( * m_iterator ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-27 13:05:50 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  ( is_space  ! =  m_last_was_space )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                m_last_was_space  =  is_space ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  ( auto  result  =  try_commit_chunk ( m_iterator ,  false ) ;  result . has_value ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    return  result . release_value ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( m_last_was_newline )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        m_last_was_newline  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( auto  result  =  try_commit_chunk ( m_utf8_view . end ( ) ,  true ) ;  result . has_value ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  result . release_value ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( m_start_of_chunk  ! =  m_utf8_view . end ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( auto  result  =  try_commit_chunk ( m_utf8_view . end ( ) ,  false ,  true ) ;  result . has_value ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  result . release_value ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								Optional < TextNode : : Chunk >  TextNode : : ChunkIterator : : try_commit_chunk ( Utf8View : : Iterator  const &  it ,  bool  has_breaking_newline ,  bool  must_commit )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( m_layout_mode  = =  LayoutMode : : OnlyRequiredLineBreaks  & &  ! must_commit ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  start  =  m_utf8_view . byte_offset_of ( m_start_of_chunk ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  length  =  m_utf8_view . byte_offset_of ( it )  -  m_utf8_view . byte_offset_of ( m_start_of_chunk ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( has_breaking_newline  | |  length  >  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto  chunk_view  =  m_utf8_view . substring_view ( start ,  length ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        m_start_of_chunk  =  it ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  Chunk  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            . view  =  chunk_view , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            . start  =  start , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            . length  =  length , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            . has_breaking_newline  =  has_breaking_newline , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            . is_all_whitespace  =  is_all_whitespace ( chunk_view . as_string ( ) ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    m_start_of_chunk  =  it ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-07 10:27:02 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}