@@ -27,7 +27,11 @@ use raw_window_handle::RawWindowHandle;
2727use std:: ffi:: c_ulong;
2828#[ cfg( any( debug_assertions, feature = "devtools" ) ) ]
2929use std:: sync:: atomic:: { AtomicBool , Ordering } ;
30- use std:: sync:: { Arc , Mutex } ;
30+ use std:: {
31+ collections:: HashMap ,
32+ rc:: Rc ,
33+ sync:: { Arc , Mutex } ,
34+ } ;
3135#[ cfg( any( debug_assertions, feature = "devtools" ) ) ]
3236use webkit2gtk:: WebInspectorExt ;
3337use webkit2gtk:: {
@@ -275,11 +279,11 @@ impl InnerWebView {
275279 }
276280
277281 // Extension loading
278- if let Some ( extension_path) = pl_attrs. extension_path {
279- web_context. os . set_web_extensions_directory ( & extension_path) ;
282+ if let Some ( extension_path) = & pl_attrs. extension_path {
283+ web_context. os . set_web_extensions_directory ( extension_path) ;
280284 }
281285
282- let webview = Self :: create_webview ( web_context, & attributes) ;
286+ let webview = Self :: create_webview ( web_context, & attributes, & pl_attrs ) ;
283287
284288 // Transparent
285289 if attributes. transparent {
@@ -379,10 +383,13 @@ impl InnerWebView {
379383 Ok ( w)
380384 }
381385
382- fn create_webview ( web_context : & WebContext , attributes : & WebViewAttributes ) -> WebView {
386+ fn create_webview (
387+ web_context : & WebContext ,
388+ attributes : & WebViewAttributes ,
389+ pl_attrs : & super :: PlatformSpecificWebViewAttributes ,
390+ ) -> WebView {
383391 let mut builder = WebView :: builder ( )
384392 . user_content_manager ( & UserContentManager :: new ( ) )
385- . web_context ( web_context. context ( ) )
386393 . is_controlled_by_automation ( web_context. allows_automation ( ) ) ;
387394
388395 if attributes. autoplay {
@@ -393,6 +400,12 @@ impl InnerWebView {
393400 ) ;
394401 }
395402
403+ if let Some ( related_view) = & pl_attrs. related_view {
404+ builder = builder. related_view ( related_view) ;
405+ } else {
406+ builder = builder. web_context ( web_context. context ( ) ) ;
407+ }
408+
396409 builder. build ( )
397410 }
398411
@@ -468,35 +481,79 @@ impl InnerWebView {
468481 } ) ;
469482 }
470483
471- // Navigation handler && New window handler
472- if attributes. navigation_handler . is_some ( ) || attributes. new_window_req_handler . is_some ( ) {
473- let new_window_req_handler = attributes. new_window_req_handler . take ( ) ;
474- let navigation_handler = attributes. navigation_handler . take ( ) ;
484+ // window creation handler
485+ if let Some ( new_window_req_handler) = attributes. new_window_req_handler . take ( ) {
486+ let related_webviews = Rc :: new ( Mutex :: new ( HashMap :: new ( ) ) ) ;
487+ webview. connect_create ( move |webview, action| {
488+ let url = action
489+ . request ( )
490+ . and_then ( |request| request. uri ( ) )
491+ . map ( |uri| uri. as_str ( ) . to_string ( ) ) ?;
492+ if new_window_req_handler ( url. clone ( ) ) {
493+ let related_webviews = related_webviews. clone ( ) ;
494+ let toplevel = webview. toplevel ( ) . unwrap ( ) ;
495+ let window = toplevel. downcast :: < gtk:: ApplicationWindow > ( ) . unwrap ( ) ;
496+ let id = window. id ( ) ;
497+ let app = window. application ( ) . unwrap ( ) ;
498+
499+ let window = gtk:: ApplicationWindow :: builder ( )
500+ . application ( & app)
501+ . title ( & url)
502+ . build ( ) ;
503+ let box_ = gtk:: Box :: new ( gtk:: Orientation :: Vertical , 0 ) ;
504+ window. add ( & box_) ;
505+
506+ let related_webviews_ = related_webviews. clone ( ) ;
507+ window. connect_destroy ( move |_| {
508+ related_webviews_. lock ( ) . unwrap ( ) . remove ( & id) ;
509+ } ) ;
475510
511+ window. show_all ( ) ;
512+ Self :: new_gtk (
513+ & box_,
514+ WebViewAttributes {
515+ ..Default :: default ( )
516+ } ,
517+ super :: PlatformSpecificWebViewAttributes {
518+ related_view : Some ( webview. clone ( ) ) ,
519+ ..Default :: default ( )
520+ } ,
521+ )
522+ . map ( |webview| {
523+ let widget = webview. webview . upcast_ref :: < gtk:: Widget > ( ) . clone ( ) ;
524+ related_webviews. lock ( ) . unwrap ( ) . insert ( id, webview) ;
525+ widget
526+ } )
527+ . ok ( )
528+ } else {
529+ None
530+ }
531+ } ) ;
532+ }
533+
534+ // Navigation handler
535+ if let Some ( navigation_handler) = attributes. navigation_handler . take ( ) {
476536 webview. connect_decide_policy ( move |_webview, policy_decision, policy_type| {
477537 let handler = match policy_type {
478538 PolicyDecisionType :: NavigationAction => & navigation_handler,
479- PolicyDecisionType :: NewWindowAction => & new_window_req_handler,
480539 _ => return false ,
481540 } ;
482541
483- if let Some ( handler) = handler {
484- if let Some ( policy) = policy_decision. dynamic_cast_ref :: < NavigationPolicyDecision > ( ) {
485- if let Some ( nav_action) = policy. navigation_action ( ) {
486- if let Some ( uri_req) = nav_action. request ( ) {
487- if let Some ( uri) = uri_req. uri ( ) {
488- let allow = handler ( uri. to_string ( ) ) ;
489- let pointer = policy_decision. as_ptr ( ) ;
490- unsafe {
491- if allow {
492- webkit_policy_decision_use ( pointer)
493- } else {
494- webkit_policy_decision_ignore ( pointer)
495- }
542+ if let Some ( policy) = policy_decision. dynamic_cast_ref :: < NavigationPolicyDecision > ( ) {
543+ if let Some ( nav_action) = policy. navigation_action ( ) {
544+ if let Some ( uri_req) = nav_action. request ( ) {
545+ if let Some ( uri) = uri_req. uri ( ) {
546+ let allow = handler ( uri. to_string ( ) ) ;
547+ let pointer = policy_decision. as_ptr ( ) ;
548+ unsafe {
549+ if allow {
550+ webkit_policy_decision_use ( pointer)
551+ } else {
552+ webkit_policy_decision_ignore ( pointer)
496553 }
497-
498- return true ;
499554 }
555+
556+ return true ;
500557 }
501558 }
502559 }
@@ -936,21 +993,21 @@ impl InnerWebView {
936993
937994 pub fn cookies_for_url ( & self , url : & str ) -> Result < Vec < cookie:: Cookie < ' static > > > {
938995 let ( tx, rx) = std:: sync:: mpsc:: channel ( ) ;
939- self
996+ if let Some ( cookies_manager ) = self
940997 . webview
941998 . website_data_manager ( )
942999 . and_then ( |manager| manager. cookie_manager ( ) )
943- . map ( |cookies_manager| {
944- cookies_manager. cookies ( url, None :: < & Cancellable > , move |cookies| {
945- let cookies = cookies. map ( |cookies| {
946- cookies
947- . into_iter ( )
948- . map ( Self :: cookie_from_soup_cookie)
949- . collect ( )
950- } ) ;
951- let _ = tx. send ( cookies) ;
952- } )
953- } ) ;
1000+ {
1001+ cookies_manager. cookies ( url, None :: < & Cancellable > , move |cookies| {
1002+ let cookies = cookies. map ( |cookies| {
1003+ cookies
1004+ . into_iter ( )
1005+ . map ( Self :: cookie_from_soup_cookie)
1006+ . collect ( )
1007+ } ) ;
1008+ let _ = tx. send ( cookies) ;
1009+ } )
1010+ }
9541011
9551012 loop {
9561013 gtk:: main_iteration ( ) ;
@@ -963,21 +1020,21 @@ impl InnerWebView {
9631020
9641021 pub fn cookies ( & self ) -> Result < Vec < cookie:: Cookie < ' static > > > {
9651022 let ( tx, rx) = std:: sync:: mpsc:: channel ( ) ;
966- self
1023+ if let Some ( cookies_manager ) = self
9671024 . webview
9681025 . website_data_manager ( )
9691026 . and_then ( |manager| manager. cookie_manager ( ) )
970- . map ( |cookies_manager| {
971- cookies_manager. all_cookies ( None :: < & Cancellable > , move |cookies| {
972- let cookies = cookies. map ( |cookies| {
973- cookies
974- . into_iter ( )
975- . map ( Self :: cookie_from_soup_cookie)
976- . collect ( )
977- } ) ;
978- let _ = tx. send ( cookies) ;
979- } )
980- } ) ;
1027+ {
1028+ cookies_manager. all_cookies ( None :: < & Cancellable > , move |cookies| {
1029+ let cookies = cookies. map ( |cookies| {
1030+ cookies
1031+ . into_iter ( )
1032+ . map ( Self :: cookie_from_soup_cookie)
1033+ . collect ( )
1034+ } ) ;
1035+ let _ = tx. send ( cookies) ;
1036+ } )
1037+ }
9811038
9821039 loop {
9831040 gtk:: main_iteration ( ) ;
@@ -990,16 +1047,16 @@ impl InnerWebView {
9901047
9911048 pub fn set_cookie ( & self , cookie : & cookie:: Cookie < ' _ > ) -> Result < ( ) > {
9921049 let ( tx, rx) = std:: sync:: mpsc:: channel ( ) ;
993- self
1050+ if let Some ( cookies_manager ) = self
9941051 . webview
9951052 . website_data_manager ( )
9961053 . and_then ( |manager| manager. cookie_manager ( ) )
997- . map ( |cookies_manager| {
998- let mut soup_cookie = Self :: cookie_into_soup_cookie ( cookie) ;
999- cookies_manager. add_cookie ( & mut soup_cookie, None :: < & Cancellable > , move |ret| {
1000- let _ = tx. send ( ret) ;
1001- } ) ;
1054+ {
1055+ let mut soup_cookie = Self :: cookie_into_soup_cookie ( cookie) ;
1056+ cookies_manager. add_cookie ( & mut soup_cookie, None :: < & Cancellable > , move |ret| {
1057+ let _ = tx. send ( ret) ;
10021058 } ) ;
1059+ }
10031060
10041061 loop {
10051062 gtk:: main_iteration ( ) ;
@@ -1012,16 +1069,16 @@ impl InnerWebView {
10121069
10131070 pub fn delete_cookie ( & self , cookie : & cookie:: Cookie < ' _ > ) -> Result < ( ) > {
10141071 let ( tx, rx) = std:: sync:: mpsc:: channel ( ) ;
1015- self
1072+ if let Some ( cookies_manager ) = self
10161073 . webview
10171074 . website_data_manager ( )
10181075 . and_then ( |manager| manager. cookie_manager ( ) )
1019- . map ( |cookies_manager| {
1020- let mut soup_cookie = Self :: cookie_into_soup_cookie ( cookie) ;
1021- cookies_manager. delete_cookie ( & mut soup_cookie, None :: < & Cancellable > , move |ret| {
1022- let _ = tx. send ( ret) ;
1023- } ) ;
1076+ {
1077+ let mut soup_cookie = Self :: cookie_into_soup_cookie ( cookie) ;
1078+ cookies_manager. delete_cookie ( & mut soup_cookie, None :: < & Cancellable > , move |ret| {
1079+ let _ = tx. send ( ret) ;
10241080 } ) ;
1081+ }
10251082
10261083 loop {
10271084 gtk:: main_iteration ( ) ;
0 commit comments