Add creator URL, creator base URL and creator origin in browsing context

This commit is contained in:
Utsav Oza 2020-05-13 00:30:58 +05:30
parent 1c78728ff1
commit ab672577e8
5 changed files with 135 additions and 20 deletions

View file

@ -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);