@@ -19,10 +19,11 @@ use std::marker::PhantomData;
1919use std:: pin:: Pin ;
2020use std:: rc:: Rc ;
2121use url:: Url ;
22+ use gtk:: gdk;
2223
2324use crate :: common;
24- use crate :: common:: { glibctx, HistoryItem , LossyTextRead , PageElement , RequestCtx } ;
25- use crate :: draw_ctx :: DrawCtx ;
25+ use crate :: common:: { glibctx, HistoryItem , LossyTextRead , PageElement } ;
26+ use crate :: text_extensions :: Gemini as GeminiTextExt ;
2627use crate :: gemini;
2728
2829#[ derive( Clone , Debug , glib:: Boxed , Default ) ]
@@ -39,7 +40,7 @@ pub mod imp {
3940 #[ properties( wrapper_type = super :: Tab ) ]
4041 pub struct Tab {
4142 pub ( crate ) gemini_client : RefCell < gemini:: Client > ,
42- pub ( crate ) draw_ctx : RefCell < Option < DrawCtx > > ,
43+ pub ( crate ) gemini_text_ext : RefCell < Option < GeminiTextExt > > ,
4344 pub ( crate ) history : RefCell < Vec < HistoryItem > > ,
4445 pub ( crate ) current_hi : RefCell < Option < usize > > ,
4546 #[ template_child]
@@ -149,38 +150,30 @@ impl Tab {
149150 imp. text_view
150151 . add_controller ( imp. motion_ctrl . borrow ( ) . as_ref ( ) . unwrap ( ) ) ;
151152
152- imp. draw_ctx
153- . replace ( Some ( DrawCtx :: new ( imp. text_view . clone ( ) , config) ) ) ;
153+ imp. gemini_text_ext
154+ . replace ( Some ( GeminiTextExt :: new ( imp. text_view . clone ( ) , config) ) ) ;
154155
155156 this. bind_signals ( ) ;
156157 this
157158 }
158- fn build_request_ctx ( & self , url : Url ) -> RequestCtx {
159- let imp = self . imp ( ) ;
160- RequestCtx {
161- draw_ctx : imp. draw_ctx . borrow ( ) . clone ( ) . unwrap ( ) ,
162- gemini_client : imp. gemini_client . borrow ( ) . clone ( ) ,
163- url,
164- }
165- }
166159 pub fn handle_click ( & self , x : f64 , y : f64 ) -> Result < ( ) > {
167160 let imp = self . imp ( ) ;
168- let draw_ctx = imp. draw_ctx . borrow ( ) ;
169- let text_view = & draw_ctx . as_ref ( ) . unwrap ( ) . text_view ;
161+ let gemini_text_ext = imp. gemini_text_ext . borrow ( ) ;
162+ let text_view = & gemini_text_ext . as_ref ( ) . unwrap ( ) . text_view ;
170163 let has_selection = text_view. buffer ( ) . has_selection ( ) ;
171164 if has_selection {
172165 return Ok ( ( ) ) ;
173166 }
174- let link = Self :: extract_linkhandler ( draw_ctx . as_ref ( ) . unwrap ( ) , x, y) ?;
167+ let link = Self :: extract_linkhandler ( gemini_text_ext . as_ref ( ) . unwrap ( ) , x, y) ?;
175168 let url = self . parse_link ( & link) ?;
176169 self . spawn_open_url ( url) ;
177170 Ok ( ( ) )
178171 }
179172 fn handle_right_click ( & self , x : f64 , y : f64 ) -> Result < ( ) > {
180173 let imp = self . imp ( ) ;
181- let draw_ctx = imp. draw_ctx . borrow ( ) ;
182- let text_view = & draw_ctx . as_ref ( ) . unwrap ( ) . text_view ;
183- let link = Self :: extract_linkhandler ( draw_ctx . as_ref ( ) . unwrap ( ) , x, y) ?;
174+ let gemini_text_ext = imp. gemini_text_ext . borrow ( ) ;
175+ let text_view = & gemini_text_ext . as_ref ( ) . unwrap ( ) . text_view ;
176+ let link = Self :: extract_linkhandler ( gemini_text_ext . as_ref ( ) . unwrap ( ) , x, y) ?;
184177 let link = self . parse_link ( & link) ?;
185178 let link_variant = link. as_str ( ) . to_variant ( ) ;
186179
@@ -198,23 +191,21 @@ impl Tab {
198191 }
199192 fn handle_motion ( & self , x : f64 , y : f64 ) -> Result < ( ) > {
200193 let imp = self . imp ( ) ;
201- let draw_ctx = imp. draw_ctx . borrow ( ) ;
202- let draw_ctx = draw_ctx . as_ref ( ) . unwrap ( ) ;
203- let link = Self :: extract_linkhandler ( draw_ctx , x, y) ;
194+ let gemini_text_ext = imp. gemini_text_ext . borrow ( ) ;
195+ let gemini_text_ext = gemini_text_ext . as_ref ( ) . unwrap ( ) ;
196+ let link = Self :: extract_linkhandler ( gemini_text_ext , x, y) ;
204197 match link {
205198 Ok ( _) => {
206- draw_ctx . text_view . set_cursor_from_name ( Some ( "pointer" ) ) ;
199+ gemini_text_ext . text_view . set_cursor_from_name ( Some ( "pointer" ) ) ;
207200 }
208201 Err ( _) => {
209- draw_ctx . text_view . set_cursor_from_name ( Some ( "text" ) ) ;
202+ gemini_text_ext . text_view . set_cursor_from_name ( Some ( "text" ) ) ;
210203 }
211204 }
212205
213206 Ok ( ( ) )
214207 }
215208 pub fn spawn_open_url ( & self , url : Url ) {
216- let imp = self . imp ( ) ;
217-
218209 let i = self . add_to_history ( HistoryItem {
219210 url : url. clone ( ) ,
220211 cache : Default :: default ( ) ,
@@ -272,17 +263,15 @@ impl Tab {
272263 * imp. url . borrow_mut ( ) = url. to_string ( ) ;
273264 self . notify ( "url" ) ;
274265
275- let mut req_ctx = self . build_request_ctx ( url. clone ( ) ) ;
276-
277266 let this = self . clone ( ) ;
278267 let fut = async move {
279- let cache = match this. send_request ( & mut req_ctx ) . await {
268+ let cache = match this. send_request ( url . clone ( ) ) . await {
280269 Ok ( Some ( cache) ) => {
281270 info ! ( "Page loaded, can be cached ({})" , url. clone( ) ) ;
282271 Some ( cache)
283272 }
284273 Ok ( _) => {
285- info ! ( "Page loaded ({})" , url. clone ( ) ) ;
274+ info ! ( "Page loaded ({})" , & url) ;
286275 None
287276 }
288277 Err ( e) => {
@@ -306,7 +295,7 @@ impl Tab {
306295 }
307296 fn open_cached ( & self , url : Url , cache : Vec < u8 > ) -> impl Future < Output = ( ) > {
308297 let imp = self . imp ( ) ;
309- let mut draw_ctx = imp. draw_ctx . borrow ( ) . clone ( ) . unwrap ( ) ;
298+ let mut gemini_text_ext = imp. gemini_text_ext . borrow ( ) . clone ( ) . unwrap ( ) ;
310299
311300 * self . imp ( ) . progress . borrow_mut ( ) = 0.0 ;
312301 self . notify ( "progress" ) ;
@@ -320,7 +309,7 @@ impl Tab {
320309 let this = self . clone ( ) ;
321310 async move {
322311 let buf = BufReader :: new ( & * cache) ;
323- draw_ctx . clear ( ) ;
312+ gemini_text_ext . clear ( ) ;
324313 let res = this. display_gemini ( buf) . await ;
325314 match res {
326315 Ok ( _) => {
@@ -409,8 +398,8 @@ impl Tab {
409398 } ) ,
410399 ) ;
411400 }
412- fn extract_linkhandler ( draw_ctx : & DrawCtx , x : f64 , y : f64 ) -> Result < String > {
413- let text_view = & draw_ctx . text_view ;
401+ fn extract_linkhandler ( gemini_text_ext : & GeminiTextExt , x : f64 , y : f64 ) -> Result < String > {
402+ let text_view = & gemini_text_ext . text_view ;
414403 let ( x, y) =
415404 text_view. window_to_buffer_coords ( gtk:: TextWindowType :: Widget , x as i32 , y as i32 ) ;
416405 let iter = text_view
@@ -419,13 +408,12 @@ impl Tab {
419408
420409 iter. tags ( )
421410 . iter ( )
422- . find_map ( DrawCtx :: linkhandler)
411+ . find_map ( GeminiTextExt :: linkhandler)
423412 . cloned ( )
424413 . ok_or ( anyhow:: Error :: msg ( "Clicked text doesn't have a link tag" ) )
425414 }
426- async fn open_file_url ( & self , req : & mut RequestCtx ) -> Result < ( ) > {
427- let path = req
428- . url
415+ async fn open_file_url ( & self , url : Url ) -> Result < ( ) > {
416+ let path = url
429417 . to_file_path ( )
430418 . map_err ( |_| anyhow:: Error :: msg ( "Can't convert link to file path" ) ) ?;
431419
@@ -437,32 +425,33 @@ impl Tab {
437425 this. display_gemini ( lines) . await ?;
438426 }
439427 _ => {
440- Self :: display_text ( & mut req . draw_ctx , lines) . await ?;
428+ this . display_text ( lines) . await ?;
441429 }
442430 }
443431 Ok ( ( ) )
444432 }
445- async fn send_request ( & self , req : & mut RequestCtx ) -> Result < Option < Vec < u8 > > > {
446- req . draw_ctx . clear ( ) ;
447- match req . url . scheme ( ) {
433+ async fn send_request ( & self , url : Url ) -> Result < Option < Vec < u8 > > > {
434+ self . imp ( ) . gemini_text_ext . borrow_mut ( ) . as_mut ( ) . unwrap ( ) . clear ( ) ;
435+ match url. scheme ( ) {
448436 "about" => {
449437 let reader = futures:: io:: BufReader :: new ( common:: ABOUT_PAGE . as_bytes ( ) ) ;
450438 self . display_gemini ( reader) . await ?;
451439 Ok ( None )
452440 }
453441 "file" => {
454- self . open_file_url ( req ) . await ?;
442+ self . open_file_url ( url ) . await ?;
455443 Ok ( None )
456444 }
457- "gemini" => self . open_gemini_url ( req ) . await ,
445+ "gemini" => self . open_gemini_url ( url ) . await ,
458446 _ => {
459- self . display_url_confirmation ( & req . url ) ;
447+ self . display_url_confirmation ( & url) ;
460448 Ok ( None )
461449 }
462450 }
463451 }
464- async fn open_gemini_url ( & self , req : & mut RequestCtx ) -> anyhow:: Result < Option < Vec < u8 > > > {
465- let res: gemini:: Response = req. gemini_client . fetch ( req. url . as_str ( ) ) . await ?;
452+ async fn open_gemini_url ( & self , url : Url ) -> anyhow:: Result < Option < Vec < u8 > > > {
453+ let imp = self . imp ( ) ;
454+ let res: gemini:: Response = imp. gemini_client . borrow ( ) . fetch ( url. as_str ( ) ) . await ?;
466455
467456 use gemini:: Status :: * ;
468457 let meta = res. meta ( ) . to_owned ( ) ;
@@ -472,7 +461,7 @@ impl Tab {
472461 let this = self . clone ( ) ;
473462 let res = match status {
474463 Input ( _) => {
475- self . display_input ( req . url . clone ( ) , & meta) ;
464+ self . display_input ( url. clone ( ) , & meta) ;
476465 None
477466 }
478467 Success ( _) => {
@@ -482,10 +471,10 @@ impl Tab {
482471 let res = this. display_gemini ( buffered) . await ?;
483472 Some ( res)
484473 } else if meta. contains ( "text" ) {
485- Self :: display_text ( & mut req . draw_ctx , buffered) . await ?;
474+ self . display_text ( buffered) . await ?;
486475 None
487476 } else {
488- self . display_download ( req . url . clone ( ) , buffered) . await ?;
477+ self . display_download ( url. clone ( ) , buffered) . await ?;
489478 None
490479 }
491480 }
@@ -596,19 +585,21 @@ impl Tab {
596585 Ok ( ( ) )
597586 }
598587 async fn display_text (
599- draw_ctx : & mut DrawCtx ,
588+ & self ,
600589 mut stream : impl AsyncBufRead + Unpin ,
601590 ) -> anyhow:: Result < ( ) > {
591+ let gemini_text_ext = self . imp ( ) . gemini_text_ext . borrow ( ) ;
592+ let gemini_text_ext = gemini_text_ext. as_ref ( ) . unwrap ( ) ;
602593 let mut line = String :: with_capacity ( 1024 ) ;
603594 loop {
604595 line. clear ( ) ;
605596 let n = stream. read_line_lossy ( & mut line) . await ?;
606597 if n == 0 {
607598 break Ok ( ( ) ) ;
608599 }
609- let text_iter = & mut draw_ctx . text_buffer . end_iter ( ) ;
610- draw_ctx . insert_paragraph ( text_iter, & line) ;
611- draw_ctx . insert_paragraph ( text_iter, "\n " ) ;
600+ let text_iter = & mut gemini_text_ext . text_buffer . end_iter ( ) ;
601+ gemini_text_ext . insert_paragraph ( text_iter, & line) ;
602+ gemini_text_ext . insert_paragraph ( text_iter, "\n " ) ;
612603 }
613604 }
614605
@@ -665,10 +656,10 @@ impl Tab {
665656 mut reader : T ,
666657 ) -> anyhow:: Result < Vec < u8 > > {
667658 let imp = self . imp ( ) ;
668- let mut draw_ctx = imp. draw_ctx . borrow ( ) . clone ( ) . unwrap ( ) ;
659+ let mut gemini_text_ext = imp. gemini_text_ext . borrow ( ) . clone ( ) . unwrap ( ) ;
669660
670661 let mut parser = gemini:: Parser :: new ( ) ;
671- let mut text_iter = draw_ctx . text_buffer . end_iter ( ) ;
662+ let mut text_iter = gemini_text_ext . text_buffer . end_iter ( ) ;
672663
673664 let mut preformatted = String :: new ( ) ;
674665 let mut data = String :: with_capacity ( 1024 ) ;
@@ -691,15 +682,15 @@ impl Tab {
691682 // preformatted text is handled different hoping to add scrollbars for it,
692683 // in the future, maybe
693684 if !preformatted. is_empty ( ) {
694- draw_ctx . insert_preformatted ( & mut text_iter, & preformatted) ;
685+ gemini_text_ext . insert_preformatted ( & mut text_iter, & preformatted) ;
695686 preformatted. clear ( ) ;
696687 }
697688 match token {
698689 PageElement :: Text ( line) => {
699- draw_ctx . insert_paragraph ( & mut text_iter, & line) ;
690+ gemini_text_ext . insert_paragraph ( & mut text_iter, & line) ;
700691 }
701692 PageElement :: Heading ( line) => {
702- draw_ctx . insert_heading ( & mut text_iter, & line) ;
693+ gemini_text_ext . insert_heading ( & mut text_iter, & line) ;
703694 if !title_updated {
704695 title_updated = true ;
705696 imp. title
@@ -708,10 +699,10 @@ impl Tab {
708699 }
709700 }
710701 PageElement :: Quote ( line) => {
711- draw_ctx . insert_quote ( & mut text_iter, & line) ;
702+ gemini_text_ext . insert_quote ( & mut text_iter, & line) ;
712703 }
713704 PageElement :: Empty => {
714- draw_ctx . insert_paragraph ( & mut text_iter, "\n " ) ;
705+ gemini_text_ext . insert_paragraph ( & mut text_iter, "\n " ) ;
715706 }
716707 PageElement :: Link ( url, label) => {
717708 let link_char = if let Ok ( true ) = self
@@ -723,12 +714,20 @@ impl Tab {
723714 "⇗"
724715 } ;
725716 let label = format ! ( "{link_char} {}" , label. as_deref( ) . unwrap_or( & url) ) ;
726- draw_ctx . insert_link ( & mut text_iter, url. clone ( ) , Some ( & label) ) ;
717+ gemini_text_ext . insert_link ( & mut text_iter, url. clone ( ) , Some ( & label) ) ;
727718 }
728719 PageElement :: Preformatted ( _) => unreachable ! ( "handled before" ) ,
729720 }
730721 }
731722 }
732723 Ok ( data. into_bytes ( ) )
733724 }
725+ pub fn set_link_color ( & self , rgba : & gdk:: RGBA ) {
726+ self . imp ( )
727+ . gemini_text_ext
728+ . borrow ( )
729+ . as_ref ( )
730+ . unwrap ( )
731+ . set_link_color ( rgba) ;
732+ }
734733}
0 commit comments