implement window.open, create auxiliary browsing context

This commit is contained in:
Gregory Terzian 2018-04-22 12:58:30 +08:00
parent 3e96a322ae
commit f408b798c4
93 changed files with 476 additions and 324 deletions

View file

@ -123,7 +123,7 @@ use network_listener::NetworkListener;
use pipeline::{InitialPipelineState, Pipeline}; use pipeline::{InitialPipelineState, Pipeline};
use profile_traits::mem; use profile_traits::mem;
use profile_traits::time; use profile_traits::time;
use script_traits::{AnimationState, AnimationTickType, CompositorEvent}; use script_traits::{AnimationState, AuxiliaryBrowsingContextLoadInfo, AnimationTickType, CompositorEvent};
use script_traits::{ConstellationControlMsg, ConstellationMsg as FromCompositorMsg, DiscardBrowsingContext}; use script_traits::{ConstellationControlMsg, ConstellationMsg as FromCompositorMsg, DiscardBrowsingContext};
use script_traits::{DocumentActivity, DocumentState, LayoutControlMsg, LoadData}; use script_traits::{DocumentActivity, DocumentState, LayoutControlMsg, LoadData};
use script_traits::{IFrameLoadInfo, IFrameLoadInfoWithData, IFrameSandboxState, TimerSchedulerMsg}; use script_traits::{IFrameLoadInfo, IFrameLoadInfoWithData, IFrameSandboxState, TimerSchedulerMsg};
@ -1121,6 +1121,9 @@ where
FromScriptMsg::ScriptNewIFrame(load_info, layout_sender) => { FromScriptMsg::ScriptNewIFrame(load_info, layout_sender) => {
self.handle_script_new_iframe(load_info, layout_sender); self.handle_script_new_iframe(load_info, layout_sender);
}, },
FromScriptMsg::ScriptNewAuxiliary(load_info, layout_sender) => {
self.handle_script_new_auxiliary(load_info, layout_sender);
},
FromScriptMsg::ChangeRunningAnimationsState(animation_state) => { FromScriptMsg::ChangeRunningAnimationsState(animation_state) => {
self.handle_change_running_animations_state(source_pipeline_id, animation_state) self.handle_change_running_animations_state(source_pipeline_id, animation_state)
}, },
@ -1868,6 +1871,62 @@ where
}); });
} }
fn handle_script_new_auxiliary(&mut self,
load_info: AuxiliaryBrowsingContextLoadInfo,
layout_sender: IpcSender<LayoutControlMsg>) {
let AuxiliaryBrowsingContextLoadInfo {
opener_pipeline_id,
new_top_level_browsing_context_id,
new_browsing_context_id,
new_pipeline_id,
} = load_info;
let url = ServoUrl::parse("about:blank").expect("infallible");
// TODO: Referrer?
let load_data = LoadData::new(url.clone(), None, None, None);
let pipeline = {
let opener_pipeline = match self.pipelines.get(&opener_pipeline_id) {
Some(parent_pipeline) => parent_pipeline,
None => return warn!("Auxiliary loaded url in closed pipeline {}.", opener_pipeline_id),
};
let opener_host = match reg_host(&opener_pipeline.url) {
Some(host) => host,
None => return warn!("Auxiliary loaded pipeline with no url {}.", opener_pipeline_id),
};
let script_sender = opener_pipeline.event_loop.clone();
// https://html.spec.whatwg.org/multipage/#unit-of-related-similar-origin-browsing-contexts
// If the auxiliary shares the host/scheme with the creator, they share an event-loop.
// So the first entry for the auxiliary, itself currently "about:blank",
// is the event-loop for the current host of the creator.
self.event_loops.entry(new_top_level_browsing_context_id)
.or_insert_with(HashMap::new)
.insert(opener_host, Rc::downgrade(&script_sender));
Pipeline::new(new_pipeline_id,
new_browsing_context_id,
new_top_level_browsing_context_id,
None,
script_sender,
layout_sender,
self.compositor_proxy.clone(),
opener_pipeline.is_private,
url,
opener_pipeline.visible,
load_data)
};
assert!(!self.pipelines.contains_key(&new_pipeline_id));
self.pipelines.insert(new_pipeline_id, pipeline);
self.joint_session_histories.insert(new_top_level_browsing_context_id, JointSessionHistory::new());
self.add_pending_change(SessionHistoryChange {
top_level_browsing_context_id: new_top_level_browsing_context_id,
browsing_context_id: new_browsing_context_id,
new_pipeline_id: new_pipeline_id,
replace: None,
});
}
fn handle_pending_paint_metric(&self, pipeline_id: PipelineId, epoch: Epoch) { fn handle_pending_paint_metric(&self, pipeline_id: PipelineId, epoch: Epoch) {
self.compositor_proxy self.compositor_proxy
.send(ToCompositorMsg::PendingPaintMetric(pipeline_id, epoch)) .send(ToCompositorMsg::PendingPaintMetric(pipeline_id, epoch))

View file

@ -84,6 +84,10 @@ pub enum EmbedderMsg {
Alert(String, IpcSender<()>), Alert(String, IpcSender<()>),
/// Wether or not to follow a link /// Wether or not to follow a link
AllowNavigation(ServoUrl, IpcSender<bool>), AllowNavigation(ServoUrl, IpcSender<bool>),
/// Whether or not to allow script to open a new tab/browser
AllowOpeningBrowser(IpcSender<bool>),
/// A new browser was created by script
BrowserCreated(TopLevelBrowsingContextId),
/// Wether or not to unload a document /// Wether or not to unload a document
AllowUnload(IpcSender<bool>), AllowUnload(IpcSender<bool>),
/// Sends an unconsumed key event back to the embedder. /// Sends an unconsumed key event back to the embedder.
@ -143,6 +147,8 @@ impl Debug for EmbedderMsg {
EmbedderMsg::ShowIME(..) => write!(f, "ShowIME"), EmbedderMsg::ShowIME(..) => write!(f, "ShowIME"),
EmbedderMsg::HideIME => write!(f, "HideIME"), EmbedderMsg::HideIME => write!(f, "HideIME"),
EmbedderMsg::Shutdown => write!(f, "Shutdown"), EmbedderMsg::Shutdown => write!(f, "Shutdown"),
EmbedderMsg::AllowOpeningBrowser(..) => write!(f, "AllowOpeningBrowser"),
EmbedderMsg::BrowserCreated(..) => write!(f, "BrowserCreated")
} }
} }
} }

View file

@ -574,45 +574,61 @@ impl Activatable for HTMLAnchorElement {
} }
} }
/// <https://html.spec.whatwg.org/multipage/#the-rules-for-choosing-a-browsing-context-given-a-browsing-context-name>
fn is_current_browsing_context(target: DOMString) -> bool {
target.is_empty() || target == "_self"
}
/// <https://html.spec.whatwg.org/multipage/#following-hyperlinks-2> /// <https://html.spec.whatwg.org/multipage/#following-hyperlinks-2>
pub fn follow_hyperlink(subject: &Element, hyperlink_suffix: Option<String>, referrer_policy: Option<ReferrerPolicy>) { pub fn follow_hyperlink(subject: &Element, hyperlink_suffix: Option<String>, referrer_policy: Option<ReferrerPolicy>) {
// Step 1: replace. // Step 1: TODO: If subject cannot navigate, then return.
// Step 2: source browsing context. // Step 2, done in Step 7.
// Step 3: target browsing context.
let target = subject.get_attribute(&ns!(), &local_name!("target"));
// Step 4: disown target's opener if needed.
let attribute = subject.get_attribute(&ns!(), &local_name!("href")).unwrap();
let mut href = attribute.Value();
// Step 7: append a hyperlink suffix.
// https://www.w3.org/Bugs/Public/show_bug.cgi?id=28925
if let Some(suffix) = hyperlink_suffix {
href.push_str(&suffix);
}
// Step 5: parse the URL.
// Step 6: navigate to an error document if parsing failed.
let document = document_from_node(subject); let document = document_from_node(subject);
let url = match document.url().join(&href) { let window = document.window();
Ok(url) => url,
Err(_) => return, // Step 3: source browsing context.
let source = document.browsing_context().unwrap();
// Step 4-5: target attribute.
let target_attribute_value = subject.get_attribute(&ns!(), &local_name!("target"));
// Step 6.
let noopener = if let Some(link_types) = subject.get_attribute(&ns!(), &local_name!("rel")) {
let values = link_types.Value();
let contains_noopener = values.contains("noopener");
let contains_noreferrer = values.contains("noreferrer");
contains_noreferrer || contains_noopener
} else {
false
}; };
// Step 8: navigate to the URL. // Step 7.
if let Some(target) = target { let (maybe_chosen, replace) = match target_attribute_value {
if !is_current_browsing_context(target.Value()) { Some(name) => source.choose_browsing_context(name.Value(), noopener),
// https://github.com/servo/servo/issues/13241 None => (Some(window.window_proxy()), false)
};
let chosen = match maybe_chosen {
Some(proxy) => proxy,
None => return,
};
if let Some(target_document) = chosen.document() {
let target_window = target_document.window();
// Step 9, dis-owning target's opener, if necessary
// will have been done as part of Step 7 above
// in choose_browsing_context/create_auxiliary_browsing_context.
// Step 10, 11, 12, 13. TODO: if parsing the URL failed, navigate to error page.
let attribute = subject.get_attribute(&ns!(), &local_name!("href")).unwrap();
let mut href = attribute.Value();
// Step 12: append a hyperlink suffix.
// https://www.w3.org/Bugs/Public/show_bug.cgi?id=28925
if let Some(suffix) = hyperlink_suffix {
href.push_str(&suffix);
} }
} let url = match document.url().join(&href) {
Ok(url) => url,
Err(_) => return,
};
debug!("following hyperlink to {}", url); // Step 13, 14.
debug!("following hyperlink to {}", url);
let window = document.window(); target_window.load_url(url, replace, false, referrer_policy);
window.load_url(url, false, false, referrer_policy); };
} }

View file

@ -41,6 +41,7 @@ use dom::node::{Node, NodeFlags, UnbindContext, VecPreOrderInsertionHelper};
use dom::node::{document_from_node, window_from_node}; use dom::node::{document_from_node, window_from_node};
use dom::validitystate::ValidationFlags; use dom::validitystate::ValidationFlags;
use dom::virtualmethods::VirtualMethods; use dom::virtualmethods::VirtualMethods;
use dom::window::Window;
use dom_struct::dom_struct; use dom_struct::dom_struct;
use encoding_rs::{Encoding, UTF_8}; use encoding_rs::{Encoding, UTF_8};
use html5ever::{LocalName, Prefix}; use html5ever::{LocalName, Prefix};
@ -337,10 +338,24 @@ impl HTMLFormElement {
let scheme = action_components.scheme().to_owned(); let scheme = action_components.scheme().to_owned();
let enctype = submitter.enctype(); let enctype = submitter.enctype();
let method = submitter.method(); let method = submitter.method();
let _target = submitter.target();
// TODO: Handle browsing contexts, partially loaded documents (step 16-17)
let mut load_data = LoadData::new(action_components, None, doc.get_referrer_policy(), Some(doc.url())); // Step 16, 17
let target_attribute_value = submitter.target();
let source = doc.browsing_context().unwrap();
let (maybe_chosen, _new) = source.choose_browsing_context(target_attribute_value, false);
let chosen = match maybe_chosen {
Some(proxy) => proxy,
None => return
};
let target_document = match chosen.document() {
Some(doc) => doc,
None => return
};
let target_window = target_document.window();
let mut load_data = LoadData::new(action_components,
None,
target_document.get_referrer_policy(),
Some(target_document.url()));
// Step 18 // Step 18
match (&*scheme, method) { match (&*scheme, method) {
@ -351,17 +366,17 @@ impl HTMLFormElement {
// https://html.spec.whatwg.org/multipage/#submit-mutate-action // https://html.spec.whatwg.org/multipage/#submit-mutate-action
("http", FormMethod::FormGet) | ("https", FormMethod::FormGet) | ("data", FormMethod::FormGet) => { ("http", FormMethod::FormGet) | ("https", FormMethod::FormGet) | ("data", FormMethod::FormGet) => {
load_data.headers.set(ContentType::form_url_encoded()); load_data.headers.set(ContentType::form_url_encoded());
self.mutate_action_url(&mut form_data, load_data, encoding); self.mutate_action_url(&mut form_data, load_data, encoding, &target_window);
} }
// https://html.spec.whatwg.org/multipage/#submit-body // https://html.spec.whatwg.org/multipage/#submit-body
("http", FormMethod::FormPost) | ("https", FormMethod::FormPost) => { ("http", FormMethod::FormPost) | ("https", FormMethod::FormPost) => {
load_data.method = Method::Post; load_data.method = Method::Post;
self.submit_entity_body(&mut form_data, load_data, enctype, encoding); self.submit_entity_body(&mut form_data, load_data, enctype, encoding, &target_window);
} }
// https://html.spec.whatwg.org/multipage/#submit-get-action // https://html.spec.whatwg.org/multipage/#submit-get-action
("file", _) | ("about", _) | ("data", FormMethod::FormPost) | ("file", _) | ("about", _) | ("data", FormMethod::FormPost) |
("ftp", _) | ("javascript", _) => { ("ftp", _) | ("javascript", _) => {
self.plan_to_navigate(load_data); self.plan_to_navigate(load_data, &target_window);
} }
("mailto", FormMethod::FormPost) => { ("mailto", FormMethod::FormPost) => {
// TODO: Mail as body // TODO: Mail as body
@ -376,7 +391,11 @@ impl HTMLFormElement {
} }
// https://html.spec.whatwg.org/multipage/#submit-mutate-action // https://html.spec.whatwg.org/multipage/#submit-mutate-action
fn mutate_action_url(&self, form_data: &mut Vec<FormDatum>, mut load_data: LoadData, encoding: &'static Encoding) { fn mutate_action_url(&self,
form_data: &mut Vec<FormDatum>,
mut load_data: LoadData,
encoding: &'static Encoding,
target: &Window) {
let charset = encoding.name(); let charset = encoding.name();
self.set_encoding_override(load_data.url.as_mut_url().query_pairs_mut()) self.set_encoding_override(load_data.url.as_mut_url().query_pairs_mut())
@ -384,12 +403,16 @@ impl HTMLFormElement {
.extend_pairs(form_data.into_iter() .extend_pairs(form_data.into_iter()
.map(|field| (field.name.clone(), field.replace_value(charset)))); .map(|field| (field.name.clone(), field.replace_value(charset))));
self.plan_to_navigate(load_data); self.plan_to_navigate(load_data, target);
} }
// https://html.spec.whatwg.org/multipage/#submit-body // https://html.spec.whatwg.org/multipage/#submit-body
fn submit_entity_body(&self, form_data: &mut Vec<FormDatum>, mut load_data: LoadData, fn submit_entity_body(&self,
enctype: FormEncType, encoding: &'static Encoding) { form_data: &mut Vec<FormDatum>,
mut load_data: LoadData,
enctype: FormEncType,
encoding: &'static Encoding,
target: &Window) {
let boundary = generate_boundary(); let boundary = generate_boundary();
let bytes = match enctype { let bytes = match enctype {
FormEncType::UrlEncoded => { FormEncType::UrlEncoded => {
@ -415,7 +438,7 @@ impl HTMLFormElement {
}; };
load_data.data = Some(bytes); load_data.data = Some(bytes);
self.plan_to_navigate(load_data); self.plan_to_navigate(load_data, target);
} }
fn set_encoding_override<'a>(&self, mut serializer: Serializer<UrlQuery<'a>>) fn set_encoding_override<'a>(&self, mut serializer: Serializer<UrlQuery<'a>>)
@ -426,9 +449,7 @@ impl HTMLFormElement {
} }
/// [Planned navigation](https://html.spec.whatwg.org/multipage/#planned-navigation) /// [Planned navigation](https://html.spec.whatwg.org/multipage/#planned-navigation)
fn plan_to_navigate(&self, load_data: LoadData) { fn plan_to_navigate(&self, load_data: LoadData, target: &Window) {
let window = window_from_node(self);
// Step 1 // Step 1
// Each planned navigation task is tagged with a generation ID, and // Each planned navigation task is tagged with a generation ID, and
// before the task is handled, it first checks whether the HTMLFormElement's // before the task is handled, it first checks whether the HTMLFormElement's
@ -437,8 +458,8 @@ impl HTMLFormElement {
self.generation_id.set(generation_id); self.generation_id.set(generation_id);
// Step 2. // Step 2.
let pipeline_id = window.upcast::<GlobalScope>().pipeline_id(); let pipeline_id = target.upcast::<GlobalScope>().pipeline_id();
let script_chan = window.main_thread_script_chan().clone(); let script_chan = target.main_thread_script_chan().clone();
let this = Trusted::new(self); let this = Trusted::new(self);
let task = task!(navigate_to_form_planned_navigation: move || { let task = task!(navigate_to_form_planned_navigation: move || {
if generation_id != this.root().generation_id.get() { if generation_id != this.root().generation_id.get() {
@ -452,7 +473,7 @@ impl HTMLFormElement {
}); });
// Step 3. // Step 3.
window.dom_manipulation_task_source().queue(task, window.upcast()).unwrap(); target.dom_manipulation_task_source().queue(task, target.upcast()).unwrap();
} }
/// Interactively validate the constraints of form elements /// Interactively validate the constraints of form elements

View file

@ -40,8 +40,8 @@
// https://github.com/whatwg/html/issues/2115 // https://github.com/whatwg/html/issues/2115
[Replaceable] readonly attribute WindowProxy? parent; [Replaceable] readonly attribute WindowProxy? parent;
readonly attribute Element? frameElement; readonly attribute Element? frameElement;
//WindowProxy open(optional DOMString url = "about:blank", optional DOMString target = "_blank", WindowProxy? open(optional DOMString url = "about:blank", optional DOMString target = "_blank",
// optional DOMString features = "", optional boolean replace = false); optional DOMString features = "");
//getter WindowProxy (unsigned long index); //getter WindowProxy (unsigned long index);
// https://github.com/servo/servo/issues/14453 // https://github.com/servo/servo/issues/14453

View file

@ -565,6 +565,15 @@ impl WindowMethods for Window {
doc.abort(); doc.abort();
} }
// https://html.spec.whatwg.org/multipage/#dom-open
fn Open(&self,
url: DOMString,
target: DOMString,
features: DOMString)
-> Option<DomRoot<WindowProxy>> {
self.window_proxy().open(url, target, features)
}
// https://html.spec.whatwg.org/multipage/#dom-window-closed // https://html.spec.whatwg.org/multipage/#dom-window-closed
fn Closed(&self) -> bool { fn Closed(&self) -> bool {
self.window_proxy.get() self.window_proxy.get()

View file

@ -13,10 +13,12 @@ use dom::bindings::str::DOMString;
use dom::bindings::trace::JSTraceable; use dom::bindings::trace::JSTraceable;
use dom::bindings::utils::{WindowProxyHandler, get_array_index_from_id, AsVoidPtr}; use dom::bindings::utils::{WindowProxyHandler, get_array_index_from_id, AsVoidPtr};
use dom::dissimilaroriginwindow::DissimilarOriginWindow; use dom::dissimilaroriginwindow::DissimilarOriginWindow;
use dom::document::Document;
use dom::element::Element; use dom::element::Element;
use dom::globalscope::GlobalScope; use dom::globalscope::GlobalScope;
use dom::window::Window; use dom::window::Window;
use dom_struct::dom_struct; use dom_struct::dom_struct;
use embedder_traits::EmbedderMsg;
use ipc_channel::ipc; use ipc_channel::ipc;
use js::JSCLASS_IS_GLOBAL; use js::JSCLASS_IS_GLOBAL;
use js::glue::{CreateWrapperProxyHandler, ProxyTraps}; use js::glue::{CreateWrapperProxyHandler, ProxyTraps};
@ -42,7 +44,9 @@ use msg::constellation_msg::BrowsingContextId;
use msg::constellation_msg::PipelineId; use msg::constellation_msg::PipelineId;
use msg::constellation_msg::TopLevelBrowsingContextId; use msg::constellation_msg::TopLevelBrowsingContextId;
use script_thread::ScriptThread; use script_thread::ScriptThread;
use script_traits::ScriptMsg; use script_traits::{AuxiliaryBrowsingContextLoadInfo, LoadData, NewLayoutInfo, ScriptMsg};
use servo_config::prefs::PREFS;
use servo_url::ServoUrl;
use std::cell::Cell; use std::cell::Cell;
use std::ptr; use std::ptr;
@ -200,6 +204,138 @@ impl WindowProxy {
} }
} }
// https://html.spec.whatwg.org/multipage/#auxiliary-browsing-context
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))
.and_then(|doc| Some(DomRoot::from_ref(doc.window())))
.unwrap();
let msg = EmbedderMsg::AllowOpeningBrowser(chan);
window.send_to_embedder(msg);
if port.recv().unwrap() {
let new_top_level_browsing_context_id = TopLevelBrowsingContextId::new();
let new_browsing_context_id = BrowsingContextId::from(new_top_level_browsing_context_id);
let new_pipeline_id = PipelineId::new();
let load_info = AuxiliaryBrowsingContextLoadInfo {
opener_pipeline_id: self.currently_active.get().unwrap(),
new_browsing_context_id: new_browsing_context_id,
new_top_level_browsing_context_id: new_top_level_browsing_context_id,
new_pipeline_id: new_pipeline_id,
};
let document = self.currently_active.get()
.and_then(|id| ScriptThread::find_document(id))
.unwrap();
let blank_url = ServoUrl::parse("about:blank").ok().unwrap();
let load_data = LoadData::new(blank_url,
None,
document.get_referrer_policy(),
Some(document.url().clone()));
let (pipeline_sender, pipeline_receiver) = ipc::channel().unwrap();
let new_layout_info = NewLayoutInfo {
parent_info: None,
new_pipeline_id: new_pipeline_id,
browsing_context_id: new_browsing_context_id,
top_level_browsing_context_id: new_top_level_browsing_context_id,
load_data: load_data,
pipeline_port: pipeline_receiver,
content_process_shutdown_chan: None,
window_size: None,
layout_threads: PREFS.get("layout.threads").as_u64().expect("count") as usize,
};
let constellation_msg = ScriptMsg::ScriptNewAuxiliary(load_info, pipeline_sender);
window.send_to_constellation(constellation_msg);
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);
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);
}
return Some(proxy)
}
}
None
}
// https://html.spec.whatwg.org/multipage/#window-open-steps
pub fn open(&self,
url: DOMString,
target: DOMString,
features: DOMString)
-> Option<DomRoot<WindowProxy>> {
// Step 3.
let non_empty_target = match target.as_ref() {
"" => DOMString::from("_blank"),
_ => target
};
// TODO Step 4, properly tokenize features.
// Step 5
let noopener = features.contains("noopener");
// Step 6, 7
let (chosen, new) = match self.choose_browsing_context(non_empty_target, noopener) {
(Some(chosen), new) => (chosen, new),
(None, _) => return None
};
// TODO Step 8, set up browsing context features.
let target_document = match chosen.document() {
Some(target_document) => target_document,
None => return None
};
let target_window = target_document.window();
// Step 9, and 10.2, will have happened elsewhere,
// since we've created a new browsing context and loaded it with about:blank.
if !url.is_empty() {
let existing_document = self.currently_active.get()
.and_then(|id| ScriptThread::find_document(id)).unwrap();
// Step 10.1
let url = match existing_document.url().join(&url) {
Ok(url) => url,
Err(_) => return None, // TODO: throw a "SyntaxError" DOMException.
};
// Step 10.3
target_window.load_url(url, new, false, target_document.get_referrer_policy());
}
if noopener {
// Step 11 (Dis-owning has been done in create_auxiliary_browsing_context).
return None
}
// Step 12.
return target_document.browsing_context()
}
// https://html.spec.whatwg.org/multipage/#the-rules-for-choosing-a-browsing-context-given-a-browsing-context-name
pub fn choose_browsing_context(&self, name: DOMString, noopener: bool) -> (Option<DomRoot<WindowProxy>>, bool) {
match name.to_lowercase().as_ref() {
"" | "_self" => {
// Step 3.
(Some(DomRoot::from_ref(self)), false)
},
"_parent" => {
// Step 4
(Some(DomRoot::from_ref(self.parent().unwrap())), false)
},
"_top" => {
// Step 5
(Some(DomRoot::from_ref(self.top())), false)
},
"_blank" => {
(self.create_auxiliary_browsing_context(name, noopener), true)
},
_ => {
// Step 6.
// TODO: expand the search to all 'familiar' bc,
// including auxiliaries familiar by way of their opener.
// See https://html.spec.whatwg.org/multipage/#familiar-with
match ScriptThread::find_window_proxy_by_name(&name) {
Some(proxy) => (Some(proxy), false),
None => (self.create_auxiliary_browsing_context(name, noopener), true)
}
}
}
}
pub fn discard_browsing_context(&self) { pub fn discard_browsing_context(&self) {
self.discarded.set(true); self.discarded.set(true);
} }
@ -220,6 +356,11 @@ impl WindowProxy {
self.frame_element.r() self.frame_element.r()
} }
pub fn document(&self) -> Option<DomRoot<Document>> {
self.currently_active.get()
.and_then(|id| ScriptThread::find_document(id))
}
pub fn parent(&self) -> Option<&WindowProxy> { pub fn parent(&self) -> Option<&WindowProxy> {
self.parent.r() self.parent.r()
} }

View file

@ -721,6 +721,18 @@ impl ScriptThread {
})) }))
} }
pub fn find_window_proxy_by_name(name: &DOMString) -> Option<DomRoot<WindowProxy>> {
SCRIPT_THREAD_ROOT.with(|root| root.get().and_then(|script_thread| {
let script_thread = unsafe { &*script_thread };
for (_, proxy) in script_thread.window_proxies.borrow().iter() {
if proxy.get_name() == *name {
return Some(DomRoot::from_ref(&**proxy))
}
}
None
}))
}
pub fn worklet_thread_pool() -> Rc<WorkletThreadPool> { pub fn worklet_thread_pool() -> Rc<WorkletThreadPool> {
SCRIPT_THREAD_ROOT.with(|root| { SCRIPT_THREAD_ROOT.with(|root| {
let script_thread = unsafe { &*root.get().unwrap() }; let script_thread = unsafe { &*root.get().unwrap() };

View file

@ -576,6 +576,19 @@ pub enum IFrameSandboxState {
IFrameUnsandboxed, IFrameUnsandboxed,
} }
/// Specifies the information required to load an auxiliary browsing context.
#[derive(Deserialize, Serialize)]
pub struct AuxiliaryBrowsingContextLoadInfo {
/// The pipeline opener browsing context.
pub opener_pipeline_id: PipelineId,
/// The new top-level ID for the auxiliary.
pub new_top_level_browsing_context_id: TopLevelBrowsingContextId,
/// The new browsing context ID.
pub new_browsing_context_id: BrowsingContextId,
/// The new pipeline ID for the auxiliary.
pub new_pipeline_id: PipelineId,
}
/// Specifies the information required to load an iframe. /// Specifies the information required to load an iframe.
#[derive(Deserialize, Serialize)] #[derive(Deserialize, Serialize)]
pub struct IFrameLoadInfo { pub struct IFrameLoadInfo {

View file

@ -3,6 +3,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use AnimationState; use AnimationState;
use AuxiliaryBrowsingContextLoadInfo;
use DocumentState; use DocumentState;
use IFrameLoadInfo; use IFrameLoadInfo;
use IFrameLoadInfoWithData; use IFrameLoadInfoWithData;
@ -137,6 +138,8 @@ pub enum ScriptMsg {
ScriptLoadedURLInIFrame(IFrameLoadInfoWithData), ScriptLoadedURLInIFrame(IFrameLoadInfoWithData),
/// A load of the initial `about:blank` has been completed in an IFrame. /// A load of the initial `about:blank` has been completed in an IFrame.
ScriptNewIFrame(IFrameLoadInfo, IpcSender<LayoutControlMsg>), ScriptNewIFrame(IFrameLoadInfo, IpcSender<LayoutControlMsg>),
/// Script has opened a new auxiliary browsing context.
ScriptNewAuxiliary(AuxiliaryBrowsingContextLoadInfo, IpcSender<LayoutControlMsg>),
/// Requests that the constellation set the contents of the clipboard /// Requests that the constellation set the contents of the clipboard
SetClipboardContents(String), SetClipboardContents(String),
/// Mark a new document as active /// Mark a new document as active
@ -196,6 +199,7 @@ impl fmt::Debug for ScriptMsg {
VisibilityChangeComplete(..) => "VisibilityChangeComplete", VisibilityChangeComplete(..) => "VisibilityChangeComplete",
ScriptLoadedURLInIFrame(..) => "ScriptLoadedURLInIFrame", ScriptLoadedURLInIFrame(..) => "ScriptLoadedURLInIFrame",
ScriptNewIFrame(..) => "ScriptNewIFrame", ScriptNewIFrame(..) => "ScriptNewIFrame",
ScriptNewAuxiliary(..) => "ScriptNewAuxiliary",
SetClipboardContents(..) => "SetClipboardContents", SetClipboardContents(..) => "SetClipboardContents",
ActivateDocument => "ActivateDocument", ActivateDocument => "ActivateDocument",
SetDocumentState(..) => "SetDocumentState", SetDocumentState(..) => "SetDocumentState",

View file

@ -284,6 +284,18 @@ impl Browser {
warn!("Failed to send AllowNavigation response: {}", e); warn!("Failed to send AllowNavigation response: {}", e);
} }
} }
EmbedderMsg::AllowOpeningBrowser(response_chan) => {
// Note: would be a place to handle pop-ups config.
// see Step 7 of #the-rules-for-choosing-a-browsing-context-given-a-browsing-context-name
if let Err(e) = response_chan.send(true) {
warn!("Failed to send AllowOpeningBrowser response: {}", e);
};
}
EmbedderMsg::BrowserCreated(new_browser_id) => {
// TODO: properly handle a new "tab"
self.browser_id = Some(new_browser_id);
self.event_queue.push(WindowEvent::SelectBrowser(new_browser_id));
}
EmbedderMsg::KeyEvent(ch, key, state, modified) => { EmbedderMsg::KeyEvent(ch, key, state, modified) => {
self.handle_key_from_servo(browser_id, ch, key, state, modified); self.handle_key_from_servo(browser_id, ch, key, state, modified);
} }

View file

@ -1,5 +1,6 @@
[embedded-credentials.tentative.sub.html] [embedded-credentials.tentative.sub.html]
type: testharness type: testharness
expected: TIMEOUT
[Embedded credentials are treated as network errors.] [Embedded credentials are treated as network errors.]
expected: FAIL expected: FAIL
@ -7,14 +8,14 @@
expected: FAIL expected: FAIL
[Embedded credentials are treated as network errors in new windows.] [Embedded credentials are treated as network errors in new windows.]
expected: FAIL expected: TIMEOUT
[Embedded credentials matching the top-level are not treated as network errors for relative URLs.] [Embedded credentials matching the top-level are not treated as network errors for relative URLs.]
expected: FAIL expected: TIMEOUT
[Embedded credentials matching the top-level are not treated as network errors for same-origin URLs.] [Embedded credentials matching the top-level are not treated as network errors for same-origin URLs.]
expected: FAIL expected: TIMEOUT
[Embedded credentials matching the top-level are treated as network errors for cross-origin URLs.] [Embedded credentials matching the top-level are treated as network errors for cross-origin URLs.]
expected: FAIL expected: TIMEOUT

View file

@ -1,8 +1,9 @@
[resume-timer-on-history-back.html] [resume-timer-on-history-back.html]
type: testharness type: testharness
expected: TIMEOUT
[history.back() handles top level page timer correctly] [history.back() handles top level page timer correctly]
expected: FAIL expected: TIMEOUT
[history.back() handles nested iframe timer correctly] [history.back() handles nested iframe timer correctly]
expected: FAIL expected: NOTRUN

View file

@ -1,6 +0,0 @@
[window-name-after-cross-origin-aux-frame-navigation.sub.html]
type: testharness
expected: ERROR
[Test that the window name is correct]
expected: NOTRUN

View file

@ -1,6 +1,5 @@
[window-name-after-cross-origin-main-frame-navigation.sub.html] [window-name-after-cross-origin-main-frame-navigation.sub.html]
type: testharness type: testharness
expected: ERROR
[window.name should equal "" after a cross-origin main frame navigation] [window.name should equal "" after a cross-origin main frame navigation]
expected: TIMEOUT expected: FAIL

View file

@ -1,6 +0,0 @@
[window-name-after-same-origin-aux-frame-navigation.sub.html]
type: testharness
expected: ERROR
[Test that the window name is correct]
expected: NOTRUN

View file

@ -1,3 +0,0 @@
[005.html]
type: testharness
expected: TIMEOUT

View file

@ -1,3 +0,0 @@
[006.html]
type: testharness
expected: TIMEOUT

View file

@ -1,3 +1,5 @@
[008.html] [008.html]
type: testharness type: testharness
expected: TIMEOUT [Link with onclick form submit to javascript url and href navigation ]
expected: FAIL

View file

@ -1,3 +1,5 @@
[009.html] [009.html]
type: testharness type: testharness
expected: TIMEOUT [Link with onclick form submit to javascript url with document.write and href navigation ]
expected: FAIL

View file

@ -1,4 +0,0 @@
[010.html]
type: testharness
[Link with onclick form submit to javascript url with delayed document.write and href navigation ]
expected: FAIL

View file

@ -1,3 +0,0 @@
[011.html]
type: testharness
expected: TIMEOUT

View file

@ -1,6 +0,0 @@
[child_navigates_parent_submit.html]
type: testharness
expected: TIMEOUT
[Child document navigating parent via submit ]
expected: TIMEOUT

View file

@ -1,4 +0,0 @@
[javascript-url-abort-return-value-string.tentative.html]
[Aborting fetch for javascript:string navigation]
expected: FAIL

View file

@ -1,5 +0,0 @@
[pageload-image-in-popup.html]
expected: ERROR
[The document for a standalone media file should have one child in the body.]
expected: NOTRUN

View file

@ -1,4 +0,0 @@
[history_back_1.html]
[history.back() with session history]
expected: FAIL

View file

@ -1,4 +0,0 @@
[history_forward_1.html]
[history.forward() with session history]
expected: FAIL

View file

@ -1,4 +0,0 @@
[history_go_no_argument.html]
[history.go()]
expected: FAIL

View file

@ -1,4 +0,0 @@
[history_go_to_uri.html]
[history.go() negative tests]
expected: FAIL

View file

@ -1,4 +0,0 @@
[history_go_zero.html]
[history.go(0)]
expected: FAIL

View file

@ -1,24 +1,5 @@
[001.html] [001.html]
type: testharness expected: TIMEOUT
expected: ERROR
[Session history length on initial load]
expected: NOTRUN
[Session history length on adding new iframe]
expected: NOTRUN
[Navigating second iframe]
expected: NOTRUN
[Traversing history back (1)]
expected: NOTRUN
[Navigating first iframe]
expected: NOTRUN
[Traversing history back (2)]
expected: NOTRUN
[Traversing history forward] [Traversing history forward]
expected: NOTRUN expected: NOTRUN

View file

@ -1,12 +1,5 @@
[002.html] [002.html]
type: testharness expected: TIMEOUT
expected: ERROR
[Session history length on initial load]
expected: NOTRUN
[Session history length on adding new iframe]
expected: NOTRUN
[Navigating second iframe] [Navigating second iframe]
expected: NOTRUN expected: TIMEOUT

View file

@ -1,4 +1,5 @@
[traverse_the_history_1.html] [traverse_the_history_1.html]
type: testharness
[Multiple history traversals from the same task] [Multiple history traversals from the same task]
expected: FAIL expected: FAIL

View file

@ -1,4 +1,3 @@
[traverse_the_history_2.html] [traverse_the_history_2.html]
[Multiple history traversals, last would be aborted] [Multiple history traversals, last would be aborted]
expected: FAIL expected: FAIL

View file

@ -1,4 +1,3 @@
[traverse_the_history_4.html] [traverse_the_history_4.html]
[Multiple history traversals, last would be aborted] [Multiple history traversals, last would be aborted]
expected: FAIL expected: FAIL

View file

@ -1,4 +0,0 @@
[traverse_the_history_unload_1.html]
[Traversing the history, unload event is fired on doucment]
expected: FAIL

View file

@ -1,4 +1,6 @@
[traverse_the_history_write_after_load_1.html] [traverse_the_history_write_after_load_1.html]
type: testharness
expected: TIMEOUT
[Traverse the history after document.write after the load event] [Traverse the history after document.write after the load event]
expected: FAIL expected: TIMEOUT

View file

@ -1,4 +0,0 @@
[traverse_the_history_write_after_load_2.html]
[Traverse the history back and forward when a history entry is written after the load event]
expected: FAIL

View file

@ -1,4 +0,0 @@
[traverse_the_history_write_onload_1.html]
[Traverse the history when a history entry is written in the load event]
expected: FAIL

View file

@ -1,4 +0,0 @@
[traverse_the_history_write_onload_2.html]
[Traverse the history back and forward when a history entry is written in the load event]
expected: FAIL

View file

@ -1,5 +0,0 @@
[reload_document_write.html]
type: testharness
[Reload document with document.written content]
expected: FAIL

View file

@ -1,6 +1,5 @@
[scripted_click_assign_during_load.html] [scripted_click_assign_during_load.html]
type: testharness type: testharness
expected: ERROR
[Assignment to location with click during load] [Assignment to location with click during load]
expected: NOTRUN expected: FAIL

View file

@ -1,6 +0,0 @@
[scripted_click_location_assign_during_load.html]
type: testharness
expected: ERROR
[location.assign with click during load]
expected: NOTRUN

View file

@ -1,6 +1,5 @@
[scripted_form_submit_assign_during_load.html] [scripted_form_submit_assign_during_load.html]
type: testharness type: testharness
expected: ERROR
[Assignment to location with form submit during load] [Assignment to location with form submit during load]
expected: NOTRUN expected: FAIL

View file

@ -1,5 +1,4 @@
[navigation-in-onload.tentative.html] [navigation-in-onload.tentative.html]
expected: ERROR
[Navigation in onload handler] [Navigation in onload handler]
expected: NOTRUN expected: FAIL

View file

@ -1,5 +1,3 @@
[cross-origin-objects-on-new-window.html] [cross-origin-objects-on-new-window.html]
type: testharness type: testharness
[Cross-origin behavior of Window and Location on new Window] expected: TIMEOUT
expected: FAIL

View file

@ -1,8 +0,0 @@
[window_length.html]
type: testharness
[Opened window]
expected: FAIL
[Iframe in opened window]
expected: FAIL

View file

@ -1,6 +0,0 @@
[close_beforeunload.html]
type: testharness
expected: ERROR
[Running beforeunload handler in window.close()]
expected: NOTRUN

View file

@ -1,6 +0,0 @@
[close_unload.html]
type: testharness
expected: ERROR
[Running unload handler in window.close()]
expected: NOTRUN

View file

@ -3,12 +3,3 @@
[first argument: absolute url] [first argument: absolute url]
expected: FAIL expected: FAIL
[first argument: empty url]
expected: FAIL
[second argument: passing a non-empty name]
expected: FAIL
[second argument: setting name after opening]
expected: FAIL

View file

@ -1,3 +1,5 @@
[open-features-negative-innerwidth-innerheight.html] [open-features-negative-innerwidth-innerheight.html]
type: testharness type: testharness
expected: ERROR [HTML: window.open `features`: negative values for legacy `innerwidth`, `innerheight`]
expected: FAIL

View file

@ -1,3 +1,5 @@
[open-features-negative-screenx-screeny.html] [open-features-negative-screenx-screeny.html]
type: testharness type: testharness
expected: ERROR [HTML: window.open `features`: negative values for legacy `screenx`, `screeny`]
expected: FAIL

View file

@ -1,3 +1,5 @@
[open-features-negative-top-left.html] [open-features-negative-top-left.html]
type: testharness type: testharness
expected: ERROR [HTML: window.open `features`: negative values for `top`, `left`]
expected: FAIL

View file

@ -1,3 +1,5 @@
[open-features-negative-width-height.html] [open-features-negative-width-height.html]
type: testharness type: testharness
expected: ERROR [HTML: window.open `features`: negative values for `width`, `height`]
expected: FAIL

View file

@ -1,3 +1,5 @@
[open-features-non-integer-height.html] [open-features-non-integer-height.html]
type: testharness type: testharness
expected: ERROR [HTML: window.open `features`: non-integer values for feature `height`]
expected: FAIL

View file

@ -1,3 +1,5 @@
[open-features-non-integer-innerheight.html] [open-features-non-integer-innerheight.html]
type: testharness type: testharness
expected: ERROR [HTML: window.open `features`: non-integer values for legacy feature `innerheight`]
expected: FAIL

View file

@ -1,3 +1,5 @@
[open-features-non-integer-innerwidth.html] [open-features-non-integer-innerwidth.html]
type: testharness type: testharness
expected: ERROR [HTML: window.open `features`: non-integer values for legacy feature `innerwidth`]
expected: FAIL

View file

@ -1,3 +1,5 @@
[open-features-non-integer-left.html] [open-features-non-integer-left.html]
type: testharness type: testharness
expected: ERROR [HTML: window.open `features`: non-integer values for feature `left`]
expected: FAIL

View file

@ -1,3 +1,5 @@
[open-features-non-integer-screenx.html] [open-features-non-integer-screenx.html]
type: testharness type: testharness
expected: ERROR [HTML: window.open `features`: non-integer values for legacy feature `screenx`]
expected: FAIL

View file

@ -1,3 +1,5 @@
[open-features-non-integer-screeny.html] [open-features-non-integer-screeny.html]
type: testharness type: testharness
expected: ERROR [HTML: window.open `features`: non-integer values for legacy feature `screeny`]
expected: FAIL

View file

@ -1,3 +1,5 @@
[open-features-non-integer-top.html] [open-features-non-integer-top.html]
type: testharness type: testharness
expected: ERROR [HTML: window.open `features`: non-integer values for feature `top`]
expected: FAIL

View file

@ -1,3 +1,5 @@
[open-features-non-integer-width.html] [open-features-non-integer-width.html]
type: testharness type: testharness
expected: ERROR [HTML: window.open `features`: non-integer values for feature `width`]
expected: FAIL

View file

@ -1,23 +1,7 @@
[open-features-tokenization-noopener.html] [open-features-tokenization-noopener.html]
type: testharness
[tokenization should skip window features separators before `name`]
expected: FAIL
[feature `name` should be converted to ASCII lowercase] [feature `name` should be converted to ASCII lowercase]
expected: FAIL expected: FAIL
[after `name`, tokenization should skip window features separators that are not "=" or ","]
expected: FAIL
[Tokenizing should ignore window feature separators except "," after initial "=" and before value]
expected: FAIL
[Tokenizing should read characters until first window feature separator as `value`]
expected: FAIL
["noopener" should be based on name (key), not value]
expected: FAIL
[invalid feature names should not tokenize as "noopener"] [invalid feature names should not tokenize as "noopener"]
expected: FAIL expected: FAIL

View file

@ -1,6 +1,5 @@
[discard_iframe_history_1.html] [discard_iframe_history_1.html]
type: testharness type: testharness
expected: ERROR
[Removing iframe from document removes it from history] [Removing iframe from document removes it from history]
expected: NOTRUN expected: FAIL

View file

@ -1,6 +1,5 @@
[discard_iframe_history_2.html] [discard_iframe_history_2.html]
type: testharness type: testharness
expected: ERROR
[Removing iframe from document via innerHTML removes it from history] [Removing iframe from document via innerHTML removes it from history]
expected: NOTRUN expected: FAIL

View file

@ -1,6 +0,0 @@
[discard_iframe_history_3.html]
type: testharness
expected: ERROR
[Removing iframe from document removes it from history]
expected: NOTRUN

View file

@ -1,6 +0,0 @@
[discard_iframe_history_4.html]
type: testharness
expected: ERROR
[Removing iframe from document removes it from history]
expected: NOTRUN

View file

@ -335,9 +335,6 @@
[A SecurityError exception must be thrown when window.stop is accessed from a different origin.] [A SecurityError exception must be thrown when window.stop is accessed from a different origin.]
expected: FAIL expected: FAIL
[A SecurityError exception should not be thrown when window.opener is accessed from a different origin.]
expected: FAIL
[A SecurityError exception should not be thrown when window.blur is accessed from a different origin.] [A SecurityError exception should not be thrown when window.blur is accessed from a different origin.]
expected: FAIL expected: FAIL

View file

@ -1,6 +1,5 @@
[window-open-noopener.html] [window-open-noopener.html]
type: testharness type: testharness
expected: ERROR
[window.open() with 'noopener' should not reuse existing target] [window.open() with 'noopener' should not reuse existing target]
expected: FAIL expected: FAIL
@ -27,15 +26,13 @@
[window-open-noopener.html?_parent] [window-open-noopener.html?_parent]
expected: ERROR
[noopener window.open targeting _parent] [noopener window.open targeting _parent]
expected: NOTRUN expected: FAIL
[window-open-noopener.html?_top] [window-open-noopener.html?_top]
expected: ERROR
[noopener window.open targeting _top] [noopener window.open targeting _top]
expected: NOTRUN expected: FAIL
[window-open-noopener.html?indexed] [window-open-noopener.html?indexed]
@ -63,7 +60,12 @@
[window-open-noopener.html?_self] [window-open-noopener.html?_self]
expected: ERROR
[noopener window.open targeting _self] [noopener window.open targeting _self]
expected: FAIL
[noopener window.open targeting _parent]
expected: NOTRUN
[noopener window.open targeting _top]
expected: NOTRUN expected: NOTRUN

View file

@ -5,9 +5,6 @@
[Window method: blur] [Window method: blur]
expected: FAIL expected: FAIL
[Window method: open]
expected: FAIL
[Window method: confirm] [Window method: confirm]
expected: FAIL expected: FAIL
@ -23,9 +20,6 @@
[Window readonly attribute: applicationCache] [Window readonly attribute: applicationCache]
expected: FAIL expected: FAIL
[Window attribute: opener]
expected: FAIL
[Window attribute: onmousewheel] [Window attribute: onmousewheel]
expected: FAIL expected: FAIL

View file

@ -1,3 +1,5 @@
[opener-closed.html] [opener-closed.html]
type: testharness type: testharness
expected: TIMEOUT expected: TIMEOUT
[An auxiliary browsing context should report `null` for `window.opener` when that browsing context is discarded]
expected: TIMEOUT

View file

@ -1,3 +1,5 @@
[opener-multiple.html] [opener-multiple.html]
type: testharness type: testharness
expected: TIMEOUT expected: TIMEOUT
[An auxiliary browsing context should be able to open another auxiliary browsing context]
expected: TIMEOUT

View file

@ -1,5 +1,6 @@
[opener-noreferrer.html] [opener-noreferrer.html]
type: testharness type: testharness
expected: TIMEOUT
[Auxiliary browsing context created with `rel="noreferrer"` should report `window.opener` `null`] [Auxiliary browsing context created with `rel="noreferrer"` should report `window.opener` `null`]
expected: FAIL expected: TIMEOUT

View file

@ -1,3 +1,7 @@
[opener.html] [opener.html]
type: testharness type: testharness
expected: TIMEOUT expected: TIMEOUT
[Newly-created auxiliary browsing context should report `window.opener`]
expected: TIMEOUT
[Browsing context created with `window.open` should report `window.opener`]
expected: FAIL

View file

@ -1,5 +1,6 @@
[choose-_blank-002.html] [choose-_blank-002.html]
type: testharness type: testharness
expected: TIMEOUT
[Context for opened noreferrer link targeted to "_blank" should not have opener reference] [Context for opened noreferrer link targeted to "_blank" should not have opener reference]
expected: FAIL expected: TIMEOUT

View file

@ -0,0 +1,6 @@
[choose-_blank-003.html]
type: testharness
expected: TIMEOUT
[Context created by link targeting "_blank" should retain opener reference]
expected: TIMEOUT

View file

@ -2,7 +2,3 @@
type: testharness type: testharness
[A embedded browsing context has empty-string default name] [A embedded browsing context has empty-string default name]
expected: FAIL expected: FAIL
[A browsing context which is opened by window.open() method with '_blank' parameter has empty-string default name]
expected: FAIL

View file

@ -1,6 +0,0 @@
[choose-existing-001.html]
type: testharness
expected: TIMEOUT
[An existing browsing context must be chosen if the given name is the same as its name]
expected: TIMEOUT

View file

@ -1,5 +1,6 @@
[noreferrer-null-opener.html] [noreferrer-null-opener.html]
type: testharness type: testharness
expected: TIMEOUT
[rel=noreferrer nullifies window.opener] [rel=noreferrer nullifies window.opener]
expected: FAIL expected: TIMEOUT

View file

@ -1,6 +1,13 @@
[noreferrer-window-name.html] [noreferrer-window-name.html]
type: testharness type: testharness
expected: TIMEOUT expected: TIMEOUT
[rel=noreferrer and reuse of names]
[Following a noreferrer link with a named target should not cause creation of a window that can be targeted by another noreferrer link with the same named target]
expected: TIMEOUT expected: TIMEOUT
[Targeting a rel=noreferrer link at an existing named subframe should work]
expected: FAIL
[Targeting a rel=noreferrer link at an existing named window should work]
expected: FAIL

View file

@ -1,3 +1,5 @@
[targeting-cross-origin-nested-browsing-contexts.html] [targeting-cross-origin-nested-browsing-contexts.html]
type: testharness type: testharness
expected: TIMEOUT expected: TIMEOUT
[Targeting nested browsing contexts]
expected: FAIL

View file

@ -1,7 +1,4 @@
[usvstring-reflection.html] [usvstring-reflection.html]
[window.open : unpaired surrogate codepoint should be replaced with U+FFFD]
expected: FAIL
[anchor : unpaired surrogate codepoint should be replaced with U+FFFD] [anchor : unpaired surrogate codepoint should be replaced with U+FFFD]
expected: FAIL expected: FAIL
@ -17,12 +14,6 @@
[source : unpaired surrogate codepoint should be replaced with U+FFFD] [source : unpaired surrogate codepoint should be replaced with U+FFFD]
expected: FAIL expected: FAIL
[Document URLs: unpaired surrogate codepoint should be replaced with U+FFFD]
expected: FAIL
[location.href : unpaired surrogate codepoint should be replaced with U+FFFD]
expected: FAIL
[sendBeacon URL: unpaired surrogate codepoint should not make any exceptions.] [sendBeacon URL: unpaired surrogate codepoint should not make any exceptions.]
expected: FAIL expected: FAIL

View file

@ -1,6 +1,5 @@
[iframe_sandbox_popups_escaping-1.html] [iframe_sandbox_popups_escaping-1.html]
type: testharness type: testharness
expected: TIMEOUT
[Check that popups from a sandboxed iframe escape the sandbox if\n allow-popups-to-escape-sandbox is used] [Check that popups from a sandboxed iframe escape the sandbox if\n allow-popups-to-escape-sandbox is used]
expected: TIMEOUT expected: FAIL

View file

@ -1,6 +1,5 @@
[iframe_sandbox_popups_escaping-2.html] [iframe_sandbox_popups_escaping-2.html]
type: testharness type: testharness
expected: TIMEOUT
[Check that popups from a sandboxed iframe escape the sandbox if\n allow-popups-to-escape-sandbox is used] [Check that popups from a sandboxed iframe escape the sandbox if\n allow-popups-to-escape-sandbox is used]
expected: TIMEOUT expected: FAIL

View file

@ -1,6 +1,5 @@
[iframe_sandbox_popups_nonescaping-1.html] [iframe_sandbox_popups_nonescaping-1.html]
type: testharness type: testharness
expected: TIMEOUT
[Check that popups from a sandboxed iframe do not escape the sandbox] [Check that popups from a sandboxed iframe do not escape the sandbox]
expected: NOTRUN expected: FAIL

View file

@ -1,6 +1,5 @@
[iframe_sandbox_popups_nonescaping-2.html] [iframe_sandbox_popups_nonescaping-2.html]
type: testharness type: testharness
expected: TIMEOUT
[Check that popups from a sandboxed iframe do not escape the sandbox] [Check that popups from a sandboxed iframe do not escape the sandbox]
expected: NOTRUN expected: FAIL

View file

@ -1,3 +1,11 @@
[submission-checks.window.html] [submission-checks.window.html]
type: testharness type: testharness
expected: TIMEOUT [<form> not connected to a document cannot navigate]
expected: FAIL
[<form> not connected to a document after submit event cannot navigate]
expected: FAIL
[<form> in a navigated document cannot navigate]
expected: FAIL

View file

@ -2,5 +2,14 @@
type: testharness type: testharness
expected: ERROR expected: ERROR
[Check that rel=noopener with target=_self does a normal load] [Check that rel=noopener with target=_self does a normal load]
expected: FAIL
[Check that targeting of rel=noopener with a given name ignores an existing window with that name]
expected: NOTRUN expected: NOTRUN
[Check that rel=noopener with target=_parent does a normal load]
expected: FAIL
[Check that rel=noopener with target=_top does a normal load]
expected: FAIL

View file

@ -2,7 +2,7 @@
type: testharness type: testharness
expected: TIMEOUT expected: TIMEOUT
[The entry settings object while executing the compiled callback via Web IDL's invoke must be that of the node document] [The entry settings object while executing the compiled callback via Web IDL's invoke must be that of the node document]
expected: TIMEOUT expected: FAIL
[The incumbent settings object while executing the compiled callback via Web IDL's invoke must be that of the node document] [The incumbent settings object while executing the compiled callback via Web IDL's invoke must be that of the node document]
expected: TIMEOUT expected: TIMEOUT

View file

@ -1,6 +1,5 @@
[003.html] [003.html]
type: testharness type: testharness
expected: TIMEOUT
[WebSockets: navigating nested browsing context] [WebSockets: navigating nested browsing context]
expected: TIMEOUT expected: FAIL

View file

@ -1,5 +1,5 @@
[004.html] [004.html]
type: testharness type: testharness
[WebSockets: navigating nested browsing context with closed websocket] [WebSockets: navigating nested browsing context with closed websocket]
expected: TIMEOUT expected: FAIL

View file

@ -1,6 +0,0 @@
[storage_local_window_open.html]
type: testharness
bug: https://github.com/servo/servo/issues/13241
[A new window to make sure there is a copy of the previous window's localStorage, and that they do not diverge after a change]
expected: FAIL

View file

@ -1,6 +1,6 @@
[open-url-multi-window-6.htm] [open-url-multi-window-6.htm]
type: testharness type: testharness
expected: ERROR expected: TIMEOUT
[XMLHttpRequest: open() in document that is not fully active (but may be active) should throw] [XMLHttpRequest: open() in document that is not fully active (but may be active) should throw]
expected: NOTRUN expected: TIMEOUT