diff options
author | Utsav Oza <utsavoza96@gmail.com> | 2020-05-13 00:30:58 +0530 |
---|---|---|
committer | Utsav Oza <utsavoza96@gmail.com> | 2020-05-18 19:07:57 +0530 |
commit | ab672577e888c44b4875c9990abfb99ae08fd646 (patch) | |
tree | 762ff1d1febb8f37aca17eb5cca39633d68951e3 /components/script | |
parent | 1c78728ff1c4eea632ce55119d605c615e033da0 (diff) | |
download | servo-ab672577e888c44b4875c9990abfb99ae08fd646.tar.gz servo-ab672577e888c44b4875c9990abfb99ae08fd646.zip |
Add creator URL, creator base URL and creator origin in browsing context
Diffstat (limited to 'components/script')
-rw-r--r-- | components/script/dom/document.rs | 17 | ||||
-rw-r--r-- | components/script/dom/windowproxy.rs | 100 | ||||
-rw-r--r-- | components/script/script_thread.rs | 28 |
3 files changed, 135 insertions, 10 deletions
diff --git a/components/script/dom/document.rs b/components/script/dom/document.rs index 4577835d24e..f548907d6a2 100644 --- a/components/script/dom/document.rs +++ b/components/script/dom/document.rs @@ -575,10 +575,19 @@ impl Document { // https://html.spec.whatwg.org/multipage/#fallback-base-url pub fn fallback_base_url(&self) -> ServoUrl { - // Step 1: iframe srcdoc (#4767). - // Step 2: about:blank with a creator browsing context. - // Step 3. - self.url() + let document_url = self.url(); + if let Some(browsing_context) = self.browsing_context() { + // Step 1: If document is an iframe srcdoc document, then return the + // document base URL of document's browsing context's container document. + + // Step 2: If document's URL is about:blank, and document's browsing + // context's creator base URL is non-null, then return that creator base URL. + if document_url.as_str() == "about:blank" && browsing_context.has_creator_base_url() { + return browsing_context.creator_base_url().unwrap(); + } + } + // Step 3: Return document's URL. + document_url } // https://html.spec.whatwg.org/multipage/#document-base-url diff --git a/components/script/dom/windowproxy.rs b/components/script/dom/windowproxy.rs index 14f9f80e20a..23e4641c4f9 100644 --- a/components/script/dom/windowproxy.rs +++ b/components/script/dom/windowproxy.rs @@ -52,7 +52,7 @@ use script_traits::{ AuxiliaryBrowsingContextLoadInfo, HistoryEntryReplacement, LoadData, LoadOrigin, }; use script_traits::{NewLayoutInfo, ScriptMsg}; -use servo_url::ServoUrl; +use servo_url::{ImmutableOrigin, ServoUrl}; use std::cell::Cell; use std::ptr; use style::attr::parse_integer; @@ -108,6 +108,15 @@ pub struct WindowProxy { /// https://html.spec.whatwg.org/multipage/#delaying-load-events-mode delaying_load_events_mode: Cell<bool>, + + /// The creator browsing context's base url. + creator_base_url: Option<ServoUrl>, + + /// The creator browsing context's url. + creator_url: Option<ServoUrl>, + + /// The creator browsing context's origin. + creator_origin: Option<ImmutableOrigin>, } impl WindowProxy { @@ -118,6 +127,7 @@ impl WindowProxy { frame_element: Option<&Element>, parent: Option<&WindowProxy>, opener: Option<BrowsingContextId>, + creator: CreatorBrowsingContextInfo, ) -> WindowProxy { let name = frame_element.map_or(DOMString::new(), |e| { e.get_string_attribute(&local_name!("name")) @@ -135,6 +145,9 @@ impl WindowProxy { parent: parent.map(Dom::from_ref), delaying_load_events_mode: Cell::new(false), opener, + creator_base_url: creator.base_url, + creator_url: creator.url, + creator_origin: creator.origin, } } @@ -146,6 +159,7 @@ impl WindowProxy { frame_element: Option<&Element>, parent: Option<&WindowProxy>, opener: Option<BrowsingContextId>, + creator: CreatorBrowsingContextInfo, ) -> DomRoot<WindowProxy> { unsafe { let WindowProxyHandler(handler) = window.windowproxy_handler(); @@ -173,6 +187,7 @@ impl WindowProxy { frame_element, parent, opener, + creator, )); // The window proxy owns the browsing context. @@ -204,6 +219,7 @@ impl WindowProxy { top_level_browsing_context_id: TopLevelBrowsingContextId, parent: Option<&WindowProxy>, opener: Option<BrowsingContextId>, + creator: CreatorBrowsingContextInfo, ) -> DomRoot<WindowProxy> { unsafe { let handler = CreateWrapperProxyHandler(&XORIGIN_PROXY_HANDLER); @@ -219,6 +235,7 @@ impl WindowProxy { None, parent, opener, + creator, )); // Create a new dissimilar-origin window. @@ -368,6 +385,33 @@ impl WindowProxy { self.is_closing.get() } + /// https://html.spec.whatwg.org/multipage/browsers.html#creator-base-url + pub fn creator_base_url(&self) -> Option<ServoUrl> { + self.creator_base_url.clone() + } + + pub fn has_creator_base_url(&self) -> bool { + self.creator_base_url.is_some() + } + + /// https://html.spec.whatwg.org/multipage/browsers.html#creator-url + pub fn creator_url(&self) -> Option<ServoUrl> { + self.creator_url.clone() + } + + pub fn has_creator_url(&self) -> bool { + self.creator_base_url.is_some() + } + + /// https://html.spec.whatwg.org/multipage/browsers.html#creator-origin + pub fn creator_origin(&self) -> Option<ImmutableOrigin> { + self.creator_origin.clone() + } + + pub fn has_creator_origin(&self) -> bool { + self.creator_origin.is_some() + } + #[allow(unsafe_code)] // https://html.spec.whatwg.org/multipage/#dom-opener pub fn opener(&self, cx: *mut JSContext, in_realm_proof: InRealm) -> JSVal { @@ -378,6 +422,7 @@ impl WindowProxy { Some(opener_browsing_context_id) => opener_browsing_context_id, None => return NullValue(), }; + let parent_browsing_context = self.parent.as_deref(); let opener_proxy = match ScriptThread::find_window_proxy(opener_id) { Some(window_proxy) => window_proxy, None => { @@ -389,12 +434,15 @@ impl WindowProxy { Some(opener_top_id) => { let global_to_clone_from = unsafe { GlobalScope::from_context(cx, in_realm_proof) }; + let creator = + CreatorBrowsingContextInfo::from(parent_browsing_context, None); WindowProxy::new_dissimilar_origin( &*global_to_clone_from, opener_id, opener_top_id, None, None, + creator, ) }, None => return NullValue(), @@ -655,6 +703,56 @@ impl WindowProxy { } } +/// A browsing context can have a creator browsing context, the browsing context that +/// was responsible for its creation. If a browsing context has a parent browsing context, +/// then that is its creator browsing context. Otherwise, if the browsing context has an +/// opener browsing context, then that is its creator browsing context. Otherwise, the +/// browsing context has no creator browsing context. +/// +/// If a browsing context A has a creator browsing context, then the Document that was the +/// active document of that creator browsing context at the time A was created is the creator +/// Document. +/// +/// See: https://html.spec.whatwg.org/multipage/browsers.html#creating-browsing-contexts +#[derive(Debug, Deserialize, Serialize)] +pub struct CreatorBrowsingContextInfo { + /// Creator document URL. + url: Option<ServoUrl>, + + /// Creator document base URL. + base_url: Option<ServoUrl>, + + /// Creator document origin. + origin: Option<ImmutableOrigin>, +} + +impl CreatorBrowsingContextInfo { + pub fn from( + parent: Option<&WindowProxy>, + opener: Option<&WindowProxy>, + ) -> CreatorBrowsingContextInfo { + let creator = if parent.is_some() { + parent.unwrap().document() + } else if opener.is_some() { + opener.unwrap().document() + } else { + None + }; + + let base_url = creator.as_deref().map(|document| document.base_url()); + let url = creator.as_deref().map(|document| document.url()); + let origin = creator + .as_deref() + .map(|document| document.origin().immutable().clone()); + + CreatorBrowsingContextInfo { + base_url, + url, + origin, + } + } +} + // https://html.spec.whatwg.org/multipage/#concept-window-open-features-tokenize fn tokenize_open_features(features: DOMString) -> IndexMap<String, String> { let is_feature_sep = |c: char| c.is_ascii_whitespace() || ['=', ','].contains(&c); diff --git a/components/script/script_thread.rs b/components/script/script_thread.rs index 6a2c4b09c1e..41dc5406b4a 100644 --- a/components/script/script_thread.rs +++ b/components/script/script_thread.rs @@ -68,7 +68,7 @@ use crate::dom::servoparser::{ParserContext, ServoParser}; use crate::dom::transitionevent::TransitionEvent; use crate::dom::uievent::UIEvent; use crate::dom::window::{ReflowReason, Window}; -use crate::dom::windowproxy::WindowProxy; +use crate::dom::windowproxy::{CreatorBrowsingContextInfo, WindowProxy}; use crate::dom::worker::TrustedWorkerAddress; use crate::dom::worklet::WorkletThreadPool; use crate::dom::workletglobalscope::WorkletGlobalScopeInit; @@ -3162,7 +3162,7 @@ impl ScriptThread { return Some(DomRoot::from_ref(window_proxy)); } - let parent = parent_pipeline_id.and_then(|parent_id| { + let parent_browsing_context = parent_pipeline_id.and_then(|parent_id| { self.remote_window_proxy( global_to_clone, top_level_browsing_context_id, @@ -3170,12 +3170,21 @@ impl ScriptThread { opener, ) }); + + let opener_browsing_context = opener.and_then(|id| ScriptThread::find_window_proxy(id)); + + let creator = CreatorBrowsingContextInfo::from( + parent_browsing_context.as_deref(), + opener_browsing_context.as_deref(), + ); + let window_proxy = WindowProxy::new_dissimilar_origin( global_to_clone, browsing_context_id, top_level_browsing_context_id, - parent.as_deref(), + parent_browsing_context.as_deref(), opener, + creator, ); self.window_proxies .borrow_mut() @@ -3207,7 +3216,7 @@ impl ScriptThread { .borrow() .find_iframe(parent_id, browsing_context_id) }); - let parent = match (parent_info, iframe.as_ref()) { + let parent_browsing_context = match (parent_info, iframe.as_ref()) { (_, Some(iframe)) => Some(window_from_node(&**iframe).window_proxy()), (Some(parent_id), _) => self.remote_window_proxy( window.upcast(), @@ -3217,13 +3226,22 @@ impl ScriptThread { ), _ => None, }; + + let opener_browsing_context = opener.and_then(|id| ScriptThread::find_window_proxy(id)); + + let creator = CreatorBrowsingContextInfo::from( + parent_browsing_context.as_deref(), + opener_browsing_context.as_deref(), + ); + let window_proxy = WindowProxy::new( &window, browsing_context_id, top_level_browsing_context_id, iframe.as_deref().map(Castable::upcast), - parent.as_deref(), + parent_browsing_context.as_deref(), opener, + creator, ); self.window_proxies .borrow_mut() |