aboutsummaryrefslogtreecommitdiffstats
path: root/components/script
diff options
context:
space:
mode:
authorUtsav Oza <utsavoza96@gmail.com>2020-05-13 00:30:58 +0530
committerUtsav Oza <utsavoza96@gmail.com>2020-05-18 19:07:57 +0530
commitab672577e888c44b4875c9990abfb99ae08fd646 (patch)
tree762ff1d1febb8f37aca17eb5cca39633d68951e3 /components/script
parent1c78728ff1c4eea632ce55119d605c615e033da0 (diff)
downloadservo-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.rs17
-rw-r--r--components/script/dom/windowproxy.rs100
-rw-r--r--components/script/script_thread.rs28
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()