aboutsummaryrefslogtreecommitdiffstats
path: root/components/script/dom/windowproxy.rs
diff options
context:
space:
mode:
authorGregory Terzian <gterzian@users.noreply.github.com>2018-06-02 20:56:00 +0800
committerGregory Terzian <gterzian@users.noreply.github.com>2018-08-11 01:13:11 +0200
commit21bf5a3a4b6398cd7c20449ba9110499feca7d6b (patch)
tree151b1df3f5dccc17b79a5feeb5a1f9bf35759123 /components/script/dom/windowproxy.rs
parentf408b798c4666eddeb8b52d8965d7d4a6942e066 (diff)
downloadservo-21bf5a3a4b6398cd7c20449ba9110499feca7d6b.tar.gz
servo-21bf5a3a4b6398cd7c20449ba9110499feca7d6b.zip
implement opener, disowning
Diffstat (limited to 'components/script/dom/windowproxy.rs')
-rw-r--r--components/script/dom/windowproxy.rs85
1 files changed, 77 insertions, 8 deletions
diff --git a/components/script/dom/windowproxy.rs b/components/script/dom/windowproxy.rs
index 10c925cb28d..093ea29b3d7 100644
--- a/components/script/dom/windowproxy.rs
+++ b/components/script/dom/windowproxy.rs
@@ -36,7 +36,7 @@ use js::jsapi::HandleValue as RawHandleValue;
use js::jsapi::MutableHandle as RawMutableHandle;
use js::jsapi::MutableHandleObject as RawMutableHandleObject;
use js::jsapi::MutableHandleValue as RawMutableHandleValue;
-use js::jsval::{UndefinedValue, PrivateValue};
+use js::jsval::{JSVal, NullValue, UndefinedValue, PrivateValue};
use js::rust::{Handle, MutableHandle};
use js::rust::get_object_class;
use js::rust::wrappers::{NewWindowProxy, SetWindowProxy, JS_TransplantObject};
@@ -67,6 +67,9 @@ pub struct WindowProxy {
/// of the container.
browsing_context_id: BrowsingContextId,
+ // https://html.spec.whatwg.org/multipage/#opener-browsing-context
+ opener: Option<BrowsingContextId>,
+
/// The frame id of the top-level ancestor browsing context.
/// In the case that this is a top-level window, this is our id.
top_level_browsing_context_id: TopLevelBrowsingContextId,
@@ -83,6 +86,9 @@ pub struct WindowProxy {
/// Has the browsing context been discarded?
discarded: Cell<bool>,
+ /// Has the browsing context been disowned?
+ disowned: Cell<bool>,
+
/// The containing iframe element, if this is a same-origin iframe
frame_element: Option<Dom<Element>>,
@@ -95,7 +101,8 @@ impl WindowProxy {
top_level_browsing_context_id: TopLevelBrowsingContextId,
currently_active: Option<PipelineId>,
frame_element: Option<&Element>,
- parent: Option<&WindowProxy>)
+ parent: Option<&WindowProxy>,
+ opener: Option<BrowsingContextId>)
-> WindowProxy
{
let name = frame_element.map_or(DOMString::new(), |e| e.get_string_attribute(&local_name!("name")));
@@ -106,8 +113,10 @@ impl WindowProxy {
name: DomRefCell::new(name),
currently_active: Cell::new(currently_active),
discarded: Cell::new(false),
+ disowned: Cell::new(false),
frame_element: frame_element.map(Dom::from_ref),
parent: parent.map(Dom::from_ref),
+ opener,
}
}
@@ -116,7 +125,8 @@ impl WindowProxy {
browsing_context_id: BrowsingContextId,
top_level_browsing_context_id: TopLevelBrowsingContextId,
frame_element: Option<&Element>,
- parent: Option<&WindowProxy>)
+ parent: Option<&WindowProxy>,
+ opener: Option<BrowsingContextId>)
-> DomRoot<WindowProxy>
{
unsafe {
@@ -140,7 +150,8 @@ impl WindowProxy {
top_level_browsing_context_id,
current,
frame_element,
- parent
+ parent,
+ opener,
));
// The window proxy owns the browsing context.
@@ -161,7 +172,8 @@ impl WindowProxy {
pub fn new_dissimilar_origin(global_to_clone_from: &GlobalScope,
browsing_context_id: BrowsingContextId,
top_level_browsing_context_id: TopLevelBrowsingContextId,
- parent: Option<&WindowProxy>)
+ parent: Option<&WindowProxy>,
+ opener: Option<BrowsingContextId>)
-> DomRoot<WindowProxy>
{
unsafe {
@@ -176,7 +188,8 @@ impl WindowProxy {
top_level_browsing_context_id,
None,
None,
- parent
+ parent,
+ opener
));
// Create a new dissimilar-origin window.
@@ -205,7 +218,7 @@ impl WindowProxy {
}
// https://html.spec.whatwg.org/multipage/#auxiliary-browsing-context
- fn create_auxiliary_browsing_context(&self, name: DOMString, _noopener: bool) -> Option<DomRoot<WindowProxy>> {
+ fn create_auxiliary_browsing_context(&self, name: DOMString, noopener: bool) -> Option<DomRoot<WindowProxy>> {
let (chan, port) = ipc::channel().unwrap();
let window = self.currently_active.get()
.and_then(|id| ScriptThread::find_document(id))
@@ -237,6 +250,7 @@ impl WindowProxy {
new_pipeline_id: new_pipeline_id,
browsing_context_id: new_browsing_context_id,
top_level_browsing_context_id: new_top_level_browsing_context_id,
+ opener: Some(self.browsing_context_id),
load_data: load_data,
pipeline_port: pipeline_receiver,
content_process_shutdown_chan: None,
@@ -248,17 +262,64 @@ impl WindowProxy {
ScriptThread::process_attach_layout(new_layout_info, document.origin().clone());
let msg = EmbedderMsg::BrowserCreated(new_top_level_browsing_context_id);
window.send_to_embedder(msg);
+ // TODO: if noopener is false, copy the sessionStorage storage area of the creator origin.
+ // See step 14 of https://html.spec.whatwg.org/multipage/#creating-a-new-browsing-context
let auxiliary = ScriptThread::find_document(new_pipeline_id).and_then(|doc| doc.browsing_context());
if let Some(proxy) = auxiliary {
if name.to_lowercase() != "_blank" {
proxy.set_name(name);
}
+ if noopener {
+ proxy.disown();
+ }
return Some(proxy)
}
}
None
}
+ // https://html.spec.whatwg.org/multipage/#disowned-its-opener
+ pub fn disown(&self) {
+ self.disowned.set(true);
+ }
+
+ #[allow(unsafe_code)]
+ // https://html.spec.whatwg.org/multipage/#dom-opener
+ pub unsafe fn opener(&self, cx: *mut JSContext) -> JSVal {
+ if self.disowned.get() {
+ return NullValue()
+ }
+ let opener_id = match self.opener {
+ Some(opener_browsing_context_id) => opener_browsing_context_id,
+ None => return NullValue()
+ };
+ let opener_proxy = match ScriptThread::find_window_proxy(opener_id) {
+ Some(window_proxy) => window_proxy,
+ None => {
+ let sender_pipeline_id = self.currently_active().unwrap();
+ match ScriptThread::get_top_level_for_browsing_context(sender_pipeline_id, opener_id) {
+ Some(opener_top_id) => {
+ let global_to_clone_from = GlobalScope::from_context(cx);
+ WindowProxy::new_dissimilar_origin(
+ &*global_to_clone_from,
+ opener_id,
+ opener_top_id,
+ None,
+ None
+ )
+ },
+ None => return NullValue()
+ }
+ }
+ };
+ if opener_proxy.is_browsing_context_discarded() {
+ return NullValue()
+ }
+ rooted!(in(cx) let mut val = UndefinedValue());
+ opener_proxy.to_jsval(cx, val.handle_mut());
+ return val.get()
+ }
+
// https://html.spec.whatwg.org/multipage/#window-open-steps
pub fn open(&self,
url: DOMString,
@@ -314,7 +375,11 @@ impl WindowProxy {
},
"_parent" => {
// Step 4
- (Some(DomRoot::from_ref(self.parent().unwrap())), false)
+ if let Some(parent) = self.parent() {
+ return (Some(DomRoot::from_ref(parent)), false)
+ }
+ (None, false)
+
},
"_top" => {
// Step 5
@@ -336,6 +401,10 @@ impl WindowProxy {
}
}
+ pub fn is_auxiliary(&self) -> bool {
+ self.opener.is_some()
+ }
+
pub fn discard_browsing_context(&self) {
self.discarded.set(true);
}