@@ -30,7 +30,7 @@ macro_rules! handle_app_error {
30
30
31
31
mod settings;
32
32
33
- use std:: cell:: Cell ;
33
+ use std:: cell:: { Cell , RefCell } ;
34
34
use std:: fs:: { File , read_dir} ;
35
35
use std:: io:: Read ;
36
36
use std:: rc:: Rc ;
@@ -83,6 +83,7 @@ use settings::AppSettingsVariant;
83
83
use stylesheet:: get_stylesheet_and_whitelist;
84
84
85
85
pub struct Model {
86
+ clicked_url : Rc < RefCell < Option < String > > > ,
86
87
config_dir : ConfigDir ,
87
88
context : WebContext ,
88
89
inspector_shown : Rc < Cell < bool > > ,
@@ -115,6 +116,7 @@ pub enum Msg {
115
116
PermissionRequest ( PermissionRequest ) ,
116
117
SearchBackward ( bool ) ,
117
118
SetOpenInNewWindow ( bool ) ,
119
+ SetClickedURL ( Option < String > ) ,
118
120
ShowInspector ,
119
121
WebViewSettingChanged ( AppSettingsVariant ) ,
120
122
ZoomChange ( i32 ) ,
@@ -133,6 +135,7 @@ impl Widget for WebView {
133
135
134
136
fn model ( relm : & Relm < Self > , ( config_dir, context) : ( ConfigDir , WebContext ) ) -> Model {
135
137
Model {
138
+ clicked_url : Rc :: new ( RefCell :: new ( None ) ) ,
136
139
config_dir,
137
140
context,
138
141
inspector_shown : Rc :: new ( Cell :: new ( false ) ) ,
@@ -171,6 +174,7 @@ impl Widget for WebView {
171
174
PermissionRequest ( _) => ( ) ,
172
175
SearchBackward ( search_backwards) => self . model . search_backwards = search_backwards,
173
176
SetOpenInNewWindow ( open_in_new_window) => self . set_open_in_new_window ( open_in_new_window) ,
177
+ SetClickedURL ( url) => * self . model . clicked_url . borrow_mut ( ) = url,
174
178
ShowInspector => self . show_inspector ( ) ,
175
179
WebViewSettingChanged ( setting) => self . setting_changed ( setting) ,
176
180
// To be listened by the user.
@@ -187,8 +191,8 @@ impl Widget for WebView {
187
191
} ) {
188
192
close => Close ,
189
193
vexpand: true ,
190
- decide_policy( _, policy_decision, policy_decision_type) with ( open_in_new_window, relm) =>
191
- return WebView :: decide_policy( & policy_decision, & policy_decision_type, & open_in_new_window, & relm) ,
194
+ decide_policy( _, policy_decision, policy_decision_type) with ( clicked_url , open_in_new_window, relm) =>
195
+ return WebView :: decide_policy( & policy_decision, & policy_decision_type, & clicked_url , & open_in_new_window, & relm) ,
192
196
enter_fullscreen => ( EnterFullScreen , false ) ,
193
197
leave_fullscreen => ( LeaveFullScreen , false ) ,
194
198
permission_request( _, request) => ( PermissionRequest ( request. clone( ) ) , true ) ,
@@ -233,10 +237,10 @@ impl WebView {
233
237
}
234
238
235
239
fn decide_policy ( policy_decision : & PolicyDecision , policy_decision_type : & PolicyDecisionType ,
236
- open_in_new_window : & Rc < Cell < bool > > , relm : & Relm < WebView > ) -> bool
240
+ clicked_url : & Rc < RefCell < Option < String > > > , open_in_new_window : & Rc < Cell < bool > > , relm : & Relm < WebView > ) -> bool
237
241
{
238
242
if * policy_decision_type == NavigationAction {
239
- Self :: handle_navigation_action ( policy_decision, open_in_new_window, relm)
243
+ Self :: handle_navigation_action ( policy_decision, clicked_url , open_in_new_window, relm)
240
244
}
241
245
else if * policy_decision_type == Response {
242
246
Self :: handle_response ( policy_decision)
@@ -272,7 +276,7 @@ impl WebView {
272
276
}
273
277
274
278
/// Handle follow link in new window.
275
- fn handle_navigation_action ( policy_decision : & PolicyDecision , open_in_new_window : & Rc < Cell < bool > > ,
279
+ fn handle_navigation_action ( policy_decision : & PolicyDecision , clicked_url : & Rc < RefCell < Option < String > > > , open_in_new_window : & Rc < Cell < bool > > ,
276
280
relm : & Relm < WebView > ) -> bool
277
281
{
278
282
let policy_decision = policy_decision. clone ( ) ;
@@ -287,10 +291,14 @@ impl WebView {
287
291
let url = policy_decision. request ( )
288
292
. and_then ( |request| request. uri ( ) ) ;
289
293
if let Some ( url) = url {
290
- policy_decision. ignore ( ) ;
291
- open_in_new_window. set ( false ) ;
292
- relm. stream ( ) . emit ( NewWindow ( url. to_string ( ) ) ) ;
293
- return true ;
294
+ // NOTE: only open the URL in a new window if it matches the hint URL that was
295
+ // selected by the user.
296
+ if Some ( url. as_str ( ) ) == clicked_url. borrow ( ) . as_deref ( ) {
297
+ policy_decision. ignore ( ) ;
298
+ open_in_new_window. set ( false ) ;
299
+ relm. stream ( ) . emit ( NewWindow ( url. to_string ( ) ) ) ;
300
+ return true ;
301
+ }
294
302
}
295
303
}
296
304
}
0 commit comments