From f408b798c4666eddeb8b52d8965d7d4a6942e066 Mon Sep 17 00:00:00 2001 From: Gregory Terzian Date: Sun, 22 Apr 2018 12:58:30 +0800 Subject: [PATCH 1/7] implement window.open, create auxiliary browsing context --- components/constellation/constellation.rs | 61 +++++++- components/embedder_traits/lib.rs | 6 + components/script/dom/htmlanchorelement.rs | 82 ++++++---- components/script/dom/htmlformelement.rs | 55 ++++--- components/script/dom/webidls/Window.webidl | 4 +- components/script/dom/window.rs | 9 ++ components/script/dom/windowproxy.rs | 143 +++++++++++++++++- components/script/script_thread.rs | 12 ++ components/script_traits/lib.rs | 13 ++ components/script_traits/script_msg.rs | 4 + ports/servo/browser.rs | 12 ++ ...mbedded-credentials.tentative.sub.html.ini | 9 +- .../resume-timer-on-history-back.html.ini | 5 +- ...s-origin-aux-frame-navigation.sub.html.ini | 6 - ...-origin-main-frame-navigation.sub.html.ini | 3 +- ...e-origin-aux-frame-navigation.sub.html.ini | 6 - .../navigating-across-documents/005.html.ini | 3 - .../navigating-across-documents/006.html.ini | 3 - .../navigating-across-documents/008.html.ini | 4 +- .../navigating-across-documents/009.html.ini | 4 +- .../navigating-across-documents/010.html.ini | 4 - .../navigating-across-documents/011.html.ini | 3 - .../child_navigates_parent_submit.html.ini | 6 - ...ort-return-value-string.tentative.html.ini | 4 - .../pageload-image-in-popup.html.ini | 5 - .../history_back_1.html.ini | 4 - .../history_forward_1.html.ini | 4 - .../history_go_no_argument.html.ini | 4 - .../history_go_to_uri.html.ini | 4 - .../history_go_zero.html.ini | 4 - .../joint_session_history/001.html.ini | 21 +-- .../joint_session_history/002.html.ini | 11 +- .../traverse_the_history_1.html.ini | 1 + .../traverse_the_history_2.html.ini | 1 - .../traverse_the_history_4.html.ini | 1 - .../traverse_the_history_unload_1.html.ini | 4 - ...se_the_history_write_after_load_1.html.ini | 4 +- ...se_the_history_write_after_load_2.html.ini | 4 - ...averse_the_history_write_onload_1.html.ini | 4 - ...averse_the_history_write_onload_2.html.ini | 4 - .../reload_document_write.html.ini | 5 - ...scripted_click_assign_during_load.html.ini | 3 +- ...click_location_assign_during_load.html.ini | 6 - ...ed_form_submit_assign_during_load.html.ini | 3 +- .../navigation-in-onload.tentative.html.ini | 3 +- ...ross-origin-objects-on-new-window.html.ini | 4 +- .../window_length.html.ini | 8 - .../close_beforeunload.html.ini | 6 - .../close_unload.html.ini | 6 - ...creating_browsing_context_test_01.html.ini | 9 -- ...s-negative-innerwidth-innerheight.html.ini | 4 +- ...features-negative-screenx-screeny.html.ini | 4 +- .../open-features-negative-top-left.html.ini | 4 +- ...en-features-negative-width-height.html.ini | 4 +- .../open-features-non-integer-height.html.ini | 4 +- ...-features-non-integer-innerheight.html.ini | 4 +- ...n-features-non-integer-innerwidth.html.ini | 4 +- .../open-features-non-integer-left.html.ini | 4 +- ...open-features-non-integer-screenx.html.ini | 4 +- ...open-features-non-integer-screeny.html.ini | 4 +- .../open-features-non-integer-top.html.ini | 4 +- .../open-features-non-integer-width.html.ini | 4 +- ...en-features-tokenization-noopener.html.ini | 16 -- .../discard_iframe_history_1.html.ini | 3 +- .../discard_iframe_history_2.html.ini | 3 +- .../discard_iframe_history_3.html.ini | 6 - .../discard_iframe_history_4.html.ini | 6 - .../window-security.https.html.ini | 3 - .../window-open-noopener.html.ini | 14 +- .../window-properties.https.html.ini | 6 - .../opener-closed.html.ini | 2 + .../opener-multiple.html.ini | 2 + .../opener-noreferrer.html.ini | 3 +- .../opener.html.ini | 4 + .../choose-_blank-002.html.ini | 3 +- .../choose-_blank-003.html.ini | 6 + .../choose-default-001.html.ini | 4 - .../choose-existing-001.html.ini | 6 - .../windows/noreferrer-null-opener.html.ini | 3 +- .../windows/noreferrer-window-name.html.ini | 9 +- ...s-origin-nested-browsing-contexts.html.ini | 2 + .../html/dom/usvstring-reflection.html.ini | 9 -- .../iframe_sandbox_popups_escaping-1.html.ini | 3 +- .../iframe_sandbox_popups_escaping-2.html.ini | 3 +- ...rame_sandbox_popups_nonescaping-1.html.ini | 3 +- ...rame_sandbox_popups_nonescaping-2.html.ini | 3 +- .../submission-checks.window.js.ini | 10 +- .../htmlanchorelement_noopener.html.ini | 9 ++ ...le-event-handler-settings-objects.html.ini | 2 +- .../websockets/unload-a-document/003.html.ini | 3 +- .../websockets/unload-a-document/004.html.ini | 2 +- .../storage_local_window_open.html.ini | 6 - .../xhr/open-url-multi-window-6.htm.ini | 4 +- 93 files changed, 476 insertions(+), 324 deletions(-) delete mode 100644 tests/wpt/metadata/html/browsers/browsing-the-web/history-traversal/window-name-after-cross-origin-aux-frame-navigation.sub.html.ini delete mode 100644 tests/wpt/metadata/html/browsers/browsing-the-web/history-traversal/window-name-after-same-origin-aux-frame-navigation.sub.html.ini delete mode 100644 tests/wpt/metadata/html/browsers/browsing-the-web/navigating-across-documents/005.html.ini delete mode 100644 tests/wpt/metadata/html/browsers/browsing-the-web/navigating-across-documents/006.html.ini delete mode 100644 tests/wpt/metadata/html/browsers/browsing-the-web/navigating-across-documents/010.html.ini delete mode 100644 tests/wpt/metadata/html/browsers/browsing-the-web/navigating-across-documents/011.html.ini delete mode 100644 tests/wpt/metadata/html/browsers/browsing-the-web/navigating-across-documents/child_navigates_parent_submit.html.ini delete mode 100644 tests/wpt/metadata/html/browsers/browsing-the-web/navigating-across-documents/javascript-url-abort/javascript-url-abort-return-value-string.tentative.html.ini delete mode 100644 tests/wpt/metadata/html/browsers/browsing-the-web/read-media/pageload-image-in-popup.html.ini delete mode 100644 tests/wpt/metadata/html/browsers/history/the-history-interface/history_back_1.html.ini delete mode 100644 tests/wpt/metadata/html/browsers/history/the-history-interface/history_forward_1.html.ini delete mode 100644 tests/wpt/metadata/html/browsers/history/the-history-interface/history_go_no_argument.html.ini delete mode 100644 tests/wpt/metadata/html/browsers/history/the-history-interface/history_go_to_uri.html.ini delete mode 100644 tests/wpt/metadata/html/browsers/history/the-history-interface/history_go_zero.html.ini delete mode 100644 tests/wpt/metadata/html/browsers/history/the-history-interface/traverse_the_history_unload_1.html.ini delete mode 100644 tests/wpt/metadata/html/browsers/history/the-history-interface/traverse_the_history_write_after_load_2.html.ini delete mode 100644 tests/wpt/metadata/html/browsers/history/the-history-interface/traverse_the_history_write_onload_1.html.ini delete mode 100644 tests/wpt/metadata/html/browsers/history/the-history-interface/traverse_the_history_write_onload_2.html.ini delete mode 100644 tests/wpt/metadata/html/browsers/history/the-location-interface/reload_document_write.html.ini delete mode 100644 tests/wpt/metadata/html/browsers/history/the-location-interface/scripted_click_location_assign_during_load.html.ini delete mode 100644 tests/wpt/metadata/html/browsers/the-window-object/accessing-other-browsing-contexts/window_length.html.ini delete mode 100644 tests/wpt/metadata/html/browsers/the-window-object/apis-for-creating-and-navigating-browsing-contexts-by-name/close_beforeunload.html.ini delete mode 100644 tests/wpt/metadata/html/browsers/the-window-object/apis-for-creating-and-navigating-browsing-contexts-by-name/close_unload.html.ini delete mode 100644 tests/wpt/metadata/html/browsers/the-window-object/garbage-collection-and-browsing-contexts/discard_iframe_history_3.html.ini delete mode 100644 tests/wpt/metadata/html/browsers/the-window-object/garbage-collection-and-browsing-contexts/discard_iframe_history_4.html.ini create mode 100644 tests/wpt/metadata/html/browsers/windows/browsing-context-names/choose-_blank-003.html.ini delete mode 100644 tests/wpt/metadata/html/browsers/windows/browsing-context-names/choose-existing-001.html.ini delete mode 100644 tests/wpt/metadata/webstorage/storage_local_window_open.html.ini diff --git a/components/constellation/constellation.rs b/components/constellation/constellation.rs index 8eb00583932..f03643bdbd5 100644 --- a/components/constellation/constellation.rs +++ b/components/constellation/constellation.rs @@ -123,7 +123,7 @@ use network_listener::NetworkListener; use pipeline::{InitialPipelineState, Pipeline}; use profile_traits::mem; 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::{DocumentActivity, DocumentState, LayoutControlMsg, LoadData}; use script_traits::{IFrameLoadInfo, IFrameLoadInfoWithData, IFrameSandboxState, TimerSchedulerMsg}; @@ -1121,6 +1121,9 @@ where FromScriptMsg::ScriptNewIFrame(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) => { 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) { + 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) { self.compositor_proxy .send(ToCompositorMsg::PendingPaintMetric(pipeline_id, epoch)) diff --git a/components/embedder_traits/lib.rs b/components/embedder_traits/lib.rs index b1698c95728..3d932281e0c 100644 --- a/components/embedder_traits/lib.rs +++ b/components/embedder_traits/lib.rs @@ -84,6 +84,10 @@ pub enum EmbedderMsg { Alert(String, IpcSender<()>), /// Wether or not to follow a link AllowNavigation(ServoUrl, IpcSender), + /// Whether or not to allow script to open a new tab/browser + AllowOpeningBrowser(IpcSender), + /// A new browser was created by script + BrowserCreated(TopLevelBrowsingContextId), /// Wether or not to unload a document AllowUnload(IpcSender), /// Sends an unconsumed key event back to the embedder. @@ -143,6 +147,8 @@ impl Debug for EmbedderMsg { EmbedderMsg::ShowIME(..) => write!(f, "ShowIME"), EmbedderMsg::HideIME => write!(f, "HideIME"), EmbedderMsg::Shutdown => write!(f, "Shutdown"), + EmbedderMsg::AllowOpeningBrowser(..) => write!(f, "AllowOpeningBrowser"), + EmbedderMsg::BrowserCreated(..) => write!(f, "BrowserCreated") } } } diff --git a/components/script/dom/htmlanchorelement.rs b/components/script/dom/htmlanchorelement.rs index e48385ed692..657ed992441 100644 --- a/components/script/dom/htmlanchorelement.rs +++ b/components/script/dom/htmlanchorelement.rs @@ -574,45 +574,61 @@ impl Activatable for HTMLAnchorElement { } } -/// -fn is_current_browsing_context(target: DOMString) -> bool { - target.is_empty() || target == "_self" -} - /// pub fn follow_hyperlink(subject: &Element, hyperlink_suffix: Option, referrer_policy: Option) { - // Step 1: replace. - // Step 2: source browsing context. - // Step 3: target browsing context. - let target = subject.get_attribute(&ns!(), &local_name!("target")); + // Step 1: TODO: If subject cannot navigate, then return. + // Step 2, done in Step 7. - // 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 url = match document.url().join(&href) { - Ok(url) => url, - Err(_) => return, + let window = document.window(); + + // 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. - if let Some(target) = target { - if !is_current_browsing_context(target.Value()) { - // https://github.com/servo/servo/issues/13241 + // Step 7. + let (maybe_chosen, replace) = match target_attribute_value { + Some(name) => source.choose_browsing_context(name.Value(), noopener), + 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); - - let window = document.window(); - window.load_url(url, false, false, referrer_policy); + // Step 13, 14. + debug!("following hyperlink to {}", url); + target_window.load_url(url, replace, false, referrer_policy); + }; } diff --git a/components/script/dom/htmlformelement.rs b/components/script/dom/htmlformelement.rs index 27a64d00cda..d13ac0e5c98 100755 --- a/components/script/dom/htmlformelement.rs +++ b/components/script/dom/htmlformelement.rs @@ -41,6 +41,7 @@ use dom::node::{Node, NodeFlags, UnbindContext, VecPreOrderInsertionHelper}; use dom::node::{document_from_node, window_from_node}; use dom::validitystate::ValidationFlags; use dom::virtualmethods::VirtualMethods; +use dom::window::Window; use dom_struct::dom_struct; use encoding_rs::{Encoding, UTF_8}; use html5ever::{LocalName, Prefix}; @@ -337,10 +338,24 @@ impl HTMLFormElement { let scheme = action_components.scheme().to_owned(); let enctype = submitter.enctype(); 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 match (&*scheme, method) { @@ -351,17 +366,17 @@ impl HTMLFormElement { // https://html.spec.whatwg.org/multipage/#submit-mutate-action ("http", FormMethod::FormGet) | ("https", FormMethod::FormGet) | ("data", FormMethod::FormGet) => { 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 ("http", FormMethod::FormPost) | ("https", FormMethod::FormPost) => { 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 ("file", _) | ("about", _) | ("data", FormMethod::FormPost) | ("ftp", _) | ("javascript", _) => { - self.plan_to_navigate(load_data); + self.plan_to_navigate(load_data, &target_window); } ("mailto", FormMethod::FormPost) => { // TODO: Mail as body @@ -376,7 +391,11 @@ impl HTMLFormElement { } // https://html.spec.whatwg.org/multipage/#submit-mutate-action - fn mutate_action_url(&self, form_data: &mut Vec, mut load_data: LoadData, encoding: &'static Encoding) { + fn mutate_action_url(&self, + form_data: &mut Vec, + mut load_data: LoadData, + encoding: &'static Encoding, + target: &Window) { let charset = encoding.name(); 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() .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 - fn submit_entity_body(&self, form_data: &mut Vec, mut load_data: LoadData, - enctype: FormEncType, encoding: &'static Encoding) { + fn submit_entity_body(&self, + form_data: &mut Vec, + mut load_data: LoadData, + enctype: FormEncType, + encoding: &'static Encoding, + target: &Window) { let boundary = generate_boundary(); let bytes = match enctype { FormEncType::UrlEncoded => { @@ -415,7 +438,7 @@ impl HTMLFormElement { }; 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>) @@ -426,9 +449,7 @@ impl HTMLFormElement { } /// [Planned navigation](https://html.spec.whatwg.org/multipage/#planned-navigation) - fn plan_to_navigate(&self, load_data: LoadData) { - let window = window_from_node(self); - + fn plan_to_navigate(&self, load_data: LoadData, target: &Window) { // Step 1 // Each planned navigation task is tagged with a generation ID, and // before the task is handled, it first checks whether the HTMLFormElement's @@ -437,8 +458,8 @@ impl HTMLFormElement { self.generation_id.set(generation_id); // Step 2. - let pipeline_id = window.upcast::().pipeline_id(); - let script_chan = window.main_thread_script_chan().clone(); + let pipeline_id = target.upcast::().pipeline_id(); + let script_chan = target.main_thread_script_chan().clone(); let this = Trusted::new(self); let task = task!(navigate_to_form_planned_navigation: move || { if generation_id != this.root().generation_id.get() { @@ -452,7 +473,7 @@ impl HTMLFormElement { }); // 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 diff --git a/components/script/dom/webidls/Window.webidl b/components/script/dom/webidls/Window.webidl index d7e22b1f60c..c143ec56bbf 100644 --- a/components/script/dom/webidls/Window.webidl +++ b/components/script/dom/webidls/Window.webidl @@ -40,8 +40,8 @@ // https://github.com/whatwg/html/issues/2115 [Replaceable] readonly attribute WindowProxy? parent; readonly attribute Element? frameElement; - //WindowProxy open(optional DOMString url = "about:blank", optional DOMString target = "_blank", - // optional DOMString features = "", optional boolean replace = false); + WindowProxy? open(optional DOMString url = "about:blank", optional DOMString target = "_blank", + optional DOMString features = ""); //getter WindowProxy (unsigned long index); // https://github.com/servo/servo/issues/14453 diff --git a/components/script/dom/window.rs b/components/script/dom/window.rs index 4d6fca64cbd..41b7441c3bf 100644 --- a/components/script/dom/window.rs +++ b/components/script/dom/window.rs @@ -565,6 +565,15 @@ impl WindowMethods for Window { doc.abort(); } + // https://html.spec.whatwg.org/multipage/#dom-open + fn Open(&self, + url: DOMString, + target: DOMString, + features: DOMString) + -> Option> { + self.window_proxy().open(url, target, features) + } + // https://html.spec.whatwg.org/multipage/#dom-window-closed fn Closed(&self) -> bool { self.window_proxy.get() diff --git a/components/script/dom/windowproxy.rs b/components/script/dom/windowproxy.rs index bfd75f879dc..10c925cb28d 100644 --- a/components/script/dom/windowproxy.rs +++ b/components/script/dom/windowproxy.rs @@ -13,10 +13,12 @@ use dom::bindings::str::DOMString; use dom::bindings::trace::JSTraceable; use dom::bindings::utils::{WindowProxyHandler, get_array_index_from_id, AsVoidPtr}; use dom::dissimilaroriginwindow::DissimilarOriginWindow; +use dom::document::Document; use dom::element::Element; use dom::globalscope::GlobalScope; use dom::window::Window; use dom_struct::dom_struct; +use embedder_traits::EmbedderMsg; use ipc_channel::ipc; use js::JSCLASS_IS_GLOBAL; use js::glue::{CreateWrapperProxyHandler, ProxyTraps}; @@ -42,7 +44,9 @@ use msg::constellation_msg::BrowsingContextId; use msg::constellation_msg::PipelineId; use msg::constellation_msg::TopLevelBrowsingContextId; 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::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> { + 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> { + // 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>, 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) { self.discarded.set(true); } @@ -220,6 +356,11 @@ impl WindowProxy { self.frame_element.r() } + pub fn document(&self) -> Option> { + self.currently_active.get() + .and_then(|id| ScriptThread::find_document(id)) + } + pub fn parent(&self) -> Option<&WindowProxy> { self.parent.r() } diff --git a/components/script/script_thread.rs b/components/script/script_thread.rs index 13c5f1f7ba4..9e20a24e55b 100644 --- a/components/script/script_thread.rs +++ b/components/script/script_thread.rs @@ -721,6 +721,18 @@ impl ScriptThread { })) } + pub fn find_window_proxy_by_name(name: &DOMString) -> Option> { + 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 { SCRIPT_THREAD_ROOT.with(|root| { let script_thread = unsafe { &*root.get().unwrap() }; diff --git a/components/script_traits/lib.rs b/components/script_traits/lib.rs index 6075cc6fc43..476f41ef0f1 100644 --- a/components/script_traits/lib.rs +++ b/components/script_traits/lib.rs @@ -576,6 +576,19 @@ pub enum IFrameSandboxState { 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. #[derive(Deserialize, Serialize)] pub struct IFrameLoadInfo { diff --git a/components/script_traits/script_msg.rs b/components/script_traits/script_msg.rs index 762300827c8..3668fd1e2fa 100644 --- a/components/script_traits/script_msg.rs +++ b/components/script_traits/script_msg.rs @@ -3,6 +3,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use AnimationState; +use AuxiliaryBrowsingContextLoadInfo; use DocumentState; use IFrameLoadInfo; use IFrameLoadInfoWithData; @@ -137,6 +138,8 @@ pub enum ScriptMsg { ScriptLoadedURLInIFrame(IFrameLoadInfoWithData), /// A load of the initial `about:blank` has been completed in an IFrame. ScriptNewIFrame(IFrameLoadInfo, IpcSender), + /// Script has opened a new auxiliary browsing context. + ScriptNewAuxiliary(AuxiliaryBrowsingContextLoadInfo, IpcSender), /// Requests that the constellation set the contents of the clipboard SetClipboardContents(String), /// Mark a new document as active @@ -196,6 +199,7 @@ impl fmt::Debug for ScriptMsg { VisibilityChangeComplete(..) => "VisibilityChangeComplete", ScriptLoadedURLInIFrame(..) => "ScriptLoadedURLInIFrame", ScriptNewIFrame(..) => "ScriptNewIFrame", + ScriptNewAuxiliary(..) => "ScriptNewAuxiliary", SetClipboardContents(..) => "SetClipboardContents", ActivateDocument => "ActivateDocument", SetDocumentState(..) => "SetDocumentState", diff --git a/ports/servo/browser.rs b/ports/servo/browser.rs index f7808b791e8..161781a8052 100644 --- a/ports/servo/browser.rs +++ b/ports/servo/browser.rs @@ -284,6 +284,18 @@ impl Browser { 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) => { self.handle_key_from_servo(browser_id, ch, key, state, modified); } diff --git a/tests/wpt/metadata/fetch/security/embedded-credentials.tentative.sub.html.ini b/tests/wpt/metadata/fetch/security/embedded-credentials.tentative.sub.html.ini index 35196e2d082..e0e97f1c6b1 100644 --- a/tests/wpt/metadata/fetch/security/embedded-credentials.tentative.sub.html.ini +++ b/tests/wpt/metadata/fetch/security/embedded-credentials.tentative.sub.html.ini @@ -1,5 +1,6 @@ [embedded-credentials.tentative.sub.html] type: testharness + expected: TIMEOUT [Embedded credentials are treated as network errors.] expected: FAIL @@ -7,14 +8,14 @@ expected: FAIL [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.] - expected: FAIL + expected: TIMEOUT [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.] - expected: FAIL + expected: TIMEOUT diff --git a/tests/wpt/metadata/html/browsers/browsing-the-web/history-traversal/persisted-user-state-restoration/resume-timer-on-history-back.html.ini b/tests/wpt/metadata/html/browsers/browsing-the-web/history-traversal/persisted-user-state-restoration/resume-timer-on-history-back.html.ini index 65ec052f25f..e820a708df3 100644 --- a/tests/wpt/metadata/html/browsers/browsing-the-web/history-traversal/persisted-user-state-restoration/resume-timer-on-history-back.html.ini +++ b/tests/wpt/metadata/html/browsers/browsing-the-web/history-traversal/persisted-user-state-restoration/resume-timer-on-history-back.html.ini @@ -1,8 +1,9 @@ [resume-timer-on-history-back.html] type: testharness + expected: TIMEOUT [history.back() handles top level page timer correctly] - expected: FAIL + expected: TIMEOUT [history.back() handles nested iframe timer correctly] - expected: FAIL + expected: NOTRUN diff --git a/tests/wpt/metadata/html/browsers/browsing-the-web/history-traversal/window-name-after-cross-origin-aux-frame-navigation.sub.html.ini b/tests/wpt/metadata/html/browsers/browsing-the-web/history-traversal/window-name-after-cross-origin-aux-frame-navigation.sub.html.ini deleted file mode 100644 index 99ceba7dc39..00000000000 --- a/tests/wpt/metadata/html/browsers/browsing-the-web/history-traversal/window-name-after-cross-origin-aux-frame-navigation.sub.html.ini +++ /dev/null @@ -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 - diff --git a/tests/wpt/metadata/html/browsers/browsing-the-web/history-traversal/window-name-after-cross-origin-main-frame-navigation.sub.html.ini b/tests/wpt/metadata/html/browsers/browsing-the-web/history-traversal/window-name-after-cross-origin-main-frame-navigation.sub.html.ini index f8a10f8f098..f3840120f49 100644 --- a/tests/wpt/metadata/html/browsers/browsing-the-web/history-traversal/window-name-after-cross-origin-main-frame-navigation.sub.html.ini +++ b/tests/wpt/metadata/html/browsers/browsing-the-web/history-traversal/window-name-after-cross-origin-main-frame-navigation.sub.html.ini @@ -1,6 +1,5 @@ [window-name-after-cross-origin-main-frame-navigation.sub.html] type: testharness - expected: ERROR [window.name should equal "" after a cross-origin main frame navigation] - expected: TIMEOUT + expected: FAIL diff --git a/tests/wpt/metadata/html/browsers/browsing-the-web/history-traversal/window-name-after-same-origin-aux-frame-navigation.sub.html.ini b/tests/wpt/metadata/html/browsers/browsing-the-web/history-traversal/window-name-after-same-origin-aux-frame-navigation.sub.html.ini deleted file mode 100644 index 51401a84708..00000000000 --- a/tests/wpt/metadata/html/browsers/browsing-the-web/history-traversal/window-name-after-same-origin-aux-frame-navigation.sub.html.ini +++ /dev/null @@ -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 - diff --git a/tests/wpt/metadata/html/browsers/browsing-the-web/navigating-across-documents/005.html.ini b/tests/wpt/metadata/html/browsers/browsing-the-web/navigating-across-documents/005.html.ini deleted file mode 100644 index 6a14cc88a26..00000000000 --- a/tests/wpt/metadata/html/browsers/browsing-the-web/navigating-across-documents/005.html.ini +++ /dev/null @@ -1,3 +0,0 @@ -[005.html] - type: testharness - expected: TIMEOUT diff --git a/tests/wpt/metadata/html/browsers/browsing-the-web/navigating-across-documents/006.html.ini b/tests/wpt/metadata/html/browsers/browsing-the-web/navigating-across-documents/006.html.ini deleted file mode 100644 index 9701e26d8e9..00000000000 --- a/tests/wpt/metadata/html/browsers/browsing-the-web/navigating-across-documents/006.html.ini +++ /dev/null @@ -1,3 +0,0 @@ -[006.html] - type: testharness - expected: TIMEOUT diff --git a/tests/wpt/metadata/html/browsers/browsing-the-web/navigating-across-documents/008.html.ini b/tests/wpt/metadata/html/browsers/browsing-the-web/navigating-across-documents/008.html.ini index 9fbd1fc405a..f06bb4cfea7 100644 --- a/tests/wpt/metadata/html/browsers/browsing-the-web/navigating-across-documents/008.html.ini +++ b/tests/wpt/metadata/html/browsers/browsing-the-web/navigating-across-documents/008.html.ini @@ -1,3 +1,5 @@ [008.html] type: testharness - expected: TIMEOUT + [Link with onclick form submit to javascript url and href navigation ] + expected: FAIL + diff --git a/tests/wpt/metadata/html/browsers/browsing-the-web/navigating-across-documents/009.html.ini b/tests/wpt/metadata/html/browsers/browsing-the-web/navigating-across-documents/009.html.ini index 2633411d86e..f2431729df2 100644 --- a/tests/wpt/metadata/html/browsers/browsing-the-web/navigating-across-documents/009.html.ini +++ b/tests/wpt/metadata/html/browsers/browsing-the-web/navigating-across-documents/009.html.ini @@ -1,3 +1,5 @@ [009.html] type: testharness - expected: TIMEOUT + [Link with onclick form submit to javascript url with document.write and href navigation ] + expected: FAIL + diff --git a/tests/wpt/metadata/html/browsers/browsing-the-web/navigating-across-documents/010.html.ini b/tests/wpt/metadata/html/browsers/browsing-the-web/navigating-across-documents/010.html.ini deleted file mode 100644 index cf12f241471..00000000000 --- a/tests/wpt/metadata/html/browsers/browsing-the-web/navigating-across-documents/010.html.ini +++ /dev/null @@ -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 diff --git a/tests/wpt/metadata/html/browsers/browsing-the-web/navigating-across-documents/011.html.ini b/tests/wpt/metadata/html/browsers/browsing-the-web/navigating-across-documents/011.html.ini deleted file mode 100644 index 7962549aeed..00000000000 --- a/tests/wpt/metadata/html/browsers/browsing-the-web/navigating-across-documents/011.html.ini +++ /dev/null @@ -1,3 +0,0 @@ -[011.html] - type: testharness - expected: TIMEOUT diff --git a/tests/wpt/metadata/html/browsers/browsing-the-web/navigating-across-documents/child_navigates_parent_submit.html.ini b/tests/wpt/metadata/html/browsers/browsing-the-web/navigating-across-documents/child_navigates_parent_submit.html.ini deleted file mode 100644 index a3de688eef5..00000000000 --- a/tests/wpt/metadata/html/browsers/browsing-the-web/navigating-across-documents/child_navigates_parent_submit.html.ini +++ /dev/null @@ -1,6 +0,0 @@ -[child_navigates_parent_submit.html] - type: testharness - expected: TIMEOUT - [Child document navigating parent via submit ] - expected: TIMEOUT - diff --git a/tests/wpt/metadata/html/browsers/browsing-the-web/navigating-across-documents/javascript-url-abort/javascript-url-abort-return-value-string.tentative.html.ini b/tests/wpt/metadata/html/browsers/browsing-the-web/navigating-across-documents/javascript-url-abort/javascript-url-abort-return-value-string.tentative.html.ini deleted file mode 100644 index 9bacb9f5c4e..00000000000 --- a/tests/wpt/metadata/html/browsers/browsing-the-web/navigating-across-documents/javascript-url-abort/javascript-url-abort-return-value-string.tentative.html.ini +++ /dev/null @@ -1,4 +0,0 @@ -[javascript-url-abort-return-value-string.tentative.html] - [Aborting fetch for javascript:string navigation] - expected: FAIL - diff --git a/tests/wpt/metadata/html/browsers/browsing-the-web/read-media/pageload-image-in-popup.html.ini b/tests/wpt/metadata/html/browsers/browsing-the-web/read-media/pageload-image-in-popup.html.ini deleted file mode 100644 index d936073896a..00000000000 --- a/tests/wpt/metadata/html/browsers/browsing-the-web/read-media/pageload-image-in-popup.html.ini +++ /dev/null @@ -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 - diff --git a/tests/wpt/metadata/html/browsers/history/the-history-interface/history_back_1.html.ini b/tests/wpt/metadata/html/browsers/history/the-history-interface/history_back_1.html.ini deleted file mode 100644 index 374935b8230..00000000000 --- a/tests/wpt/metadata/html/browsers/history/the-history-interface/history_back_1.html.ini +++ /dev/null @@ -1,4 +0,0 @@ -[history_back_1.html] - [history.back() with session history] - expected: FAIL - diff --git a/tests/wpt/metadata/html/browsers/history/the-history-interface/history_forward_1.html.ini b/tests/wpt/metadata/html/browsers/history/the-history-interface/history_forward_1.html.ini deleted file mode 100644 index 1296fcfa765..00000000000 --- a/tests/wpt/metadata/html/browsers/history/the-history-interface/history_forward_1.html.ini +++ /dev/null @@ -1,4 +0,0 @@ -[history_forward_1.html] - [history.forward() with session history] - expected: FAIL - diff --git a/tests/wpt/metadata/html/browsers/history/the-history-interface/history_go_no_argument.html.ini b/tests/wpt/metadata/html/browsers/history/the-history-interface/history_go_no_argument.html.ini deleted file mode 100644 index 93b88710b8f..00000000000 --- a/tests/wpt/metadata/html/browsers/history/the-history-interface/history_go_no_argument.html.ini +++ /dev/null @@ -1,4 +0,0 @@ -[history_go_no_argument.html] - [history.go()] - expected: FAIL - diff --git a/tests/wpt/metadata/html/browsers/history/the-history-interface/history_go_to_uri.html.ini b/tests/wpt/metadata/html/browsers/history/the-history-interface/history_go_to_uri.html.ini deleted file mode 100644 index d4dc04751d2..00000000000 --- a/tests/wpt/metadata/html/browsers/history/the-history-interface/history_go_to_uri.html.ini +++ /dev/null @@ -1,4 +0,0 @@ -[history_go_to_uri.html] - [history.go() negative tests] - expected: FAIL - diff --git a/tests/wpt/metadata/html/browsers/history/the-history-interface/history_go_zero.html.ini b/tests/wpt/metadata/html/browsers/history/the-history-interface/history_go_zero.html.ini deleted file mode 100644 index 2b0ff4704cf..00000000000 --- a/tests/wpt/metadata/html/browsers/history/the-history-interface/history_go_zero.html.ini +++ /dev/null @@ -1,4 +0,0 @@ -[history_go_zero.html] - [history.go(0)] - expected: FAIL - diff --git a/tests/wpt/metadata/html/browsers/history/the-history-interface/joint_session_history/001.html.ini b/tests/wpt/metadata/html/browsers/history/the-history-interface/joint_session_history/001.html.ini index 7ae291525bf..ad887840e4b 100644 --- a/tests/wpt/metadata/html/browsers/history/the-history-interface/joint_session_history/001.html.ini +++ b/tests/wpt/metadata/html/browsers/history/the-history-interface/joint_session_history/001.html.ini @@ -1,24 +1,5 @@ [001.html] - type: testharness - 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 - + expected: TIMEOUT [Traversing history forward] expected: NOTRUN diff --git a/tests/wpt/metadata/html/browsers/history/the-history-interface/joint_session_history/002.html.ini b/tests/wpt/metadata/html/browsers/history/the-history-interface/joint_session_history/002.html.ini index 5b47fc659d5..d575094af59 100644 --- a/tests/wpt/metadata/html/browsers/history/the-history-interface/joint_session_history/002.html.ini +++ b/tests/wpt/metadata/html/browsers/history/the-history-interface/joint_session_history/002.html.ini @@ -1,12 +1,5 @@ [002.html] - type: testharness - expected: ERROR - [Session history length on initial load] - expected: NOTRUN - - [Session history length on adding new iframe] - expected: NOTRUN - + expected: TIMEOUT [Navigating second iframe] - expected: NOTRUN + expected: TIMEOUT diff --git a/tests/wpt/metadata/html/browsers/history/the-history-interface/traverse_the_history_1.html.ini b/tests/wpt/metadata/html/browsers/history/the-history-interface/traverse_the_history_1.html.ini index 87b07c3e670..10190c72bb4 100644 --- a/tests/wpt/metadata/html/browsers/history/the-history-interface/traverse_the_history_1.html.ini +++ b/tests/wpt/metadata/html/browsers/history/the-history-interface/traverse_the_history_1.html.ini @@ -1,4 +1,5 @@ [traverse_the_history_1.html] + type: testharness [Multiple history traversals from the same task] expected: FAIL diff --git a/tests/wpt/metadata/html/browsers/history/the-history-interface/traverse_the_history_2.html.ini b/tests/wpt/metadata/html/browsers/history/the-history-interface/traverse_the_history_2.html.ini index 75d75b4cda2..5d17a8e9419 100644 --- a/tests/wpt/metadata/html/browsers/history/the-history-interface/traverse_the_history_2.html.ini +++ b/tests/wpt/metadata/html/browsers/history/the-history-interface/traverse_the_history_2.html.ini @@ -1,4 +1,3 @@ [traverse_the_history_2.html] [Multiple history traversals, last would be aborted] expected: FAIL - diff --git a/tests/wpt/metadata/html/browsers/history/the-history-interface/traverse_the_history_4.html.ini b/tests/wpt/metadata/html/browsers/history/the-history-interface/traverse_the_history_4.html.ini index 385376c7321..d6188c03424 100644 --- a/tests/wpt/metadata/html/browsers/history/the-history-interface/traverse_the_history_4.html.ini +++ b/tests/wpt/metadata/html/browsers/history/the-history-interface/traverse_the_history_4.html.ini @@ -1,4 +1,3 @@ [traverse_the_history_4.html] [Multiple history traversals, last would be aborted] expected: FAIL - diff --git a/tests/wpt/metadata/html/browsers/history/the-history-interface/traverse_the_history_unload_1.html.ini b/tests/wpt/metadata/html/browsers/history/the-history-interface/traverse_the_history_unload_1.html.ini deleted file mode 100644 index 42886146b6c..00000000000 --- a/tests/wpt/metadata/html/browsers/history/the-history-interface/traverse_the_history_unload_1.html.ini +++ /dev/null @@ -1,4 +0,0 @@ -[traverse_the_history_unload_1.html] - [Traversing the history, unload event is fired on doucment] - expected: FAIL - diff --git a/tests/wpt/metadata/html/browsers/history/the-history-interface/traverse_the_history_write_after_load_1.html.ini b/tests/wpt/metadata/html/browsers/history/the-history-interface/traverse_the_history_write_after_load_1.html.ini index d45557366ac..52142098cb0 100644 --- a/tests/wpt/metadata/html/browsers/history/the-history-interface/traverse_the_history_write_after_load_1.html.ini +++ b/tests/wpt/metadata/html/browsers/history/the-history-interface/traverse_the_history_write_after_load_1.html.ini @@ -1,4 +1,6 @@ [traverse_the_history_write_after_load_1.html] + type: testharness + expected: TIMEOUT [Traverse the history after document.write after the load event] - expected: FAIL + expected: TIMEOUT diff --git a/tests/wpt/metadata/html/browsers/history/the-history-interface/traverse_the_history_write_after_load_2.html.ini b/tests/wpt/metadata/html/browsers/history/the-history-interface/traverse_the_history_write_after_load_2.html.ini deleted file mode 100644 index 07f625686be..00000000000 --- a/tests/wpt/metadata/html/browsers/history/the-history-interface/traverse_the_history_write_after_load_2.html.ini +++ /dev/null @@ -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 - diff --git a/tests/wpt/metadata/html/browsers/history/the-history-interface/traverse_the_history_write_onload_1.html.ini b/tests/wpt/metadata/html/browsers/history/the-history-interface/traverse_the_history_write_onload_1.html.ini deleted file mode 100644 index 1778e5a7aac..00000000000 --- a/tests/wpt/metadata/html/browsers/history/the-history-interface/traverse_the_history_write_onload_1.html.ini +++ /dev/null @@ -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 - diff --git a/tests/wpt/metadata/html/browsers/history/the-history-interface/traverse_the_history_write_onload_2.html.ini b/tests/wpt/metadata/html/browsers/history/the-history-interface/traverse_the_history_write_onload_2.html.ini deleted file mode 100644 index 771592ec776..00000000000 --- a/tests/wpt/metadata/html/browsers/history/the-history-interface/traverse_the_history_write_onload_2.html.ini +++ /dev/null @@ -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 - diff --git a/tests/wpt/metadata/html/browsers/history/the-location-interface/reload_document_write.html.ini b/tests/wpt/metadata/html/browsers/history/the-location-interface/reload_document_write.html.ini deleted file mode 100644 index 34a93c104c3..00000000000 --- a/tests/wpt/metadata/html/browsers/history/the-location-interface/reload_document_write.html.ini +++ /dev/null @@ -1,5 +0,0 @@ -[reload_document_write.html] - type: testharness - [Reload document with document.written content] - expected: FAIL - diff --git a/tests/wpt/metadata/html/browsers/history/the-location-interface/scripted_click_assign_during_load.html.ini b/tests/wpt/metadata/html/browsers/history/the-location-interface/scripted_click_assign_during_load.html.ini index e7844bf0924..e993ee4cd81 100644 --- a/tests/wpt/metadata/html/browsers/history/the-location-interface/scripted_click_assign_during_load.html.ini +++ b/tests/wpt/metadata/html/browsers/history/the-location-interface/scripted_click_assign_during_load.html.ini @@ -1,6 +1,5 @@ [scripted_click_assign_during_load.html] type: testharness - expected: ERROR [Assignment to location with click during load] - expected: NOTRUN + expected: FAIL diff --git a/tests/wpt/metadata/html/browsers/history/the-location-interface/scripted_click_location_assign_during_load.html.ini b/tests/wpt/metadata/html/browsers/history/the-location-interface/scripted_click_location_assign_during_load.html.ini deleted file mode 100644 index e63972ce41e..00000000000 --- a/tests/wpt/metadata/html/browsers/history/the-location-interface/scripted_click_location_assign_during_load.html.ini +++ /dev/null @@ -1,6 +0,0 @@ -[scripted_click_location_assign_during_load.html] - type: testharness - expected: ERROR - [location.assign with click during load] - expected: NOTRUN - diff --git a/tests/wpt/metadata/html/browsers/history/the-location-interface/scripted_form_submit_assign_during_load.html.ini b/tests/wpt/metadata/html/browsers/history/the-location-interface/scripted_form_submit_assign_during_load.html.ini index 40a4ab9d7c6..2338cd16001 100644 --- a/tests/wpt/metadata/html/browsers/history/the-location-interface/scripted_form_submit_assign_during_load.html.ini +++ b/tests/wpt/metadata/html/browsers/history/the-location-interface/scripted_form_submit_assign_during_load.html.ini @@ -1,6 +1,5 @@ [scripted_form_submit_assign_during_load.html] type: testharness - expected: ERROR [Assignment to location with form submit during load] - expected: NOTRUN + expected: FAIL diff --git a/tests/wpt/metadata/html/browsers/history/the-session-history-of-browsing-contexts/navigation-in-onload.tentative.html.ini b/tests/wpt/metadata/html/browsers/history/the-session-history-of-browsing-contexts/navigation-in-onload.tentative.html.ini index 2d6b8fa2546..37a316d60be 100644 --- a/tests/wpt/metadata/html/browsers/history/the-session-history-of-browsing-contexts/navigation-in-onload.tentative.html.ini +++ b/tests/wpt/metadata/html/browsers/history/the-session-history-of-browsing-contexts/navigation-in-onload.tentative.html.ini @@ -1,5 +1,4 @@ [navigation-in-onload.tentative.html] - expected: ERROR [Navigation in onload handler] - expected: NOTRUN + expected: FAIL diff --git a/tests/wpt/metadata/html/browsers/origin/cross-origin-objects/cross-origin-objects-on-new-window.html.ini b/tests/wpt/metadata/html/browsers/origin/cross-origin-objects/cross-origin-objects-on-new-window.html.ini index fa72caf81c9..498fa7e4254 100644 --- a/tests/wpt/metadata/html/browsers/origin/cross-origin-objects/cross-origin-objects-on-new-window.html.ini +++ b/tests/wpt/metadata/html/browsers/origin/cross-origin-objects/cross-origin-objects-on-new-window.html.ini @@ -1,5 +1,3 @@ [cross-origin-objects-on-new-window.html] type: testharness - [Cross-origin behavior of Window and Location on new Window] - expected: FAIL - + expected: TIMEOUT diff --git a/tests/wpt/metadata/html/browsers/the-window-object/accessing-other-browsing-contexts/window_length.html.ini b/tests/wpt/metadata/html/browsers/the-window-object/accessing-other-browsing-contexts/window_length.html.ini deleted file mode 100644 index 808ae95d568..00000000000 --- a/tests/wpt/metadata/html/browsers/the-window-object/accessing-other-browsing-contexts/window_length.html.ini +++ /dev/null @@ -1,8 +0,0 @@ -[window_length.html] - type: testharness - [Opened window] - expected: FAIL - - [Iframe in opened window] - expected: FAIL - diff --git a/tests/wpt/metadata/html/browsers/the-window-object/apis-for-creating-and-navigating-browsing-contexts-by-name/close_beforeunload.html.ini b/tests/wpt/metadata/html/browsers/the-window-object/apis-for-creating-and-navigating-browsing-contexts-by-name/close_beforeunload.html.ini deleted file mode 100644 index 83bd871d725..00000000000 --- a/tests/wpt/metadata/html/browsers/the-window-object/apis-for-creating-and-navigating-browsing-contexts-by-name/close_beforeunload.html.ini +++ /dev/null @@ -1,6 +0,0 @@ -[close_beforeunload.html] - type: testharness - expected: ERROR - [Running beforeunload handler in window.close()] - expected: NOTRUN - diff --git a/tests/wpt/metadata/html/browsers/the-window-object/apis-for-creating-and-navigating-browsing-contexts-by-name/close_unload.html.ini b/tests/wpt/metadata/html/browsers/the-window-object/apis-for-creating-and-navigating-browsing-contexts-by-name/close_unload.html.ini deleted file mode 100644 index 935275388a6..00000000000 --- a/tests/wpt/metadata/html/browsers/the-window-object/apis-for-creating-and-navigating-browsing-contexts-by-name/close_unload.html.ini +++ /dev/null @@ -1,6 +0,0 @@ -[close_unload.html] - type: testharness - expected: ERROR - [Running unload handler in window.close()] - expected: NOTRUN - diff --git a/tests/wpt/metadata/html/browsers/the-window-object/apis-for-creating-and-navigating-browsing-contexts-by-name/creating_browsing_context_test_01.html.ini b/tests/wpt/metadata/html/browsers/the-window-object/apis-for-creating-and-navigating-browsing-contexts-by-name/creating_browsing_context_test_01.html.ini index 06deac2164e..5d28284b841 100644 --- a/tests/wpt/metadata/html/browsers/the-window-object/apis-for-creating-and-navigating-browsing-contexts-by-name/creating_browsing_context_test_01.html.ini +++ b/tests/wpt/metadata/html/browsers/the-window-object/apis-for-creating-and-navigating-browsing-contexts-by-name/creating_browsing_context_test_01.html.ini @@ -3,12 +3,3 @@ [first argument: absolute url] 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 - diff --git a/tests/wpt/metadata/html/browsers/the-window-object/apis-for-creating-and-navigating-browsing-contexts-by-name/open-features-negative-innerwidth-innerheight.html.ini b/tests/wpt/metadata/html/browsers/the-window-object/apis-for-creating-and-navigating-browsing-contexts-by-name/open-features-negative-innerwidth-innerheight.html.ini index 110dbe90b25..bf50d59df41 100644 --- a/tests/wpt/metadata/html/browsers/the-window-object/apis-for-creating-and-navigating-browsing-contexts-by-name/open-features-negative-innerwidth-innerheight.html.ini +++ b/tests/wpt/metadata/html/browsers/the-window-object/apis-for-creating-and-navigating-browsing-contexts-by-name/open-features-negative-innerwidth-innerheight.html.ini @@ -1,3 +1,5 @@ [open-features-negative-innerwidth-innerheight.html] type: testharness - expected: ERROR + [HTML: window.open `features`: negative values for legacy `innerwidth`, `innerheight`] + expected: FAIL + diff --git a/tests/wpt/metadata/html/browsers/the-window-object/apis-for-creating-and-navigating-browsing-contexts-by-name/open-features-negative-screenx-screeny.html.ini b/tests/wpt/metadata/html/browsers/the-window-object/apis-for-creating-and-navigating-browsing-contexts-by-name/open-features-negative-screenx-screeny.html.ini index ec97a9ade64..e150c9d848f 100644 --- a/tests/wpt/metadata/html/browsers/the-window-object/apis-for-creating-and-navigating-browsing-contexts-by-name/open-features-negative-screenx-screeny.html.ini +++ b/tests/wpt/metadata/html/browsers/the-window-object/apis-for-creating-and-navigating-browsing-contexts-by-name/open-features-negative-screenx-screeny.html.ini @@ -1,3 +1,5 @@ [open-features-negative-screenx-screeny.html] type: testharness - expected: ERROR + [HTML: window.open `features`: negative values for legacy `screenx`, `screeny`] + expected: FAIL + diff --git a/tests/wpt/metadata/html/browsers/the-window-object/apis-for-creating-and-navigating-browsing-contexts-by-name/open-features-negative-top-left.html.ini b/tests/wpt/metadata/html/browsers/the-window-object/apis-for-creating-and-navigating-browsing-contexts-by-name/open-features-negative-top-left.html.ini index 54ffbd242fc..ad8840fbb68 100644 --- a/tests/wpt/metadata/html/browsers/the-window-object/apis-for-creating-and-navigating-browsing-contexts-by-name/open-features-negative-top-left.html.ini +++ b/tests/wpt/metadata/html/browsers/the-window-object/apis-for-creating-and-navigating-browsing-contexts-by-name/open-features-negative-top-left.html.ini @@ -1,3 +1,5 @@ [open-features-negative-top-left.html] type: testharness - expected: ERROR + [HTML: window.open `features`: negative values for `top`, `left`] + expected: FAIL + diff --git a/tests/wpt/metadata/html/browsers/the-window-object/apis-for-creating-and-navigating-browsing-contexts-by-name/open-features-negative-width-height.html.ini b/tests/wpt/metadata/html/browsers/the-window-object/apis-for-creating-and-navigating-browsing-contexts-by-name/open-features-negative-width-height.html.ini index 8462dfff21f..d1ed9088b2b 100644 --- a/tests/wpt/metadata/html/browsers/the-window-object/apis-for-creating-and-navigating-browsing-contexts-by-name/open-features-negative-width-height.html.ini +++ b/tests/wpt/metadata/html/browsers/the-window-object/apis-for-creating-and-navigating-browsing-contexts-by-name/open-features-negative-width-height.html.ini @@ -1,3 +1,5 @@ [open-features-negative-width-height.html] type: testharness - expected: ERROR + [HTML: window.open `features`: negative values for `width`, `height`] + expected: FAIL + diff --git a/tests/wpt/metadata/html/browsers/the-window-object/apis-for-creating-and-navigating-browsing-contexts-by-name/open-features-non-integer-height.html.ini b/tests/wpt/metadata/html/browsers/the-window-object/apis-for-creating-and-navigating-browsing-contexts-by-name/open-features-non-integer-height.html.ini index 1781d871ff0..14e2d7593e4 100644 --- a/tests/wpt/metadata/html/browsers/the-window-object/apis-for-creating-and-navigating-browsing-contexts-by-name/open-features-non-integer-height.html.ini +++ b/tests/wpt/metadata/html/browsers/the-window-object/apis-for-creating-and-navigating-browsing-contexts-by-name/open-features-non-integer-height.html.ini @@ -1,3 +1,5 @@ [open-features-non-integer-height.html] type: testharness - expected: ERROR + [HTML: window.open `features`: non-integer values for feature `height`] + expected: FAIL + diff --git a/tests/wpt/metadata/html/browsers/the-window-object/apis-for-creating-and-navigating-browsing-contexts-by-name/open-features-non-integer-innerheight.html.ini b/tests/wpt/metadata/html/browsers/the-window-object/apis-for-creating-and-navigating-browsing-contexts-by-name/open-features-non-integer-innerheight.html.ini index 395635123fe..fed8fba4a3d 100644 --- a/tests/wpt/metadata/html/browsers/the-window-object/apis-for-creating-and-navigating-browsing-contexts-by-name/open-features-non-integer-innerheight.html.ini +++ b/tests/wpt/metadata/html/browsers/the-window-object/apis-for-creating-and-navigating-browsing-contexts-by-name/open-features-non-integer-innerheight.html.ini @@ -1,3 +1,5 @@ [open-features-non-integer-innerheight.html] type: testharness - expected: ERROR + [HTML: window.open `features`: non-integer values for legacy feature `innerheight`] + expected: FAIL + diff --git a/tests/wpt/metadata/html/browsers/the-window-object/apis-for-creating-and-navigating-browsing-contexts-by-name/open-features-non-integer-innerwidth.html.ini b/tests/wpt/metadata/html/browsers/the-window-object/apis-for-creating-and-navigating-browsing-contexts-by-name/open-features-non-integer-innerwidth.html.ini index 35e811141e9..8b35ad53d15 100644 --- a/tests/wpt/metadata/html/browsers/the-window-object/apis-for-creating-and-navigating-browsing-contexts-by-name/open-features-non-integer-innerwidth.html.ini +++ b/tests/wpt/metadata/html/browsers/the-window-object/apis-for-creating-and-navigating-browsing-contexts-by-name/open-features-non-integer-innerwidth.html.ini @@ -1,3 +1,5 @@ [open-features-non-integer-innerwidth.html] type: testharness - expected: ERROR + [HTML: window.open `features`: non-integer values for legacy feature `innerwidth`] + expected: FAIL + diff --git a/tests/wpt/metadata/html/browsers/the-window-object/apis-for-creating-and-navigating-browsing-contexts-by-name/open-features-non-integer-left.html.ini b/tests/wpt/metadata/html/browsers/the-window-object/apis-for-creating-and-navigating-browsing-contexts-by-name/open-features-non-integer-left.html.ini index 856ff7988a2..64bf0a8d345 100644 --- a/tests/wpt/metadata/html/browsers/the-window-object/apis-for-creating-and-navigating-browsing-contexts-by-name/open-features-non-integer-left.html.ini +++ b/tests/wpt/metadata/html/browsers/the-window-object/apis-for-creating-and-navigating-browsing-contexts-by-name/open-features-non-integer-left.html.ini @@ -1,3 +1,5 @@ [open-features-non-integer-left.html] type: testharness - expected: ERROR + [HTML: window.open `features`: non-integer values for feature `left`] + expected: FAIL + diff --git a/tests/wpt/metadata/html/browsers/the-window-object/apis-for-creating-and-navigating-browsing-contexts-by-name/open-features-non-integer-screenx.html.ini b/tests/wpt/metadata/html/browsers/the-window-object/apis-for-creating-and-navigating-browsing-contexts-by-name/open-features-non-integer-screenx.html.ini index 2a72b50b6d3..d6c76d5a550 100644 --- a/tests/wpt/metadata/html/browsers/the-window-object/apis-for-creating-and-navigating-browsing-contexts-by-name/open-features-non-integer-screenx.html.ini +++ b/tests/wpt/metadata/html/browsers/the-window-object/apis-for-creating-and-navigating-browsing-contexts-by-name/open-features-non-integer-screenx.html.ini @@ -1,3 +1,5 @@ [open-features-non-integer-screenx.html] type: testharness - expected: ERROR + [HTML: window.open `features`: non-integer values for legacy feature `screenx`] + expected: FAIL + diff --git a/tests/wpt/metadata/html/browsers/the-window-object/apis-for-creating-and-navigating-browsing-contexts-by-name/open-features-non-integer-screeny.html.ini b/tests/wpt/metadata/html/browsers/the-window-object/apis-for-creating-and-navigating-browsing-contexts-by-name/open-features-non-integer-screeny.html.ini index accc00b3b4c..bf6d1eb3fed 100644 --- a/tests/wpt/metadata/html/browsers/the-window-object/apis-for-creating-and-navigating-browsing-contexts-by-name/open-features-non-integer-screeny.html.ini +++ b/tests/wpt/metadata/html/browsers/the-window-object/apis-for-creating-and-navigating-browsing-contexts-by-name/open-features-non-integer-screeny.html.ini @@ -1,3 +1,5 @@ [open-features-non-integer-screeny.html] type: testharness - expected: ERROR + [HTML: window.open `features`: non-integer values for legacy feature `screeny`] + expected: FAIL + diff --git a/tests/wpt/metadata/html/browsers/the-window-object/apis-for-creating-and-navigating-browsing-contexts-by-name/open-features-non-integer-top.html.ini b/tests/wpt/metadata/html/browsers/the-window-object/apis-for-creating-and-navigating-browsing-contexts-by-name/open-features-non-integer-top.html.ini index d0be8627e99..252d8d53363 100644 --- a/tests/wpt/metadata/html/browsers/the-window-object/apis-for-creating-and-navigating-browsing-contexts-by-name/open-features-non-integer-top.html.ini +++ b/tests/wpt/metadata/html/browsers/the-window-object/apis-for-creating-and-navigating-browsing-contexts-by-name/open-features-non-integer-top.html.ini @@ -1,3 +1,5 @@ [open-features-non-integer-top.html] type: testharness - expected: ERROR + [HTML: window.open `features`: non-integer values for feature `top`] + expected: FAIL + diff --git a/tests/wpt/metadata/html/browsers/the-window-object/apis-for-creating-and-navigating-browsing-contexts-by-name/open-features-non-integer-width.html.ini b/tests/wpt/metadata/html/browsers/the-window-object/apis-for-creating-and-navigating-browsing-contexts-by-name/open-features-non-integer-width.html.ini index d17bba2270a..3cdeaa95031 100644 --- a/tests/wpt/metadata/html/browsers/the-window-object/apis-for-creating-and-navigating-browsing-contexts-by-name/open-features-non-integer-width.html.ini +++ b/tests/wpt/metadata/html/browsers/the-window-object/apis-for-creating-and-navigating-browsing-contexts-by-name/open-features-non-integer-width.html.ini @@ -1,3 +1,5 @@ [open-features-non-integer-width.html] type: testharness - expected: ERROR + [HTML: window.open `features`: non-integer values for feature `width`] + expected: FAIL + diff --git a/tests/wpt/metadata/html/browsers/the-window-object/apis-for-creating-and-navigating-browsing-contexts-by-name/open-features-tokenization-noopener.html.ini b/tests/wpt/metadata/html/browsers/the-window-object/apis-for-creating-and-navigating-browsing-contexts-by-name/open-features-tokenization-noopener.html.ini index 86bb0f4c578..2fa1da41f33 100644 --- a/tests/wpt/metadata/html/browsers/the-window-object/apis-for-creating-and-navigating-browsing-contexts-by-name/open-features-tokenization-noopener.html.ini +++ b/tests/wpt/metadata/html/browsers/the-window-object/apis-for-creating-and-navigating-browsing-contexts-by-name/open-features-tokenization-noopener.html.ini @@ -1,23 +1,7 @@ [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] 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"] expected: FAIL diff --git a/tests/wpt/metadata/html/browsers/the-window-object/garbage-collection-and-browsing-contexts/discard_iframe_history_1.html.ini b/tests/wpt/metadata/html/browsers/the-window-object/garbage-collection-and-browsing-contexts/discard_iframe_history_1.html.ini index 882045d2623..5a447d65400 100644 --- a/tests/wpt/metadata/html/browsers/the-window-object/garbage-collection-and-browsing-contexts/discard_iframe_history_1.html.ini +++ b/tests/wpt/metadata/html/browsers/the-window-object/garbage-collection-and-browsing-contexts/discard_iframe_history_1.html.ini @@ -1,6 +1,5 @@ [discard_iframe_history_1.html] type: testharness - expected: ERROR [Removing iframe from document removes it from history] - expected: NOTRUN + expected: FAIL diff --git a/tests/wpt/metadata/html/browsers/the-window-object/garbage-collection-and-browsing-contexts/discard_iframe_history_2.html.ini b/tests/wpt/metadata/html/browsers/the-window-object/garbage-collection-and-browsing-contexts/discard_iframe_history_2.html.ini index 864fe9a325f..e032f4d1988 100644 --- a/tests/wpt/metadata/html/browsers/the-window-object/garbage-collection-and-browsing-contexts/discard_iframe_history_2.html.ini +++ b/tests/wpt/metadata/html/browsers/the-window-object/garbage-collection-and-browsing-contexts/discard_iframe_history_2.html.ini @@ -1,6 +1,5 @@ [discard_iframe_history_2.html] type: testharness - expected: ERROR [Removing iframe from document via innerHTML removes it from history] - expected: NOTRUN + expected: FAIL diff --git a/tests/wpt/metadata/html/browsers/the-window-object/garbage-collection-and-browsing-contexts/discard_iframe_history_3.html.ini b/tests/wpt/metadata/html/browsers/the-window-object/garbage-collection-and-browsing-contexts/discard_iframe_history_3.html.ini deleted file mode 100644 index 0d6e7127dab..00000000000 --- a/tests/wpt/metadata/html/browsers/the-window-object/garbage-collection-and-browsing-contexts/discard_iframe_history_3.html.ini +++ /dev/null @@ -1,6 +0,0 @@ -[discard_iframe_history_3.html] - type: testharness - expected: ERROR - [Removing iframe from document removes it from history] - expected: NOTRUN - diff --git a/tests/wpt/metadata/html/browsers/the-window-object/garbage-collection-and-browsing-contexts/discard_iframe_history_4.html.ini b/tests/wpt/metadata/html/browsers/the-window-object/garbage-collection-and-browsing-contexts/discard_iframe_history_4.html.ini deleted file mode 100644 index 31ff6be6133..00000000000 --- a/tests/wpt/metadata/html/browsers/the-window-object/garbage-collection-and-browsing-contexts/discard_iframe_history_4.html.ini +++ /dev/null @@ -1,6 +0,0 @@ -[discard_iframe_history_4.html] - type: testharness - expected: ERROR - [Removing iframe from document removes it from history] - expected: NOTRUN - diff --git a/tests/wpt/metadata/html/browsers/the-window-object/security-window/window-security.https.html.ini b/tests/wpt/metadata/html/browsers/the-window-object/security-window/window-security.https.html.ini index c18a4adb31e..e9b165f8c8d 100644 --- a/tests/wpt/metadata/html/browsers/the-window-object/security-window/window-security.https.html.ini +++ b/tests/wpt/metadata/html/browsers/the-window-object/security-window/window-security.https.html.ini @@ -335,9 +335,6 @@ [A SecurityError exception must be thrown when window.stop is accessed from a different origin.] 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.] expected: FAIL diff --git a/tests/wpt/metadata/html/browsers/the-window-object/window-open-noopener.html.ini b/tests/wpt/metadata/html/browsers/the-window-object/window-open-noopener.html.ini index 7844c379089..2e46ade9563 100644 --- a/tests/wpt/metadata/html/browsers/the-window-object/window-open-noopener.html.ini +++ b/tests/wpt/metadata/html/browsers/the-window-object/window-open-noopener.html.ini @@ -1,6 +1,5 @@ [window-open-noopener.html] type: testharness - expected: ERROR [window.open() with 'noopener' should not reuse existing target] expected: FAIL @@ -27,15 +26,13 @@ [window-open-noopener.html?_parent] - expected: ERROR [noopener window.open targeting _parent] - expected: NOTRUN + expected: FAIL [window-open-noopener.html?_top] - expected: ERROR [noopener window.open targeting _top] - expected: NOTRUN + expected: FAIL [window-open-noopener.html?indexed] @@ -63,7 +60,12 @@ [window-open-noopener.html?_self] - expected: ERROR [noopener window.open targeting _self] + expected: FAIL + + [noopener window.open targeting _parent] + expected: NOTRUN + + [noopener window.open targeting _top] expected: NOTRUN diff --git a/tests/wpt/metadata/html/browsers/the-window-object/window-properties.https.html.ini b/tests/wpt/metadata/html/browsers/the-window-object/window-properties.https.html.ini index c691ea29632..a58584d0006 100644 --- a/tests/wpt/metadata/html/browsers/the-window-object/window-properties.https.html.ini +++ b/tests/wpt/metadata/html/browsers/the-window-object/window-properties.https.html.ini @@ -5,9 +5,6 @@ [Window method: blur] expected: FAIL - [Window method: open] - expected: FAIL - [Window method: confirm] expected: FAIL @@ -23,9 +20,6 @@ [Window readonly attribute: applicationCache] expected: FAIL - [Window attribute: opener] - expected: FAIL - [Window attribute: onmousewheel] expected: FAIL diff --git a/tests/wpt/metadata/html/browsers/windows/auxiliary-browsing-contexts/opener-closed.html.ini b/tests/wpt/metadata/html/browsers/windows/auxiliary-browsing-contexts/opener-closed.html.ini index 0782cb9ad52..d97cd045a92 100644 --- a/tests/wpt/metadata/html/browsers/windows/auxiliary-browsing-contexts/opener-closed.html.ini +++ b/tests/wpt/metadata/html/browsers/windows/auxiliary-browsing-contexts/opener-closed.html.ini @@ -1,3 +1,5 @@ [opener-closed.html] type: testharness expected: TIMEOUT + [An auxiliary browsing context should report `null` for `window.opener` when that browsing context is discarded] + expected: TIMEOUT diff --git a/tests/wpt/metadata/html/browsers/windows/auxiliary-browsing-contexts/opener-multiple.html.ini b/tests/wpt/metadata/html/browsers/windows/auxiliary-browsing-contexts/opener-multiple.html.ini index 45e3f839871..5f19cf016eb 100644 --- a/tests/wpt/metadata/html/browsers/windows/auxiliary-browsing-contexts/opener-multiple.html.ini +++ b/tests/wpt/metadata/html/browsers/windows/auxiliary-browsing-contexts/opener-multiple.html.ini @@ -1,3 +1,5 @@ [opener-multiple.html] type: testharness expected: TIMEOUT + [An auxiliary browsing context should be able to open another auxiliary browsing context] + expected: TIMEOUT diff --git a/tests/wpt/metadata/html/browsers/windows/auxiliary-browsing-contexts/opener-noreferrer.html.ini b/tests/wpt/metadata/html/browsers/windows/auxiliary-browsing-contexts/opener-noreferrer.html.ini index 393a5059e9d..dabad35e2ee 100644 --- a/tests/wpt/metadata/html/browsers/windows/auxiliary-browsing-contexts/opener-noreferrer.html.ini +++ b/tests/wpt/metadata/html/browsers/windows/auxiliary-browsing-contexts/opener-noreferrer.html.ini @@ -1,5 +1,6 @@ [opener-noreferrer.html] type: testharness + expected: TIMEOUT [Auxiliary browsing context created with `rel="noreferrer"` should report `window.opener` `null`] - expected: FAIL + expected: TIMEOUT diff --git a/tests/wpt/metadata/html/browsers/windows/auxiliary-browsing-contexts/opener.html.ini b/tests/wpt/metadata/html/browsers/windows/auxiliary-browsing-contexts/opener.html.ini index 13ce462c59d..59a38204b5e 100644 --- a/tests/wpt/metadata/html/browsers/windows/auxiliary-browsing-contexts/opener.html.ini +++ b/tests/wpt/metadata/html/browsers/windows/auxiliary-browsing-contexts/opener.html.ini @@ -1,3 +1,7 @@ [opener.html] type: testharness 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 diff --git a/tests/wpt/metadata/html/browsers/windows/browsing-context-names/choose-_blank-002.html.ini b/tests/wpt/metadata/html/browsers/windows/browsing-context-names/choose-_blank-002.html.ini index f1158390a90..da270341b6f 100644 --- a/tests/wpt/metadata/html/browsers/windows/browsing-context-names/choose-_blank-002.html.ini +++ b/tests/wpt/metadata/html/browsers/windows/browsing-context-names/choose-_blank-002.html.ini @@ -1,5 +1,6 @@ [choose-_blank-002.html] type: testharness + expected: TIMEOUT [Context for opened noreferrer link targeted to "_blank" should not have opener reference] - expected: FAIL + expected: TIMEOUT diff --git a/tests/wpt/metadata/html/browsers/windows/browsing-context-names/choose-_blank-003.html.ini b/tests/wpt/metadata/html/browsers/windows/browsing-context-names/choose-_blank-003.html.ini new file mode 100644 index 00000000000..34eeff13c09 --- /dev/null +++ b/tests/wpt/metadata/html/browsers/windows/browsing-context-names/choose-_blank-003.html.ini @@ -0,0 +1,6 @@ +[choose-_blank-003.html] + type: testharness + expected: TIMEOUT + [Context created by link targeting "_blank" should retain opener reference] + expected: TIMEOUT + diff --git a/tests/wpt/metadata/html/browsers/windows/browsing-context-names/choose-default-001.html.ini b/tests/wpt/metadata/html/browsers/windows/browsing-context-names/choose-default-001.html.ini index ee09c5266fb..c57a3c272ef 100644 --- a/tests/wpt/metadata/html/browsers/windows/browsing-context-names/choose-default-001.html.ini +++ b/tests/wpt/metadata/html/browsers/windows/browsing-context-names/choose-default-001.html.ini @@ -2,7 +2,3 @@ type: testharness [A embedded browsing context has empty-string default name] expected: FAIL - - [A browsing context which is opened by window.open() method with '_blank' parameter has empty-string default name] - expected: FAIL - diff --git a/tests/wpt/metadata/html/browsers/windows/browsing-context-names/choose-existing-001.html.ini b/tests/wpt/metadata/html/browsers/windows/browsing-context-names/choose-existing-001.html.ini deleted file mode 100644 index 7ac26620d87..00000000000 --- a/tests/wpt/metadata/html/browsers/windows/browsing-context-names/choose-existing-001.html.ini +++ /dev/null @@ -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 - diff --git a/tests/wpt/metadata/html/browsers/windows/noreferrer-null-opener.html.ini b/tests/wpt/metadata/html/browsers/windows/noreferrer-null-opener.html.ini index 4df42589175..5b7cd2d3c82 100644 --- a/tests/wpt/metadata/html/browsers/windows/noreferrer-null-opener.html.ini +++ b/tests/wpt/metadata/html/browsers/windows/noreferrer-null-opener.html.ini @@ -1,5 +1,6 @@ [noreferrer-null-opener.html] type: testharness + expected: TIMEOUT [rel=noreferrer nullifies window.opener] - expected: FAIL + expected: TIMEOUT diff --git a/tests/wpt/metadata/html/browsers/windows/noreferrer-window-name.html.ini b/tests/wpt/metadata/html/browsers/windows/noreferrer-window-name.html.ini index c7f0b290235..711a7a94e41 100644 --- a/tests/wpt/metadata/html/browsers/windows/noreferrer-window-name.html.ini +++ b/tests/wpt/metadata/html/browsers/windows/noreferrer-window-name.html.ini @@ -1,6 +1,13 @@ [noreferrer-window-name.html] type: testharness 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 + [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 + diff --git a/tests/wpt/metadata/html/browsers/windows/targeting-cross-origin-nested-browsing-contexts.html.ini b/tests/wpt/metadata/html/browsers/windows/targeting-cross-origin-nested-browsing-contexts.html.ini index 90464594a18..7e01a712d91 100644 --- a/tests/wpt/metadata/html/browsers/windows/targeting-cross-origin-nested-browsing-contexts.html.ini +++ b/tests/wpt/metadata/html/browsers/windows/targeting-cross-origin-nested-browsing-contexts.html.ini @@ -1,3 +1,5 @@ [targeting-cross-origin-nested-browsing-contexts.html] type: testharness expected: TIMEOUT + [Targeting nested browsing contexts] + expected: FAIL diff --git a/tests/wpt/metadata/html/dom/usvstring-reflection.html.ini b/tests/wpt/metadata/html/dom/usvstring-reflection.html.ini index 4106ed36649..37bb450ceb9 100644 --- a/tests/wpt/metadata/html/dom/usvstring-reflection.html.ini +++ b/tests/wpt/metadata/html/dom/usvstring-reflection.html.ini @@ -1,7 +1,4 @@ [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] expected: FAIL @@ -17,12 +14,6 @@ [source : unpaired surrogate codepoint should be replaced with U+FFFD] 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.] expected: FAIL diff --git a/tests/wpt/metadata/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_escaping-1.html.ini b/tests/wpt/metadata/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_escaping-1.html.ini index fc37df7e3fa..f42f518d257 100644 --- a/tests/wpt/metadata/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_escaping-1.html.ini +++ b/tests/wpt/metadata/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_escaping-1.html.ini @@ -1,6 +1,5 @@ [iframe_sandbox_popups_escaping-1.html] type: testharness - expected: TIMEOUT [Check that popups from a sandboxed iframe escape the sandbox if\n allow-popups-to-escape-sandbox is used] - expected: TIMEOUT + expected: FAIL diff --git a/tests/wpt/metadata/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_escaping-2.html.ini b/tests/wpt/metadata/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_escaping-2.html.ini index b21a85689bf..2cda2cc95ad 100644 --- a/tests/wpt/metadata/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_escaping-2.html.ini +++ b/tests/wpt/metadata/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_escaping-2.html.ini @@ -1,6 +1,5 @@ [iframe_sandbox_popups_escaping-2.html] type: testharness - expected: TIMEOUT [Check that popups from a sandboxed iframe escape the sandbox if\n allow-popups-to-escape-sandbox is used] - expected: TIMEOUT + expected: FAIL diff --git a/tests/wpt/metadata/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_nonescaping-1.html.ini b/tests/wpt/metadata/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_nonescaping-1.html.ini index 9df1ac56f2a..3f7e3e9544f 100644 --- a/tests/wpt/metadata/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_nonescaping-1.html.ini +++ b/tests/wpt/metadata/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_nonescaping-1.html.ini @@ -1,6 +1,5 @@ [iframe_sandbox_popups_nonescaping-1.html] type: testharness - expected: TIMEOUT [Check that popups from a sandboxed iframe do not escape the sandbox] - expected: NOTRUN + expected: FAIL diff --git a/tests/wpt/metadata/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_nonescaping-2.html.ini b/tests/wpt/metadata/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_nonescaping-2.html.ini index d43f38b40cd..3a32693ffa8 100644 --- a/tests/wpt/metadata/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_nonescaping-2.html.ini +++ b/tests/wpt/metadata/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_nonescaping-2.html.ini @@ -1,6 +1,5 @@ [iframe_sandbox_popups_nonescaping-2.html] type: testharness - expected: TIMEOUT [Check that popups from a sandboxed iframe do not escape the sandbox] - expected: NOTRUN + expected: FAIL diff --git a/tests/wpt/metadata/html/semantics/forms/form-submission-0/submission-checks.window.js.ini b/tests/wpt/metadata/html/semantics/forms/form-submission-0/submission-checks.window.js.ini index 98bf6052cdb..1344c61fb3d 100644 --- a/tests/wpt/metadata/html/semantics/forms/form-submission-0/submission-checks.window.js.ini +++ b/tests/wpt/metadata/html/semantics/forms/form-submission-0/submission-checks.window.js.ini @@ -1,3 +1,11 @@ [submission-checks.window.html] type: testharness - expected: TIMEOUT + [
not connected to a document cannot navigate] + expected: FAIL + + [ not connected to a document after submit event cannot navigate] + expected: FAIL + + [ in a navigated document cannot navigate] + expected: FAIL + diff --git a/tests/wpt/metadata/html/semantics/links/links-created-by-a-and-area-elements/htmlanchorelement_noopener.html.ini b/tests/wpt/metadata/html/semantics/links/links-created-by-a-and-area-elements/htmlanchorelement_noopener.html.ini index f57fa77bf15..8547a8949c4 100644 --- a/tests/wpt/metadata/html/semantics/links/links-created-by-a-and-area-elements/htmlanchorelement_noopener.html.ini +++ b/tests/wpt/metadata/html/semantics/links/links-created-by-a-and-area-elements/htmlanchorelement_noopener.html.ini @@ -2,5 +2,14 @@ type: testharness expected: ERROR [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 + [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 + diff --git a/tests/wpt/metadata/html/webappapis/scripting/events/compile-event-handler-settings-objects.html.ini b/tests/wpt/metadata/html/webappapis/scripting/events/compile-event-handler-settings-objects.html.ini index 6be42ab4108..5934ad00ad2 100644 --- a/tests/wpt/metadata/html/webappapis/scripting/events/compile-event-handler-settings-objects.html.ini +++ b/tests/wpt/metadata/html/webappapis/scripting/events/compile-event-handler-settings-objects.html.ini @@ -2,7 +2,7 @@ type: testharness expected: TIMEOUT [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] expected: TIMEOUT diff --git a/tests/wpt/metadata/websockets/unload-a-document/003.html.ini b/tests/wpt/metadata/websockets/unload-a-document/003.html.ini index 0f8dd7f068d..a479ae60b5a 100644 --- a/tests/wpt/metadata/websockets/unload-a-document/003.html.ini +++ b/tests/wpt/metadata/websockets/unload-a-document/003.html.ini @@ -1,6 +1,5 @@ [003.html] type: testharness - expected: TIMEOUT [WebSockets: navigating nested browsing context] - expected: TIMEOUT + expected: FAIL diff --git a/tests/wpt/metadata/websockets/unload-a-document/004.html.ini b/tests/wpt/metadata/websockets/unload-a-document/004.html.ini index 51828d4eabd..66180a29004 100644 --- a/tests/wpt/metadata/websockets/unload-a-document/004.html.ini +++ b/tests/wpt/metadata/websockets/unload-a-document/004.html.ini @@ -1,5 +1,5 @@ [004.html] type: testharness [WebSockets: navigating nested browsing context with closed websocket] - expected: TIMEOUT + expected: FAIL diff --git a/tests/wpt/metadata/webstorage/storage_local_window_open.html.ini b/tests/wpt/metadata/webstorage/storage_local_window_open.html.ini deleted file mode 100644 index 45787f2fd72..00000000000 --- a/tests/wpt/metadata/webstorage/storage_local_window_open.html.ini +++ /dev/null @@ -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 - diff --git a/tests/wpt/metadata/xhr/open-url-multi-window-6.htm.ini b/tests/wpt/metadata/xhr/open-url-multi-window-6.htm.ini index 50740305a60..59ebafd80c5 100644 --- a/tests/wpt/metadata/xhr/open-url-multi-window-6.htm.ini +++ b/tests/wpt/metadata/xhr/open-url-multi-window-6.htm.ini @@ -1,6 +1,6 @@ [open-url-multi-window-6.htm] type: testharness - expected: ERROR + expected: TIMEOUT [XMLHttpRequest: open() in document that is not fully active (but may be active) should throw] - expected: NOTRUN + expected: TIMEOUT From 21bf5a3a4b6398cd7c20449ba9110499feca7d6b Mon Sep 17 00:00:00 2001 From: Gregory Terzian Date: Sat, 2 Jun 2018 20:56:00 +0800 Subject: [PATCH 2/7] implement opener, disowning --- components/constellation/constellation.rs | 33 +++++-- components/constellation/pipeline.rs | 11 +++ components/script/dom/htmliframeelement.rs | 1 + components/script/dom/webidls/Window.webidl | 2 +- components/script/dom/window.rs | 30 ++++++- components/script/dom/windowproxy.rs | 85 +++++++++++++++++-- components/script/script_thread.rs | 50 +++++++++-- components/script_traits/lib.rs | 4 + components/script_traits/script_msg.rs | 6 +- tests/wpt/metadata/MANIFEST.json | 19 +++++ .../navigating-across-documents/005.html.ini | 3 + .../navigating-across-documents/007.html.ini | 1 - .../opener-closed.html.ini | 4 +- .../opener-multiple.html.ini | 5 -- .../opener-noreferrer.html.ini | 6 -- .../opener-setter.window.js.ini | 22 ----- .../opener.html.ini | 7 -- .../choose-_blank-001.html.ini | 8 -- .../choose-_blank-002.html.ini | 6 -- .../choose-_blank-003.html.ini | 6 -- .../choose-_parent-001.html.ini | 6 -- .../choose-_parent-002.html.ini | 6 -- .../choose-_parent-003.html.ini | 6 -- .../choose-_parent-004.html.ini | 6 -- .../choose-_self-002.html.ini | 6 -- .../choose-_top-001.html.ini | 5 -- .../choose-_top-002.html.ini | 5 -- .../choose-_top-003.html.ini | 5 -- .../windows/noreferrer-null-opener.html.ini | 6 -- ...s-origin-nested-browsing-contexts.html.ini | 1 - .../opener-setter.html | 32 +++++++ .../resources/opener-setter.html | 23 +++++ 32 files changed, 273 insertions(+), 143 deletions(-) create mode 100644 tests/wpt/metadata/html/browsers/browsing-the-web/navigating-across-documents/005.html.ini delete mode 100644 tests/wpt/metadata/html/browsers/windows/auxiliary-browsing-contexts/opener-multiple.html.ini delete mode 100644 tests/wpt/metadata/html/browsers/windows/auxiliary-browsing-contexts/opener-noreferrer.html.ini delete mode 100644 tests/wpt/metadata/html/browsers/windows/auxiliary-browsing-contexts/opener-setter.window.js.ini delete mode 100644 tests/wpt/metadata/html/browsers/windows/auxiliary-browsing-contexts/opener.html.ini delete mode 100644 tests/wpt/metadata/html/browsers/windows/browsing-context-names/choose-_blank-001.html.ini delete mode 100644 tests/wpt/metadata/html/browsers/windows/browsing-context-names/choose-_blank-002.html.ini delete mode 100644 tests/wpt/metadata/html/browsers/windows/browsing-context-names/choose-_blank-003.html.ini delete mode 100644 tests/wpt/metadata/html/browsers/windows/browsing-context-names/choose-_parent-001.html.ini delete mode 100644 tests/wpt/metadata/html/browsers/windows/browsing-context-names/choose-_parent-002.html.ini delete mode 100644 tests/wpt/metadata/html/browsers/windows/browsing-context-names/choose-_parent-003.html.ini delete mode 100644 tests/wpt/metadata/html/browsers/windows/browsing-context-names/choose-_parent-004.html.ini delete mode 100644 tests/wpt/metadata/html/browsers/windows/browsing-context-names/choose-_self-002.html.ini delete mode 100644 tests/wpt/metadata/html/browsers/windows/browsing-context-names/choose-_top-001.html.ini delete mode 100644 tests/wpt/metadata/html/browsers/windows/browsing-context-names/choose-_top-002.html.ini delete mode 100644 tests/wpt/metadata/html/browsers/windows/browsing-context-names/choose-_top-003.html.ini delete mode 100644 tests/wpt/metadata/html/browsers/windows/noreferrer-null-opener.html.ini create mode 100644 tests/wpt/web-platform-tests/html/browsers/windows/auxiliary-browsing-contexts/opener-setter.html create mode 100644 tests/wpt/web-platform-tests/html/browsers/windows/auxiliary-browsing-contexts/resources/opener-setter.html diff --git a/components/constellation/constellation.rs b/components/constellation/constellation.rs index f03643bdbd5..6e1e2b87f30 100644 --- a/components/constellation/constellation.rs +++ b/components/constellation/constellation.rs @@ -690,6 +690,7 @@ where browsing_context_id: BrowsingContextId, top_level_browsing_context_id: TopLevelBrowsingContextId, parent_info: Option, + opener: Option, initial_window_size: Option>, // TODO: we have to provide ownership of the LoadData // here, because it will be send on an ipc channel, @@ -764,6 +765,7 @@ where browsing_context_id, top_level_browsing_context_id, parent_info, + opener, script_to_constellation_chan: ScriptToConstellationChan { sender: self.script_sender.clone(), pipeline_id: pipeline_id, @@ -1256,6 +1258,13 @@ where warn!("Sending reply to get parent info failed ({:?}).", e); } }, + FromScriptMsg::GetTopForBrowsingContext(browsing_context_id, sender) => { + let result = self.browsing_contexts.get(&browsing_context_id) + .and_then(|bc| Some(bc.top_level_id)); + if let Err(e) = sender.send(result) { + warn!("Sending reply to get top for browsing context info failed ({:?}).", e); + } + }, FromScriptMsg::GetChildBrowsingContextId(browsing_context_id, index, sender) => { let result = self .browsing_contexts @@ -1547,11 +1556,12 @@ where (window_size, pipeline_id) }; - let (pipeline_url, parent_info) = { + let (pipeline_url, parent_info, opener) = { let pipeline = pipeline_id.and_then(|id| self.pipelines.get(&id)); let pipeline_url = pipeline.map(|pipeline| pipeline.url.clone()); let parent_info = pipeline.and_then(|pipeline| pipeline.parent_info); - (pipeline_url, parent_info) + let opener = pipeline.and_then(|pipeline| pipeline.opener); + (pipeline_url, parent_info, opener) }; self.close_browsing_context_children( @@ -1578,6 +1588,7 @@ where browsing_context_id, top_level_browsing_context_id, parent_info, + opener, window_size, load_data.clone(), sandbox, @@ -1672,6 +1683,7 @@ where browsing_context_id, top_level_browsing_context_id, None, + None, Some(window_size), load_data.clone(), sandbox, @@ -1805,6 +1817,7 @@ where load_info.info.browsing_context_id, load_info.info.top_level_browsing_context_id, Some(load_info.info.parent_pipeline_id), + None, window_size, load_data.clone(), load_info.sandbox, @@ -1850,6 +1863,7 @@ where browsing_context_id, top_level_browsing_context_id, Some(parent_pipeline_id), + None, script_sender, layout_sender, self.compositor_proxy.clone(), @@ -1887,8 +1901,8 @@ where 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, + let (opener_pipeline, opener_id) = match self.pipelines.get(&opener_pipeline_id) { + Some(opener_pipeline) => (opener_pipeline, opener_pipeline.browsing_context_id), None => return warn!("Auxiliary loaded url in closed pipeline {}.", opener_pipeline_id), }; let opener_host = match reg_host(&opener_pipeline.url) { @@ -1907,6 +1921,7 @@ where new_browsing_context_id, new_top_level_browsing_context_id, None, + Some(opener_id), script_sender, layout_sender, self.compositor_proxy.clone(), @@ -2010,8 +2025,8 @@ where // requested change so it can update its internal state. // // If replace is true, the current entry is replaced instead of a new entry being added. - let (browsing_context_id, parent_info) = match self.pipelines.get(&source_id) { - Some(pipeline) => (pipeline.browsing_context_id, pipeline.parent_info), + let (browsing_context_id, parent_info, opener) = match self.pipelines.get(&source_id) { + Some(pipeline) => (pipeline.browsing_context_id, pipeline.parent_info, pipeline.opener), None => { warn!("Pipeline {} loaded after closure.", source_id); return None; @@ -2088,6 +2103,7 @@ where browsing_context_id, top_level_id, None, + opener, window_size, load_data.clone(), sandbox, @@ -2372,19 +2388,21 @@ where // TODO: Save the sandbox state so it can be restored here. let sandbox = IFrameSandboxState::IFrameUnsandboxed; let new_pipeline_id = PipelineId::new(); - let (top_level_id, parent_info, window_size, is_private) = + let (top_level_id, parent_info, opener, window_size, is_private) = match self.browsing_contexts.get(&browsing_context_id) { Some(browsing_context) => { match self.pipelines.get(&browsing_context.pipeline_id) { Some(pipeline) => ( browsing_context.top_level_id, pipeline.parent_info, + pipeline.opener, browsing_context.size, pipeline.is_private, ), None => ( browsing_context.top_level_id, None, + None, browsing_context.size, false, ), @@ -2397,6 +2415,7 @@ where browsing_context_id, top_level_id, parent_info, + opener, window_size, load_data.clone(), sandbox, diff --git a/components/constellation/pipeline.rs b/components/constellation/pipeline.rs index 50d2911a535..62899328ca1 100644 --- a/components/constellation/pipeline.rs +++ b/components/constellation/pipeline.rs @@ -62,6 +62,8 @@ pub struct Pipeline { /// TODO: move this field to `BrowsingContext`. pub parent_info: Option, + pub opener: Option, + /// The event loop handling this pipeline. pub event_loop: Rc, @@ -119,6 +121,8 @@ pub struct InitialPipelineState { /// If `None`, this is the root. pub parent_info: Option, + pub opener: Option, + /// A channel to the associated constellation. pub script_to_constellation_chan: ScriptToConstellationChan, @@ -216,6 +220,7 @@ impl Pipeline { new_pipeline_id: state.id, browsing_context_id: state.browsing_context_id, top_level_browsing_context_id: state.top_level_browsing_context_id, + opener: state.opener, load_data: state.load_data.clone(), window_size: window_size, pipeline_port: pipeline_port, @@ -266,6 +271,7 @@ impl Pipeline { browsing_context_id: state.browsing_context_id, top_level_browsing_context_id: state.top_level_browsing_context_id, parent_info: state.parent_info, + opener: state.opener, script_to_constellation_chan: state.script_to_constellation_chan.clone(), scheduler_chan: state.scheduler_chan, devtools_chan: script_to_devtools_chan, @@ -312,6 +318,7 @@ impl Pipeline { state.browsing_context_id, state.top_level_browsing_context_id, state.parent_info, + state.opener, script_chan, pipeline_chan, state.compositor_proxy, @@ -329,6 +336,7 @@ impl Pipeline { browsing_context_id: BrowsingContextId, top_level_browsing_context_id: TopLevelBrowsingContextId, parent_info: Option, + opener: Option, event_loop: Rc, layout_chan: IpcSender, compositor_proxy: CompositorProxy, @@ -342,6 +350,7 @@ impl Pipeline { browsing_context_id: browsing_context_id, top_level_browsing_context_id: top_level_browsing_context_id, parent_info: parent_info, + opener: opener, event_loop: event_loop, layout_chan: layout_chan, compositor_proxy: compositor_proxy, @@ -469,6 +478,7 @@ pub struct UnprivilegedPipelineContent { top_level_browsing_context_id: TopLevelBrowsingContextId, browsing_context_id: BrowsingContextId, parent_info: Option, + opener: Option, script_to_constellation_chan: ScriptToConstellationChan, layout_to_constellation_chan: IpcSender, scheduler_chan: IpcSender, @@ -517,6 +527,7 @@ impl UnprivilegedPipelineContent { browsing_context_id: self.browsing_context_id, top_level_browsing_context_id: self.top_level_browsing_context_id, parent_info: self.parent_info, + opener: self.opener, control_chan: self.script_chan.clone(), control_port: self.script_port, script_to_constellation_chan: self.script_to_constellation_chan.clone(), diff --git a/components/script/dom/htmliframeelement.rs b/components/script/dom/htmliframeelement.rs index 373aa9c254f..b7540344c6a 100644 --- a/components/script/dom/htmliframeelement.rs +++ b/components/script/dom/htmliframeelement.rs @@ -177,6 +177,7 @@ impl HTMLIFrameElement { new_pipeline_id: new_pipeline_id, browsing_context_id: browsing_context_id, top_level_browsing_context_id: top_level_browsing_context_id, + opener: None, load_data: load_data.unwrap(), pipeline_port: pipeline_receiver, content_process_shutdown_chan: None, diff --git a/components/script/dom/webidls/Window.webidl b/components/script/dom/webidls/Window.webidl index c143ec56bbf..396bb936d71 100644 --- a/components/script/dom/webidls/Window.webidl +++ b/components/script/dom/webidls/Window.webidl @@ -35,7 +35,7 @@ // Note that this can return null in the case that the browsing context has been discarded. // https://github.com/whatwg/html/issues/2115 [Unforgeable] readonly attribute WindowProxy? top; - // attribute any opener; + attribute any opener; // Note that this can return null in the case that the browsing context has been discarded. // https://github.com/whatwg/html/issues/2115 [Replaceable] readonly attribute WindowProxy? parent; diff --git a/components/script/dom/window.rs b/components/script/dom/window.rs index 41b7441c3bf..b4c99ddfc94 100644 --- a/components/script/dom/window.rs +++ b/components/script/dom/window.rs @@ -61,10 +61,12 @@ use fetch; use ipc_channel::ipc::IpcSender; use ipc_channel::router::ROUTER; use js::jsapi::{JSAutoCompartment, JSContext}; -use js::jsapi::{JS_GC, JS_GetRuntime}; -use js::jsval::UndefinedValue; +use js::jsapi::{JS_GC, JS_GetRuntime, JSPROP_ENUMERATE}; +use js::jsval::{JSVal, UndefinedValue}; use js::rust::HandleValue; +use js::rust::wrappers::JS_DefineProperty; use layout_image::fetch_image_for_layout; +use libc; use microtask::MicrotaskQueue; use msg::constellation_msg::PipelineId; use net_traits::{ResourceThreads, ReferrerPolicy}; @@ -574,6 +576,30 @@ impl WindowMethods for Window { self.window_proxy().open(url, target, features) } + #[allow(unsafe_code)] + // https://html.spec.whatwg.org/multipage/#dom-opener + unsafe fn Opener(&self, cx: *mut JSContext) -> JSVal { + self.window_proxy().opener(cx) + } + + #[allow(unsafe_code)] + // https://html.spec.whatwg.org/multipage/#dom-opener + unsafe fn SetOpener(&self, cx: *mut JSContext, value: HandleValue) { + // Step 1. + if value.is_null() { + return self.window_proxy().disown(); + } + // Step 2. + let obj = self.reflector().get_jsobject(); + assert!(JS_DefineProperty(cx, + obj, + "opener\0".as_ptr() as *const libc::c_char, + value, + JSPROP_ENUMERATE, + None, + None)); + } + // https://html.spec.whatwg.org/multipage/#dom-window-closed fn Closed(&self) -> bool { self.window_proxy.get() 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, + /// 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, + /// Has the browsing context been disowned? + disowned: Cell, + /// The containing iframe element, if this is a same-origin iframe frame_element: Option>, @@ -95,7 +101,8 @@ impl WindowProxy { top_level_browsing_context_id: TopLevelBrowsingContextId, currently_active: Option, frame_element: Option<&Element>, - parent: Option<&WindowProxy>) + parent: Option<&WindowProxy>, + opener: Option) -> 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) -> DomRoot { 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) -> DomRoot { 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> { + fn create_auxiliary_browsing_context(&self, name: DOMString, noopener: bool) -> Option> { 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); } diff --git a/components/script/script_thread.rs b/components/script/script_thread.rs index 9e20a24e55b..8f4855c777b 100644 --- a/components/script/script_thread.rs +++ b/components/script/script_thread.rs @@ -157,6 +157,8 @@ struct InProgressLoad { top_level_browsing_context_id: TopLevelBrowsingContextId, /// The parent pipeline and frame type associated with this load, if any. parent_info: Option, + /// The opener, if this is an auxiliary. + opener: Option, /// The current window size associated with this pipeline. window_size: Option, /// Channel to the layout thread associated with this pipeline. @@ -183,6 +185,7 @@ impl InProgressLoad { browsing_context_id: BrowsingContextId, top_level_browsing_context_id: TopLevelBrowsingContextId, parent_info: Option, + opener: Option, layout_chan: Sender, window_size: Option, url: ServoUrl, @@ -195,6 +198,7 @@ impl InProgressLoad { browsing_context_id: browsing_context_id, top_level_browsing_context_id: top_level_browsing_context_id, parent_info: parent_info, + opener: opener, layout_chan: layout_chan, window_size: window_size, activity: DocumentActivity::FullyActive, @@ -569,6 +573,7 @@ impl ScriptThreadFactory for ScriptThread { let browsing_context_id = state.browsing_context_id; let top_level_browsing_context_id = state.top_level_browsing_context_id; let parent_info = state.parent_info; + let opener = state.opener; let mem_profiler_chan = state.mem_profiler_chan.clone(); let window_size = state.window_size; let script_thread = ScriptThread::new(state, @@ -583,7 +588,7 @@ impl ScriptThreadFactory for ScriptThread { let origin = MutableOrigin::new(load_data.url.origin()); let new_load = InProgressLoad::new(id, browsing_context_id, top_level_browsing_context_id, parent_info, - layout_chan, window_size, load_data.url.clone(), origin); + opener, layout_chan, window_size, load_data.url.clone(), origin); script_thread.pre_page_load(new_load, load_data); let reporter_name = format!("script-reporter-{}", id); @@ -706,6 +711,15 @@ impl ScriptThread { }); } + pub fn get_top_level_for_browsing_context(sender_pipeline: PipelineId, + browsing_context_id: BrowsingContextId) + -> Option { + SCRIPT_THREAD_ROOT.with(|root| root.get().and_then(|script_thread| { + let script_thread = unsafe { &*script_thread }; + script_thread.ask_constellation_for_top_level_info(sender_pipeline, browsing_context_id) + })) + } + pub fn find_document(id: PipelineId) -> Option> { SCRIPT_THREAD_ROOT.with(|root| root.get().and_then(|script_thread| { let script_thread = unsafe { &*script_thread }; @@ -1553,6 +1567,7 @@ impl ScriptThread { new_pipeline_id, browsing_context_id, top_level_browsing_context_id, + opener, load_data, window_size, pipeline_port, @@ -1597,6 +1612,7 @@ impl ScriptThread { browsing_context_id, top_level_browsing_context_id, parent_info, + opener, layout_chan, window_size, load_data.url.clone(), @@ -2025,6 +2041,16 @@ impl ScriptThread { result_receiver.recv().expect("Failed to get frame id from constellation.") } + fn ask_constellation_for_top_level_info(&self, + sender_pipeline: PipelineId, + browsing_context_id: BrowsingContextId) + -> Option { + let (result_sender, result_receiver) = ipc::channel().unwrap(); + let msg = ScriptMsg::GetTopForBrowsingContext(browsing_context_id, result_sender); + self.script_sender.send((sender_pipeline, msg)).expect("Failed to send to constellation."); + result_receiver.recv().expect("Failed to get top-level id from constellation.") + } + // Get the browsing context for a pipeline that may exist in another // script thread. If the browsing context already exists in the // `window_proxies` map, we return it, otherwise we recursively @@ -2034,7 +2060,8 @@ impl ScriptThread { fn remote_window_proxy(&self, global_to_clone: &GlobalScope, top_level_browsing_context_id: TopLevelBrowsingContextId, - pipeline_id: PipelineId) + pipeline_id: PipelineId, + opener: Option) -> Option> { let browsing_context_id = self.ask_constellation_for_browsing_context_id(pipeline_id)?; @@ -2042,12 +2069,13 @@ impl ScriptThread { return Some(DomRoot::from_ref(window_proxy)); } let parent = self.ask_constellation_for_parent_info(pipeline_id).and_then(|parent_id| { - self.remote_window_proxy(global_to_clone, top_level_browsing_context_id, parent_id) + self.remote_window_proxy(global_to_clone, top_level_browsing_context_id, parent_id, opener) }); let window_proxy = WindowProxy::new_dissimilar_origin(global_to_clone, browsing_context_id, top_level_browsing_context_id, - parent.r()); + parent.r(), + opener); self.window_proxies.borrow_mut().insert(browsing_context_id, Dom::from_ref(&*window_proxy)); Some(window_proxy) } @@ -2062,7 +2090,8 @@ impl ScriptThread { window: &Window, browsing_context_id: BrowsingContextId, top_level_browsing_context_id: TopLevelBrowsingContextId, - parent_info: Option) + parent_info: Option, + opener: Option) -> DomRoot { if let Some(window_proxy) = self.window_proxies.borrow().get(&browsing_context_id) { @@ -2075,15 +2104,17 @@ impl ScriptThread { let parent = match (parent_info, iframe.as_ref()) { (_, Some(iframe)) => Some(window_from_node(&**iframe).window_proxy()), (Some(parent_id), _) => self.remote_window_proxy(window.upcast(), - top_level_browsing_context_id, - parent_id), + top_level_browsing_context_id, + parent_id, + opener), _ => None, }; let window_proxy = WindowProxy::new(&window, browsing_context_id, top_level_browsing_context_id, iframe.r().map(Castable::upcast), - parent.r()); + parent.r(), + opener); self.window_proxies.borrow_mut().insert(browsing_context_id, Dom::from_ref(&*window_proxy)); window_proxy } @@ -2162,7 +2193,8 @@ impl ScriptThread { let window_proxy = self.local_window_proxy(&window, incomplete.browsing_context_id, incomplete.top_level_browsing_context_id, - incomplete.parent_info); + incomplete.parent_info, + incomplete.opener); window.init_window_proxy(&window_proxy); let last_modified = metadata.headers.as_ref().and_then(|headers| { diff --git a/components/script_traits/lib.rs b/components/script_traits/lib.rs index 476f41ef0f1..be39ab71cb2 100644 --- a/components/script_traits/lib.rs +++ b/components/script_traits/lib.rs @@ -193,6 +193,8 @@ pub struct NewLayoutInfo { pub browsing_context_id: BrowsingContextId, /// Id of the top-level browsing context associated with this pipeline. pub top_level_browsing_context_id: TopLevelBrowsingContextId, + /// Id of the opener, if any + pub opener: Option, /// Network request data which will be initiated by the script thread. pub load_data: LoadData, /// Information about the initial window size. @@ -521,6 +523,8 @@ pub struct InitialScriptState { pub browsing_context_id: BrowsingContextId, /// The ID of the top-level browsing context this script is part of. pub top_level_browsing_context_id: TopLevelBrowsingContextId, + /// The ID of the opener, if any. + pub opener: Option, /// A channel with which messages can be sent to us (the script thread). pub control_chan: IpcSender, /// A port on which messages sent by the constellation to script can be received. diff --git a/components/script_traits/script_msg.rs b/components/script_traits/script_msg.rs index 3668fd1e2fa..6dba5c00509 100644 --- a/components/script_traits/script_msg.rs +++ b/components/script_traits/script_msg.rs @@ -17,7 +17,8 @@ use embedder_traits::EmbedderMsg; use euclid::{Size2D, TypedSize2D}; use gfx_traits::Epoch; use ipc_channel::ipc::{IpcReceiver, IpcSender}; -use msg::constellation_msg::{BrowsingContextId, HistoryStateId, PipelineId, TraversalDirection}; +use msg::constellation_msg::{BrowsingContextId, PipelineId, TopLevelBrowsingContextId}; +use msg::constellation_msg::{HistoryStateId, TraversalDirection}; use net_traits::CoreResourceMsg; use net_traits::request::RequestInit; use net_traits::storage_thread::StorageType; @@ -105,6 +106,8 @@ pub enum ScriptMsg { GetBrowsingContextId(PipelineId, IpcSender>), /// Get the parent info for a given pipeline. GetParentInfo(PipelineId, IpcSender>), + /// Get the top-level browsing context info for a given browsing context. + GetTopForBrowsingContext(BrowsingContextId, IpcSender>), /// Get the nth child browsing context ID for a given browsing context, sorted in tree order. GetChildBrowsingContextId(BrowsingContextId, usize, IpcSender>), /// All pending loads are complete, and the `load` event for this pipeline @@ -184,6 +187,7 @@ impl fmt::Debug for ScriptMsg { GetClipboardContents(..) => "GetClipboardContents", GetBrowsingContextId(..) => "GetBrowsingContextId", GetParentInfo(..) => "GetParentInfo", + GetTopForBrowsingContext(..) => "GetParentBrowsingContext", GetChildBrowsingContextId(..) => "GetChildBrowsingContextId", LoadComplete => "LoadComplete", LoadUrl(..) => "LoadUrl", diff --git a/tests/wpt/metadata/MANIFEST.json b/tests/wpt/metadata/MANIFEST.json index c5b3b544067..9887429ef07 100644 --- a/tests/wpt/metadata/MANIFEST.json +++ b/tests/wpt/metadata/MANIFEST.json @@ -279733,6 +279733,11 @@ {} ] ], + "html/browsers/windows/auxiliary-browsing-contexts/resources/opener-setter.html": [ + [ + {} + ] + ], "html/browsers/windows/browsing-context-names/resources/choose-_parent-001-iframe-1.html": [ [ {} @@ -352032,6 +352037,12 @@ {} ] ], + "html/browsers/windows/auxiliary-browsing-contexts/opener-setter.html": [ + [ + "/html/browsers/windows/auxiliary-browsing-contexts/opener-setter.html", + {} + ] + ], "html/browsers/windows/auxiliary-browsing-contexts/opener-setter.window.js": [ [ "/html/browsers/windows/auxiliary-browsing-contexts/opener-setter.window.html", @@ -587647,6 +587658,10 @@ "f82aa6f0abe0d16a8b132e531d165988af0af99f", "testharness" ], + "html/browsers/windows/auxiliary-browsing-contexts/opener-setter.html": [ + "85c52e0b42e19bdd78dda120320d66ddbb2103b4", + "testharness" + ], "html/browsers/windows/auxiliary-browsing-contexts/opener-setter.window.js": [ "6d540ce97c94bff5845023098d0960d51dad62b4", "testharness" @@ -587675,6 +587690,10 @@ "6f43a5188c790577c4a1a03da270317eedba0fb0", "support" ], + "html/browsers/windows/auxiliary-browsing-contexts/resources/opener-setter.html": [ + "4112dae0cee66138a309b202a8d09d6b256c6d4d", + "support" + ], "html/browsers/windows/browsing-context-names/choose-_blank-001.html": [ "a1416f2eb8437a8824a26a0e2e6aa6fdede37ffa", "testharness" diff --git a/tests/wpt/metadata/html/browsers/browsing-the-web/navigating-across-documents/005.html.ini b/tests/wpt/metadata/html/browsers/browsing-the-web/navigating-across-documents/005.html.ini new file mode 100644 index 00000000000..20ee9003920 --- /dev/null +++ b/tests/wpt/metadata/html/browsers/browsing-the-web/navigating-across-documents/005.html.ini @@ -0,0 +1,3 @@ +[005.html] + type: testharness + expected: ERROR diff --git a/tests/wpt/metadata/html/browsers/browsing-the-web/navigating-across-documents/007.html.ini b/tests/wpt/metadata/html/browsers/browsing-the-web/navigating-across-documents/007.html.ini index 04538ab47a0..aadbdc0beda 100644 --- a/tests/wpt/metadata/html/browsers/browsing-the-web/navigating-across-documents/007.html.ini +++ b/tests/wpt/metadata/html/browsers/browsing-the-web/navigating-across-documents/007.html.ini @@ -2,4 +2,3 @@ type: testharness [Link with onclick javascript url and href navigation ] expected: FAIL - diff --git a/tests/wpt/metadata/html/browsers/windows/auxiliary-browsing-contexts/opener-closed.html.ini b/tests/wpt/metadata/html/browsers/windows/auxiliary-browsing-contexts/opener-closed.html.ini index d97cd045a92..9516c5bd53e 100644 --- a/tests/wpt/metadata/html/browsers/windows/auxiliary-browsing-contexts/opener-closed.html.ini +++ b/tests/wpt/metadata/html/browsers/windows/auxiliary-browsing-contexts/opener-closed.html.ini @@ -1,5 +1,5 @@ [opener-closed.html] type: testharness - expected: TIMEOUT + expected: CRASH [An auxiliary browsing context should report `null` for `window.opener` when that browsing context is discarded] - expected: TIMEOUT + expected: CRASH diff --git a/tests/wpt/metadata/html/browsers/windows/auxiliary-browsing-contexts/opener-multiple.html.ini b/tests/wpt/metadata/html/browsers/windows/auxiliary-browsing-contexts/opener-multiple.html.ini deleted file mode 100644 index 5f19cf016eb..00000000000 --- a/tests/wpt/metadata/html/browsers/windows/auxiliary-browsing-contexts/opener-multiple.html.ini +++ /dev/null @@ -1,5 +0,0 @@ -[opener-multiple.html] - type: testharness - expected: TIMEOUT - [An auxiliary browsing context should be able to open another auxiliary browsing context] - expected: TIMEOUT diff --git a/tests/wpt/metadata/html/browsers/windows/auxiliary-browsing-contexts/opener-noreferrer.html.ini b/tests/wpt/metadata/html/browsers/windows/auxiliary-browsing-contexts/opener-noreferrer.html.ini deleted file mode 100644 index dabad35e2ee..00000000000 --- a/tests/wpt/metadata/html/browsers/windows/auxiliary-browsing-contexts/opener-noreferrer.html.ini +++ /dev/null @@ -1,6 +0,0 @@ -[opener-noreferrer.html] - type: testharness - expected: TIMEOUT - [Auxiliary browsing context created with `rel="noreferrer"` should report `window.opener` `null`] - expected: TIMEOUT - diff --git a/tests/wpt/metadata/html/browsers/windows/auxiliary-browsing-contexts/opener-setter.window.js.ini b/tests/wpt/metadata/html/browsers/windows/auxiliary-browsing-contexts/opener-setter.window.js.ini deleted file mode 100644 index 9d293d228ba..00000000000 --- a/tests/wpt/metadata/html/browsers/windows/auxiliary-browsing-contexts/opener-setter.window.js.ini +++ /dev/null @@ -1,22 +0,0 @@ -[opener-setter.window.html] - [Setting window.opener to undefined] - expected: FAIL - - [Setting window.opener to 42] - expected: FAIL - - [Setting window.opener to function () { return "hi" }] - expected: FAIL - - [Setting window.opener to hi] - expected: FAIL - - [Setting window.opener to [object Object\]] - expected: FAIL - - [Setting window.opener to ] - expected: FAIL - - [Setting window.opener to Symbol()] - expected: FAIL - diff --git a/tests/wpt/metadata/html/browsers/windows/auxiliary-browsing-contexts/opener.html.ini b/tests/wpt/metadata/html/browsers/windows/auxiliary-browsing-contexts/opener.html.ini deleted file mode 100644 index 59a38204b5e..00000000000 --- a/tests/wpt/metadata/html/browsers/windows/auxiliary-browsing-contexts/opener.html.ini +++ /dev/null @@ -1,7 +0,0 @@ -[opener.html] - type: testharness - 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 diff --git a/tests/wpt/metadata/html/browsers/windows/browsing-context-names/choose-_blank-001.html.ini b/tests/wpt/metadata/html/browsers/windows/browsing-context-names/choose-_blank-001.html.ini deleted file mode 100644 index de54ed6babc..00000000000 --- a/tests/wpt/metadata/html/browsers/windows/browsing-context-names/choose-_blank-001.html.ini +++ /dev/null @@ -1,8 +0,0 @@ -[choose-_blank-001.html] - type: testharness - [window.open into `_blank` should create a new browsing context each time] - expected: FAIL - - [`_blank` should be ASCII case-insensitive] - expected: FAIL - diff --git a/tests/wpt/metadata/html/browsers/windows/browsing-context-names/choose-_blank-002.html.ini b/tests/wpt/metadata/html/browsers/windows/browsing-context-names/choose-_blank-002.html.ini deleted file mode 100644 index da270341b6f..00000000000 --- a/tests/wpt/metadata/html/browsers/windows/browsing-context-names/choose-_blank-002.html.ini +++ /dev/null @@ -1,6 +0,0 @@ -[choose-_blank-002.html] - type: testharness - expected: TIMEOUT - [Context for opened noreferrer link targeted to "_blank" should not have opener reference] - expected: TIMEOUT - diff --git a/tests/wpt/metadata/html/browsers/windows/browsing-context-names/choose-_blank-003.html.ini b/tests/wpt/metadata/html/browsers/windows/browsing-context-names/choose-_blank-003.html.ini deleted file mode 100644 index 34eeff13c09..00000000000 --- a/tests/wpt/metadata/html/browsers/windows/browsing-context-names/choose-_blank-003.html.ini +++ /dev/null @@ -1,6 +0,0 @@ -[choose-_blank-003.html] - type: testharness - expected: TIMEOUT - [Context created by link targeting "_blank" should retain opener reference] - expected: TIMEOUT - diff --git a/tests/wpt/metadata/html/browsers/windows/browsing-context-names/choose-_parent-001.html.ini b/tests/wpt/metadata/html/browsers/windows/browsing-context-names/choose-_parent-001.html.ini deleted file mode 100644 index 13139ca78c7..00000000000 --- a/tests/wpt/metadata/html/browsers/windows/browsing-context-names/choose-_parent-001.html.ini +++ /dev/null @@ -1,6 +0,0 @@ -[choose-_parent-001.html] - type: testharness - expected: TIMEOUT - [The parent browsing context must be chosen if the given name is `_parent`] - expected: TIMEOUT - diff --git a/tests/wpt/metadata/html/browsers/windows/browsing-context-names/choose-_parent-002.html.ini b/tests/wpt/metadata/html/browsers/windows/browsing-context-names/choose-_parent-002.html.ini deleted file mode 100644 index beaa956fd61..00000000000 --- a/tests/wpt/metadata/html/browsers/windows/browsing-context-names/choose-_parent-002.html.ini +++ /dev/null @@ -1,6 +0,0 @@ -[choose-_parent-002.html] - type: testharness - expected: ERROR - [choosing _parent context: multiple nested contexts] - expected: FAIL - diff --git a/tests/wpt/metadata/html/browsers/windows/browsing-context-names/choose-_parent-003.html.ini b/tests/wpt/metadata/html/browsers/windows/browsing-context-names/choose-_parent-003.html.ini deleted file mode 100644 index a2bcdf6ed59..00000000000 --- a/tests/wpt/metadata/html/browsers/windows/browsing-context-names/choose-_parent-003.html.ini +++ /dev/null @@ -1,6 +0,0 @@ -[choose-_parent-003.html] - type: testharness - expected: ERROR - [_parent should reuse window.parent context] - expected: FAIL - diff --git a/tests/wpt/metadata/html/browsers/windows/browsing-context-names/choose-_parent-004.html.ini b/tests/wpt/metadata/html/browsers/windows/browsing-context-names/choose-_parent-004.html.ini deleted file mode 100644 index 853b3be6979..00000000000 --- a/tests/wpt/metadata/html/browsers/windows/browsing-context-names/choose-_parent-004.html.ini +++ /dev/null @@ -1,6 +0,0 @@ -[choose-_parent-004.html] - type: testharness - expected: TIMEOUT - [choosing _parent context should be case-insensitive] - expected: TIMEOUT - diff --git a/tests/wpt/metadata/html/browsers/windows/browsing-context-names/choose-_self-002.html.ini b/tests/wpt/metadata/html/browsers/windows/browsing-context-names/choose-_self-002.html.ini deleted file mode 100644 index 8647f6bb351..00000000000 --- a/tests/wpt/metadata/html/browsers/windows/browsing-context-names/choose-_self-002.html.ini +++ /dev/null @@ -1,6 +0,0 @@ -[choose-_self-002.html] - type: testharness - expected: TIMEOUT - [choosing _self context should be case-insensitive] - expected: TIMEOUT - diff --git a/tests/wpt/metadata/html/browsers/windows/browsing-context-names/choose-_top-001.html.ini b/tests/wpt/metadata/html/browsers/windows/browsing-context-names/choose-_top-001.html.ini deleted file mode 100644 index 13bbd30d86b..00000000000 --- a/tests/wpt/metadata/html/browsers/windows/browsing-context-names/choose-_top-001.html.ini +++ /dev/null @@ -1,5 +0,0 @@ -[choose-_top-001.html] - type: testharness - [Should choose current browsing context for "_top" if current is top] - expected: FAIL - diff --git a/tests/wpt/metadata/html/browsers/windows/browsing-context-names/choose-_top-002.html.ini b/tests/wpt/metadata/html/browsers/windows/browsing-context-names/choose-_top-002.html.ini deleted file mode 100644 index 464f944cdf3..00000000000 --- a/tests/wpt/metadata/html/browsers/windows/browsing-context-names/choose-_top-002.html.ini +++ /dev/null @@ -1,5 +0,0 @@ -[choose-_top-002.html] - type: testharness - [Should choose top browsing context for "_top" if current is not top] - expected: FAIL - diff --git a/tests/wpt/metadata/html/browsers/windows/browsing-context-names/choose-_top-003.html.ini b/tests/wpt/metadata/html/browsers/windows/browsing-context-names/choose-_top-003.html.ini deleted file mode 100644 index ee59a5236c8..00000000000 --- a/tests/wpt/metadata/html/browsers/windows/browsing-context-names/choose-_top-003.html.ini +++ /dev/null @@ -1,5 +0,0 @@ -[choose-_top-003.html] - type: testharness - [choosing _top context should be case-insensitive] - expected: FAIL - diff --git a/tests/wpt/metadata/html/browsers/windows/noreferrer-null-opener.html.ini b/tests/wpt/metadata/html/browsers/windows/noreferrer-null-opener.html.ini deleted file mode 100644 index 5b7cd2d3c82..00000000000 --- a/tests/wpt/metadata/html/browsers/windows/noreferrer-null-opener.html.ini +++ /dev/null @@ -1,6 +0,0 @@ -[noreferrer-null-opener.html] - type: testharness - expected: TIMEOUT - [rel=noreferrer nullifies window.opener] - expected: TIMEOUT - diff --git a/tests/wpt/metadata/html/browsers/windows/targeting-cross-origin-nested-browsing-contexts.html.ini b/tests/wpt/metadata/html/browsers/windows/targeting-cross-origin-nested-browsing-contexts.html.ini index 7e01a712d91..4ee3fbb8304 100644 --- a/tests/wpt/metadata/html/browsers/windows/targeting-cross-origin-nested-browsing-contexts.html.ini +++ b/tests/wpt/metadata/html/browsers/windows/targeting-cross-origin-nested-browsing-contexts.html.ini @@ -1,5 +1,4 @@ [targeting-cross-origin-nested-browsing-contexts.html] type: testharness - expected: TIMEOUT [Targeting nested browsing contexts] expected: FAIL diff --git a/tests/wpt/web-platform-tests/html/browsers/windows/auxiliary-browsing-contexts/opener-setter.html b/tests/wpt/web-platform-tests/html/browsers/windows/auxiliary-browsing-contexts/opener-setter.html new file mode 100644 index 00000000000..85c52e0b42e --- /dev/null +++ b/tests/wpt/web-platform-tests/html/browsers/windows/auxiliary-browsing-contexts/opener-setter.html @@ -0,0 +1,32 @@ + + + + Auxiliary Browing Contexts: window.opener setter + + + + + +
+ + + diff --git a/tests/wpt/web-platform-tests/html/browsers/windows/auxiliary-browsing-contexts/resources/opener-setter.html b/tests/wpt/web-platform-tests/html/browsers/windows/auxiliary-browsing-contexts/resources/opener-setter.html new file mode 100644 index 00000000000..4112dae0cee --- /dev/null +++ b/tests/wpt/web-platform-tests/html/browsers/windows/auxiliary-browsing-contexts/resources/opener-setter.html @@ -0,0 +1,23 @@ + + + +

This window should set the window.opener attribute

+ + + + + From e27ba16c3fda8a851b358b00852c2e0784649702 Mon Sep 17 00:00:00 2001 From: Gregory Terzian Date: Sun, 3 Jun 2018 17:31:11 +0800 Subject: [PATCH 3/7] share event-loops based on eTLD+1 --- components/constellation/constellation.rs | 37 +++++------------------ 1 file changed, 7 insertions(+), 30 deletions(-) diff --git a/components/constellation/constellation.rs b/components/constellation/constellation.rs index 6e1e2b87f30..c0c3bd566fa 100644 --- a/components/constellation/constellation.rs +++ b/components/constellation/constellation.rs @@ -264,18 +264,13 @@ pub struct Constellation { /// WebRender thread. webrender_api_sender: webrender_api::RenderApiSender, - /// The set of all event loops in the browser. We generate a new - /// event loop for each registered domain name (aka eTLD+1) in - /// each top-level browsing context. We store the event loops in a map - /// indexed by top-level browsing context id - /// (as a `TopLevelBrowsingContextId`) and registered - /// domain name (as a `Host`) to event loops. This double - /// indirection ensures that separate tabs do not share event - /// loops, even if the same domain is loaded in each. + /// The set of all event loops in the browser. + /// We store the event loops in a map + /// indexed by registered domain name (as a `Host`) to event loops. /// It is important that scripts with the same eTLD+1 /// share an event loop, since they can use `document.domain` /// to become same-origin, at which point they can share DOM objects. - event_loops: HashMap>>, + event_loops: HashMap>, joint_session_histories: HashMap, @@ -718,9 +713,7 @@ where None => (None, None), Some(host) => { let event_loop = self - .event_loops - .get(&top_level_browsing_context_id) - .and_then(|map| map.get(&host)) + .event_loops.get(&host) .and_then(|weak| weak.upgrade()); match event_loop { None => (None, Some(host)), @@ -806,9 +799,8 @@ where "Adding new host entry {} for top-level browsing context {}.", host, top_level_browsing_context_id ); - self.event_loops - .entry(top_level_browsing_context_id) - .or_insert_with(HashMap::new) + let _ = self + .event_loops .insert(host, Rc::downgrade(&pipeline.event_loop)); } @@ -1905,18 +1897,7 @@ where Some(opener_pipeline) => (opener_pipeline, opener_pipeline.browsing_context_id), 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, @@ -3565,10 +3546,6 @@ where session_history.remove_entries_for_browsing_context(browsing_context_id); } - if BrowsingContextId::from(browsing_context.top_level_id) == browsing_context_id { - self.event_loops.remove(&browsing_context.top_level_id); - } - let parent_info = self .pipelines .get(&browsing_context.pipeline_id) From a0082c57c8bb9a1c62f03bffa3f636e0791ee7b3 Mon Sep 17 00:00:00 2001 From: Gregory Terzian Date: Sun, 3 Jun 2018 22:59:36 +0800 Subject: [PATCH 4/7] iframe: use value of name attr to set nested bc name --- components/script/dom/htmliframeelement.rs | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/components/script/dom/htmliframeelement.rs b/components/script/dom/htmliframeelement.rs index b7540344c6a..658961a1725 100644 --- a/components/script/dom/htmliframeelement.rs +++ b/components/script/dom/htmliframeelement.rs @@ -76,6 +76,7 @@ pub struct HTMLIFrameElement { sandbox_allowance: Cell>, load_blocker: DomRefCell>, visibility: Cell, + name: DomRefCell, } impl HTMLIFrameElement { @@ -223,6 +224,16 @@ impl HTMLIFrameElement { return; } + // https://html.spec.whatwg.org/multipage/#attr-iframe-name + // Note: the spec says to set the name 'when the nested browsing context is created'. + // The current implementation sets the name on the window, + // when the iframe attributes are first processed. + if mode == ProcessingMode::FirstTime { + if let Some(window) = self.GetContentWindow() { + window.set_name(self.name.borrow().clone()) + } + } + let url = self.get_url(); // TODO: check ancestor browsing contexts for same URL @@ -299,6 +310,7 @@ impl HTMLIFrameElement { sandbox_allowance: Cell::new(None), load_blocker: DomRefCell::new(None), visibility: Cell::new(true), + name: DomRefCell::new(DOMString::new()) } } @@ -471,6 +483,7 @@ impl HTMLIFrameElementMethods for HTMLIFrameElement { // https://html.spec.whatwg.org/multipage/#dom-iframe-name fn SetName(&self, name: DOMString) { + *self.name.borrow_mut() = name.clone(); if let Some(window) = self.GetContentWindow() { window.set_name(name) } @@ -481,7 +494,7 @@ impl HTMLIFrameElementMethods for HTMLIFrameElement { if let Some(window) = self.GetContentWindow() { window.get_name() } else { - DOMString::new() + self.name.borrow().clone() } } } From fee542831683d52b07cc59bf62fb1b5442cd94ba Mon Sep 17 00:00:00 2001 From: Gregory Terzian Date: Tue, 5 Jun 2018 09:45:39 +0800 Subject: [PATCH 5/7] make auxiliary browsing-context script-closeable --- components/script/dom/window.rs | 6 +++--- .../auxiliary-browsing-contexts/opener-closed.html.ini | 5 ----- .../auxiliary-browsing-contexts/opener-noopener.html.ini | 5 ----- .../browsing-context-names/choose-_self-001.html.ini | 6 ------ 4 files changed, 3 insertions(+), 19 deletions(-) delete mode 100644 tests/wpt/metadata/html/browsers/windows/auxiliary-browsing-contexts/opener-closed.html.ini delete mode 100644 tests/wpt/metadata/html/browsers/windows/auxiliary-browsing-contexts/opener-noopener.html.ini delete mode 100644 tests/wpt/metadata/html/browsers/windows/browsing-context-names/choose-_self-001.html.ini diff --git a/components/script/dom/window.rs b/components/script/dom/window.rs index b4c99ddfc94..fe3a1fdbc12 100644 --- a/components/script/dom/window.rs +++ b/components/script/dom/window.rs @@ -609,13 +609,13 @@ impl WindowMethods for Window { // https://html.spec.whatwg.org/multipage/#dom-window-close fn Close(&self) { + let window_proxy = self.window_proxy(); // Note: check the length of the "session history", as opposed to the joint session history? // see https://github.com/whatwg/html/issues/3734 if let Ok(history_length) = self.History().GetLength() { - // TODO: allow auxilliary browsing contexts created by script to be script-closeable, - // regardless of history length. + let is_auxiliary = window_proxy.is_auxiliary(); // https://html.spec.whatwg.org/multipage/#script-closable - let is_script_closable = self.is_top_level() && history_length == 1; + let is_script_closable = (self.is_top_level() && history_length == 1) || is_auxiliary; if is_script_closable { let doc = self.Document(); // https://html.spec.whatwg.org/multipage/#closing-browsing-contexts diff --git a/tests/wpt/metadata/html/browsers/windows/auxiliary-browsing-contexts/opener-closed.html.ini b/tests/wpt/metadata/html/browsers/windows/auxiliary-browsing-contexts/opener-closed.html.ini deleted file mode 100644 index 9516c5bd53e..00000000000 --- a/tests/wpt/metadata/html/browsers/windows/auxiliary-browsing-contexts/opener-closed.html.ini +++ /dev/null @@ -1,5 +0,0 @@ -[opener-closed.html] - type: testharness - expected: CRASH - [An auxiliary browsing context should report `null` for `window.opener` when that browsing context is discarded] - expected: CRASH diff --git a/tests/wpt/metadata/html/browsers/windows/auxiliary-browsing-contexts/opener-noopener.html.ini b/tests/wpt/metadata/html/browsers/windows/auxiliary-browsing-contexts/opener-noopener.html.ini deleted file mode 100644 index d65181dcd1c..00000000000 --- a/tests/wpt/metadata/html/browsers/windows/auxiliary-browsing-contexts/opener-noopener.html.ini +++ /dev/null @@ -1,5 +0,0 @@ -[opener-noopener.html] - type: testharness - [Auxiliary browsing context created via `window.open` setting `noopener` should report `window.opener` `null`] - expected: FAIL - diff --git a/tests/wpt/metadata/html/browsers/windows/browsing-context-names/choose-_self-001.html.ini b/tests/wpt/metadata/html/browsers/windows/browsing-context-names/choose-_self-001.html.ini deleted file mode 100644 index 75e00d9632f..00000000000 --- a/tests/wpt/metadata/html/browsers/windows/browsing-context-names/choose-_self-001.html.ini +++ /dev/null @@ -1,6 +0,0 @@ -[choose-_self-001.html] - type: testharness - expected: TIMEOUT - [The current browsing context must be chosen if the given name is "_self"] - expected: TIMEOUT - From 96f75465cfddc616721ea24cbc2e011611e432f9 Mon Sep 17 00:00:00 2001 From: Gregory Terzian Date: Tue, 5 Jun 2018 10:42:09 +0800 Subject: [PATCH 6/7] rudimentary handling of tabs --- ports/servo/browser.rs | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/ports/servo/browser.rs b/ports/servo/browser.rs index 161781a8052..a2c69a0365a 100644 --- a/ports/servo/browser.rs +++ b/ports/servo/browser.rs @@ -26,6 +26,12 @@ pub struct Browser { /// are not supported yet. None until created. browser_id: Option, + // A rudimentary stack of "tabs". + // EmbedderMsg::BrowserCreated will push onto it. + // EmbedderMsg::CloseBrowser will pop from it, + // and exit if it is empty afterwards. + browsers: Vec, + title: Option, status: Option, favicon: Option, @@ -47,6 +53,7 @@ impl Browser { title: None, current_url: None, browser_id: None, + browsers: Vec::new(), status: None, favicon: None, loading_state: None, @@ -62,6 +69,7 @@ impl Browser { pub fn set_browser_id(&mut self, browser_id: BrowserId) { self.browser_id = Some(browser_id); + self.browsers.push(browser_id); } pub fn handle_window_events(&mut self, events: Vec) { @@ -293,7 +301,7 @@ impl Browser { } EmbedderMsg::BrowserCreated(new_browser_id) => { // TODO: properly handle a new "tab" - self.browser_id = Some(new_browser_id); + self.browsers.push(new_browser_id); self.event_queue.push(WindowEvent::SelectBrowser(new_browser_id)); } EmbedderMsg::KeyEvent(ch, key, state, modified) => { @@ -321,10 +329,13 @@ impl Browser { self.loading_state = Some(LoadingState::Loaded); } EmbedderMsg::CloseBrowser => { - self.browser_id = None; - // Nothing left to do for now, - // but could hide a tab, and show another one, instead of quitting. - self.event_queue.push(WindowEvent::Quit); + // TODO: close the appropriate "tab". + let _ = self.browsers.pop(); + if let Some(prev_browser_id) = self.browsers.last() { + self.event_queue.push(WindowEvent::SelectBrowser(*prev_browser_id)); + } else { + self.event_queue.push(WindowEvent::Quit); + } }, EmbedderMsg::Shutdown => { self.shutdown_requested = true; From e784f5a9f7a4c3eec92b946b0debd4cbcb942ae7 Mon Sep 17 00:00:00 2001 From: Gregory Terzian Date: Thu, 7 Jun 2018 22:37:53 +0800 Subject: [PATCH 7/7] Refactor embedder NewBrowser flow --- components/compositing/windowing.rs | 3 +- components/constellation/constellation.rs | 24 ++++---- components/script_traits/lib.rs | 2 +- components/servo/lib.rs | 8 ++- ports/libsimpleservo/src/api.rs | 74 +++++++++++++++++------ ports/servo/browser.rs | 9 ++- ports/servo/non_android_main.rs | 11 +--- 7 files changed, 83 insertions(+), 48 deletions(-) diff --git a/components/compositing/windowing.rs b/components/compositing/windowing.rs index b81b1e3ebc7..654f7341678 100644 --- a/components/compositing/windowing.rs +++ b/components/compositing/windowing.rs @@ -8,7 +8,6 @@ use embedder_traits::EventLoopWaker; use euclid::TypedScale; #[cfg(feature = "gleam")] use gleam::gl; -use ipc_channel::ipc::IpcSender; use msg::constellation_msg::{Key, KeyModifiers, KeyState, TopLevelBrowsingContextId, TraversalDirection}; use script_traits::{MouseButton, TouchEventType, TouchId}; use servo_geometry::{DeviceIndependentPixel, DeviceUintLength}; @@ -75,7 +74,7 @@ pub enum WindowEvent { /// Sent when Ctr+R/Apple+R is called to reload the current page. Reload(TopLevelBrowsingContextId), /// Create a new top level browsing context - NewBrowser(ServoUrl, IpcSender), + NewBrowser(ServoUrl, TopLevelBrowsingContextId), /// Close a top level browsing context CloseBrowser(TopLevelBrowsingContextId), /// Panic a top level browsing context. diff --git a/components/constellation/constellation.rs b/components/constellation/constellation.rs index c0c3bd566fa..a08768c06dc 100644 --- a/components/constellation/constellation.rs +++ b/components/constellation/constellation.rs @@ -578,7 +578,8 @@ where let swmanager_receiver = route_ipc_receiver_to_new_mpsc_receiver_preserving_errors(swmanager_receiver); - PipelineNamespace::install(PipelineNamespaceId(0)); + // Zero is reserved for the embedder. + PipelineNamespace::install(PipelineNamespaceId(1)); let mut constellation: Constellation = Constellation { script_sender: ipc_script_sender, @@ -605,8 +606,10 @@ where pipelines: HashMap::new(), browsing_contexts: HashMap::new(), pending_changes: vec![], - // We initialize the namespace at 1, since we reserved namespace 0 for the constellation - next_pipeline_namespace_id: PipelineNamespaceId(1), + // We initialize the namespace at 2, + // since we reserved namespace 0 for the embedder, + // and 0 for the constellation + next_pipeline_namespace_id: PipelineNamespaceId(2), focus_pipeline_id: None, time_profiler_chan: state.time_profiler_chan, mem_profiler_chan: state.mem_profiler_chan, @@ -1026,8 +1029,8 @@ where }, // Create a new top level browsing context. Will use response_chan to return // the browsing context id. - FromCompositorMsg::NewBrowser(url, response_chan) => { - self.handle_new_top_level_browsing_context(url, response_chan); + FromCompositorMsg::NewBrowser(url, top_level_browsing_context_id) => { + self.handle_new_top_level_browsing_context(url, top_level_browsing_context_id); }, // Close a top level browsing context. FromCompositorMsg::CloseBrowser(top_level_browsing_context_id) => { @@ -1651,17 +1654,12 @@ where fn handle_new_top_level_browsing_context( &mut self, url: ServoUrl, - reply: IpcSender, + top_level_browsing_context_id: TopLevelBrowsingContextId ) { let window_size = self.window_size.initial_viewport; let pipeline_id = PipelineId::new(); - let top_level_browsing_context_id = TopLevelBrowsingContextId::new(); - if let Err(e) = reply.send(top_level_browsing_context_id) { - warn!( - "Failed to send newly created top level browsing context ({}).", - e - ); - } + let msg = (Some(top_level_browsing_context_id), EmbedderMsg::BrowserCreated(top_level_browsing_context_id)); + self.embedder_proxy.send(msg); let browsing_context_id = BrowsingContextId::from(top_level_browsing_context_id); let load_data = LoadData::new(url.clone(), None, None, None); let sandbox = IFrameSandboxState::IFrameUnsandboxed; diff --git a/components/script_traits/lib.rs b/components/script_traits/lib.rs index be39ab71cb2..02b4bd7efed 100644 --- a/components/script_traits/lib.rs +++ b/components/script_traits/lib.rs @@ -717,7 +717,7 @@ pub enum ConstellationMsg { /// Dispatch WebVR events to the subscribed script threads. WebVREvents(Vec, Vec), /// Create a new top level browsing context. - NewBrowser(ServoUrl, IpcSender), + NewBrowser(ServoUrl, TopLevelBrowsingContextId), /// Close a top level browsing context. CloseBrowser(TopLevelBrowsingContextId), /// Panic a top level browsing context. diff --git a/components/servo/lib.rs b/components/servo/lib.rs index 5623874408f..278e590bae5 100644 --- a/components/servo/lib.rs +++ b/components/servo/lib.rs @@ -87,6 +87,7 @@ use gaol::sandbox::{ChildSandbox, ChildSandboxMethods}; use gfx::font_cache_thread::FontCacheThread; use ipc_channel::ipc::{self, IpcSender}; use log::{Log, Metadata, Record}; +use msg::constellation_msg::{PipelineNamespace, PipelineNamespaceId}; use net::resource_thread::new_resource_threads; use net_traits::IpcSend; use profile::mem as profile_mem; @@ -135,6 +136,9 @@ impl Servo where Window: WindowMethods + 'static { // Make sure the gl context is made current. window.prepare_for_composite(Length::new(0), Length::new(0)); + // Reserving a namespace to create TopLevelBrowserContextId. + PipelineNamespace::install(PipelineNamespaceId(0)); + // Get both endpoints of a special channel for communication between // the client window and the compositor. This channel is unique because // messages to client may need to pump a platform-specific event loop @@ -326,8 +330,8 @@ impl Servo where Window: WindowMethods + 'static { self.compositor.capture_webrender(); } - WindowEvent::NewBrowser(url, response_chan) => { - let msg = ConstellationMsg::NewBrowser(url, response_chan); + WindowEvent::NewBrowser(url, browser_id) => { + let msg = ConstellationMsg::NewBrowser(url, browser_id); if let Err(e) = self.constellation_chan.send(msg) { warn!("Sending NewBrowser message to constellation failed ({}).", e); } diff --git a/ports/libsimpleservo/src/api.rs b/ports/libsimpleservo/src/api.rs index 9305465a724..69d42ed349f 100644 --- a/ports/libsimpleservo/src/api.rs +++ b/ports/libsimpleservo/src/api.rs @@ -8,7 +8,6 @@ use servo::compositing::windowing::{AnimationState, EmbedderCoordinates, MouseWi use servo::embedder_traits::EmbedderMsg; use servo::embedder_traits::resources::{self, Resource}; use servo::euclid::{Length, TypedPoint2D, TypedScale, TypedSize2D, TypedVector2D}; -use servo::ipc_channel::ipc; use servo::msg::constellation_msg::TraversalDirection; use servo::script_traits::{MouseButton, TouchEventType}; use servo::servo_config::opts; @@ -75,7 +74,14 @@ pub struct ServoGlue { servo: Servo, batch_mode: bool, callbacks: Rc, - browser_id: BrowserId, + /// id of the top level browsing context. It is unique as tabs + /// are not supported yet. None until created. + browser_id: Option, + // A rudimentary stack of "tabs". + // EmbedderMsg::BrowserCreated will push onto it. + // EmbedderMsg::CloseBrowser will pop from it, + // and exit if it is empty afterwards. + browsers: Vec, events: Vec, current_url: Option, } @@ -133,28 +139,34 @@ pub fn init( waker, }); - let mut servo = Servo::new(callbacks.clone()); - - let (sender, receiver) = ipc::channel().map_err(|_| "Can't create ipc::channel")?; - servo.handle_events(vec![WindowEvent::NewBrowser(url.clone(), sender)]); - let browser_id = receiver.recv().map_err(|_| "Can't receive browser_id")?; - servo.handle_events(vec![WindowEvent::SelectBrowser(browser_id)]); + let servo = Servo::new(callbacks.clone()); SERVO.with(|s| { - *s.borrow_mut() = Some(ServoGlue { + let mut servo_glue = ServoGlue { servo, batch_mode: false, callbacks, - browser_id, + browser_id: None, + browsers: vec![], events: vec![], - current_url: Some(url), - }); + current_url: Some(url.clone()), + }; + let browser_id = BrowserId::new(); + let _ = servo_glue.process_event(WindowEvent::NewBrowser(url, browser_id)); + *s.borrow_mut() = Some(servo_glue); }); Ok(()) } impl ServoGlue { + fn get_browser_id(&self) -> Result { + let browser_id = match self.browser_id { + Some(id) => id, + None => return Err("No BrowserId set yet.") + }; + Ok(browser_id) + } /// This is the Servo heartbeat. This needs to be called /// everytime wakeup is called or when embedder wants Servo /// to act on its pending events. @@ -182,7 +194,8 @@ impl ServoGlue { ServoUrl::parse(url) .map_err(|_| "Can't parse URL") .and_then(|url| { - let event = WindowEvent::LoadUrl(self.browser_id, url); + let browser_id = self.get_browser_id()?; + let event = WindowEvent::LoadUrl(browser_id, url); self.process_event(event) }) } @@ -190,7 +203,8 @@ impl ServoGlue { /// Reload the page. pub fn reload(&mut self) -> Result<(), &'static str> { debug!("reload"); - let event = WindowEvent::Reload(self.browser_id); + let browser_id = self.get_browser_id()?; + let event = WindowEvent::Reload(browser_id); self.process_event(event) } @@ -203,14 +217,16 @@ impl ServoGlue { /// Go back in history. pub fn go_back(&mut self) -> Result<(), &'static str> { debug!("go_back"); - let event = WindowEvent::Navigation(self.browser_id, TraversalDirection::Back(1)); + let browser_id = self.get_browser_id()?; + let event = WindowEvent::Navigation(browser_id, TraversalDirection::Back(1)); self.process_event(event) } /// Go forward in history. pub fn go_forward(&mut self) -> Result<(), &'static str> { debug!("go_forward"); - let event = WindowEvent::Navigation(self.browser_id, TraversalDirection::Forward(1)); + let browser_id = self.get_browser_id()?; + let event = WindowEvent::Navigation(browser_id, TraversalDirection::Forward(1)); self.process_event(event) } @@ -329,7 +345,31 @@ impl ServoGlue { info!("Alert: {}", message); let _ = sender.send(()); }, - EmbedderMsg::CloseBrowser | + 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.browsers.push(new_browser_id); + if self.browser_id.is_none() { + self.browser_id = Some(new_browser_id); + } + self.events.push(WindowEvent::SelectBrowser(new_browser_id)); + }, + EmbedderMsg::CloseBrowser => { + // TODO: close the appropriate "tab". + let _ = self.browsers.pop(); + if let Some(prev_browser_id) = self.browsers.last() { + self.browser_id = Some(*prev_browser_id); + self.events.push(WindowEvent::SelectBrowser(*prev_browser_id)); + } else { + self.events.push(WindowEvent::Quit); + } + }, EmbedderMsg::Status(..) | EmbedderMsg::SelectFiles(..) | EmbedderMsg::MoveTo(..) | diff --git a/ports/servo/browser.rs b/ports/servo/browser.rs index a2c69a0365a..49f3d1c0626 100644 --- a/ports/servo/browser.rs +++ b/ports/servo/browser.rs @@ -67,11 +67,6 @@ impl Browser { mem::replace(&mut self.event_queue, Vec::new()) } - pub fn set_browser_id(&mut self, browser_id: BrowserId) { - self.browser_id = Some(browser_id); - self.browsers.push(browser_id); - } - pub fn handle_window_events(&mut self, events: Vec) { for event in events { match event { @@ -302,6 +297,9 @@ impl Browser { EmbedderMsg::BrowserCreated(new_browser_id) => { // TODO: properly handle a new "tab" self.browsers.push(new_browser_id); + if self.browser_id.is_none() { + self.browser_id = Some(new_browser_id); + } self.event_queue.push(WindowEvent::SelectBrowser(new_browser_id)); } EmbedderMsg::KeyEvent(ch, key, state, modified) => { @@ -332,6 +330,7 @@ impl Browser { // TODO: close the appropriate "tab". let _ = self.browsers.pop(); if let Some(prev_browser_id) = self.browsers.last() { + self.browser_id = Some(*prev_browser_id); self.event_queue.push(WindowEvent::SelectBrowser(*prev_browser_id)); } else { self.event_queue.push(WindowEvent::Quit); diff --git a/ports/servo/non_android_main.rs b/ports/servo/non_android_main.rs index c271cab0e65..7db35a35e78 100644 --- a/ports/servo/non_android_main.rs +++ b/ports/servo/non_android_main.rs @@ -27,11 +27,10 @@ mod resources; mod browser; use backtrace::Backtrace; -use servo::Servo; +use servo::{Servo, BrowserId}; use servo::compositing::windowing::WindowEvent; use servo::config::opts::{self, ArgumentParsingResult, parse_url_or_filename}; use servo::config::servo_version; -use servo::ipc_channel::ipc; use servo::servo_config::prefs::PREFS; use servo::servo_url::ServoUrl; use std::env; @@ -150,12 +149,8 @@ pub fn main() { let target_url = cmdline_url.or(pref_url).or(blank_url).unwrap(); let mut servo = Servo::new(window.clone()); - - let (sender, receiver) = ipc::channel().unwrap(); - servo.handle_events(vec![WindowEvent::NewBrowser(target_url, sender)]); - let browser_id = receiver.recv().unwrap(); - browser.set_browser_id(browser_id); - servo.handle_events(vec![WindowEvent::SelectBrowser(browser_id)]); + let browser_id = BrowserId::new(); + servo.handle_events(vec![WindowEvent::NewBrowser(target_url, browser_id)]); servo.setup_logging();