Rewild Your Web
web
browser
dweb
1--- original
2+++ modified
3@@ -7,7 +7,7 @@
4 use std::rc::Rc;
5
6 use base::generic_channel;
7-use base::generic_channel::GenericSend;
8+use base::generic_channel::{GenericSend, channel};
9 use base::id::{BrowsingContextId, PipelineId, WebViewId};
10 use constellation_traits::{
11 AuxiliaryWebViewCreationRequest, LoadData, LoadOrigin, NavigationHistoryBehavior,
12@@ -298,8 +298,9 @@
13 &self,
14 name: DOMString,
15 noopener: bool,
16+ target_url: Option<ServoUrl>,
17 ) -> Option<DomRoot<WindowProxy>> {
18- let (response_sender, response_receiver) = ipc::channel().unwrap();
19+ let (response_sender, response_receiver) = channel().unwrap();
20 let window = self
21 .currently_active
22 .get()
23@@ -333,6 +334,7 @@
24 opener_webview_id: window.webview_id(),
25 opener_pipeline_id: self.currently_active.get().unwrap(),
26 response_sender,
27+ target_url,
28 };
29 let constellation_msg = ScriptToConstellationMessage::CreateAuxiliaryWebView(load_info);
30 window.send_to_constellation(constellation_msg);
31@@ -351,6 +353,8 @@
32 // Use the current `WebView`'s theme initially, but the embedder may
33 // change this later.
34 theme: window.theme(),
35+ is_embedded_webview: false,
36+ hide_focus: false,
37 };
38
39 with_script_thread(|script_thread| {
40@@ -509,14 +513,32 @@
41 // (TODO) Step 11. Let referrerPolicy be the empty string.
42 // (TODO) Step 12. If noreferrer is true, then set referrerPolicy to "no-referrer".
43
44+ // Resolve the target URL early so we can pass it to choose_browsing_context.
45+ // This is needed for embedded webviews where the embedder needs to know what URL
46+ // will be navigated to before creating the new browsing context.
47+ let target_url = if !url.is_empty() {
48+ let existing_document = self
49+ .currently_active
50+ .get()
51+ .and_then(ScriptThread::find_document)
52+ .unwrap();
53+ match existing_document.url().join(&url) {
54+ Ok(resolved_url) => Some(resolved_url),
55+ Err(_) => return Err(Error::Syntax(None)),
56+ }
57+ } else {
58+ None
59+ };
60+
61 // Step 13 - 14
62 // Let targetNavigable and windowType be the result of applying the rules for
63 // choosing a navigable given target, sourceDocument's node navigable, and noopener.
64 // If targetNavigable is null, then return null.
65- let (chosen, new) = match self.choose_browsing_context(non_empty_target, noopener) {
66- (Some(chosen), new) => (chosen, new),
67- (None, _) => return Ok(None),
68- };
69+ let (chosen, new) =
70+ match self.choose_browsing_context(non_empty_target, noopener, target_url.clone()) {
71+ (Some(chosen), new) => (chosen, new),
72+ (None, _) => return Ok(None),
73+ };
74 // TODO Step 15.2, Set up browsing context features for targetNavigable's
75 // active browsing context given tokenizedFeatures.
76 let target_document = match chosen.document() {
77@@ -531,16 +553,12 @@
78 let target_window = target_document.window();
79 // Step 15.3 and 15.4 will have happened elsewhere,
80 // since we've created a new browsing context and loaded it with about:blank.
81- if !url.is_empty() {
82+ if let Some(url) = target_url {
83 let existing_document = self
84 .currently_active
85 .get()
86 .and_then(ScriptThread::find_document)
87 .unwrap();
88- let url = match existing_document.url().join(&url) {
89- Ok(url) => url,
90- Err(_) => return Err(Error::Syntax(None)),
91- };
92 let referrer = if noreferrer {
93 Referrer::NoReferrer
94 } else {
95@@ -604,6 +622,7 @@
96 &self,
97 name: DOMString,
98 noopener: bool,
99+ target_url: Option<ServoUrl>,
100 ) -> (Option<DomRoot<WindowProxy>>, bool) {
101 match name.to_lowercase().as_ref() {
102 "" | "_self" => {
103@@ -621,7 +640,10 @@
104 // Step 5
105 (Some(DomRoot::from_ref(self.top())), false)
106 },
107- "_blank" => (self.create_auxiliary_browsing_context(name, noopener), true),
108+ "_blank" => (
109+ self.create_auxiliary_browsing_context(name, noopener, target_url),
110+ true,
111+ ),
112 _ => {
113 // Step 6.
114 // TODO: expand the search to all 'familiar' bc,
115@@ -629,7 +651,10 @@
116 // See https://html.spec.whatwg.org/multipage/#familiar-with
117 match ScriptThread::find_window_proxy_by_name(&name) {
118 Some(proxy) => (Some(proxy), false),
119- None => (self.create_auxiliary_browsing_context(name, noopener), true),
120+ None => (
121+ self.create_auxiliary_browsing_context(name, noopener, target_url),
122+ true,
123+ ),
124 }
125 },
126 }