From eedff27ea9277a411637decbb66685e3905a45c8 Mon Sep 17 00:00:00 2001 From: Connor Brewster Date: Tue, 17 Jan 2017 21:48:51 -0600 Subject: [PATCH 1/2] add methods to ensure frame state stays consistent --- components/constellation/constellation.rs | 6 ++---- components/constellation/frame.rs | 16 ++++++++++++++++ 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/components/constellation/constellation.rs b/components/constellation/constellation.rs index 15c0e258ea3c..e3aefdeaa46f 100644 --- a/components/constellation/constellation.rs +++ b/components/constellation/constellation.rs @@ -2033,9 +2033,7 @@ impl Constellation debug_assert_eq!(entry.instant, curr_entry.instant); - frame.pipeline_id = pipeline_id; - frame.instant = entry.instant; - frame.url = entry.url.clone(); + frame.update_current(pipeline_id, &entry); old_pipeline_id }, @@ -2130,7 +2128,7 @@ impl Constellation let (evicted_id, new_frame, clear_future, location_changed) = if let Some(mut entry) = frame_change.replace { debug!("Replacing pipeline in existing frame."); let evicted_id = entry.pipeline_id; - entry.pipeline_id = Some(frame_change.new_pipeline_id); + entry.replace_pipeline(frame_change.new_pipeline_id, frame_change.url.clone()); self.traverse_to_entry(entry); (evicted_id, false, false, false) } else if let Some(frame) = self.frames.get_mut(&frame_change.frame_id) { diff --git a/components/constellation/frame.rs b/components/constellation/frame.rs index 1613e18b6702..daa443b2b80f 100644 --- a/components/constellation/frame.rs +++ b/components/constellation/frame.rs @@ -76,6 +76,13 @@ impl Frame { pub fn remove_forward_entries(&mut self) -> Vec { replace(&mut self.next, vec!()) } + + /// Update the current entry of the Frame from an entry that has been traversed to. + pub fn update_current(&mut self, pipeline_id: PipelineId, entry: &FrameState) { + self.pipeline_id = pipeline_id; + self.instant = entry.instant; + self.url = entry.url.clone(); + } } /// An entry in a frame's session history. @@ -99,6 +106,15 @@ pub struct FrameState { pub frame_id: FrameId, } +impl FrameState { + /// Updates the entry's pipeline and url. This is used when navigating with replacement + /// enabled. + pub fn replace_pipeline(&mut self, pipeline_id: PipelineId, url: ServoUrl) { + self.pipeline_id = Some(pipeline_id); + self.url = url; + } +} + /// Represents a pending change in the frame tree, that will be applied /// once the new pipeline has loaded and completed initial layout / paint. pub struct FrameChange { From 92bf8623316293d789ab5912ee1649e7699938cb Mon Sep 17 00:00:00 2001 From: Connor Brewster Date: Sat, 6 Aug 2016 19:45:59 -0600 Subject: [PATCH 2/2] Implement history state, pushState, replaceState Add HistoryStateId Added state id to browsing context add history state removal Updated test expectations fix tidy issues and remove document parameter fix spec link Add popstate event address review comments enable 001 and 002 history interface tests Add 001 and 002 to the intermittent check rebased. fix tidy issues Update test expectations rebase Store and set Url, compare FrameState during traversal --- components/constellation/constellation.rs | 58 ++++++++- components/constellation/frame.rs | 35 +++++- components/msg/constellation_msg.rs | 3 + components/script/dom/bindings/trace.rs | 4 +- components/script/dom/browsingcontext.rs | 113 +++++++++++++++++- components/script/dom/history.rs | 90 ++++++++++++++ components/script/dom/popstateevent.rs | 11 ++ components/script/dom/webidls/History.webidl | 8 +- components/script/script_thread.rs | 22 +++- components/script_traits/lib.rs | 10 +- components/script_traits/script_msg.rs | 4 +- etc/ci/former_intermittents_wpt.txt | 2 + .../the-history-interface/001.html.ini | 70 +---------- .../the-history-interface/002.html.ini | 58 +-------- .../the-history-interface/005.html.ini | 1 + .../the-history-interface/006.html.ini | 14 --- .../the-history-interface/007.html.ini | 23 ---- .../the-history-interface/008.html.ini | 3 - .../the-history-interface/009.html.ini | 14 --- .../the-history-interface/010.html.ini | 14 --- .../the-history-interface/011.html.ini | 11 -- .../the-history-interface/012.html.ini | 3 - .../combination_history_001.html.ini | 5 - .../combination_history_002.html.ini | 5 - .../combination_history_003.html.ini | 5 - .../combination_history_004.html.ini | 5 - .../combination_history_005.html.ini | 5 - .../combination_history_006.html.ini | 5 - .../history_back.html.ini | 5 - .../history_forward.html.ini | 5 - .../history_go_minus.html.ini | 5 - .../history_go_plus.html.ini | 5 - .../history_pushstate.html.ini | 5 - .../history_pushstate_err.html.ini | 5 - ...history_pushstate_nooptionalparam.html.ini | 5 - .../history_replacestate.html.ini | 5 - .../history_replacestate_err.html.ini | 5 - ...tory_replacestate_nooptionalparam.html.ini | 5 - .../history_state.html.ini | 5 - 39 files changed, 344 insertions(+), 312 deletions(-) delete mode 100644 tests/wpt/metadata/html/browsers/history/the-history-interface/006.html.ini delete mode 100644 tests/wpt/metadata/html/browsers/history/the-history-interface/007.html.ini delete mode 100644 tests/wpt/metadata/html/browsers/history/the-history-interface/009.html.ini delete mode 100644 tests/wpt/metadata/html/browsers/history/the-history-interface/010.html.ini delete mode 100644 tests/wpt/metadata/html/browsers/history/the-history-interface/011.html.ini delete mode 100644 tests/wpt/metadata/html/browsers/history/the-history-interface/combination_history_001.html.ini delete mode 100644 tests/wpt/metadata/html/browsers/history/the-history-interface/combination_history_002.html.ini delete mode 100644 tests/wpt/metadata/html/browsers/history/the-history-interface/combination_history_003.html.ini delete mode 100644 tests/wpt/metadata/html/browsers/history/the-history-interface/combination_history_004.html.ini delete mode 100644 tests/wpt/metadata/html/browsers/history/the-history-interface/combination_history_005.html.ini delete mode 100644 tests/wpt/metadata/html/browsers/history/the-history-interface/combination_history_006.html.ini delete mode 100644 tests/wpt/metadata/html/browsers/history/the-history-interface/history_back.html.ini delete mode 100644 tests/wpt/metadata/html/browsers/history/the-history-interface/history_forward.html.ini delete mode 100644 tests/wpt/metadata/html/browsers/history/the-history-interface/history_go_minus.html.ini delete mode 100644 tests/wpt/metadata/html/browsers/history/the-history-interface/history_go_plus.html.ini delete mode 100644 tests/wpt/metadata/html/browsers/history/the-history-interface/history_pushstate.html.ini delete mode 100644 tests/wpt/metadata/html/browsers/history/the-history-interface/history_pushstate_err.html.ini delete mode 100644 tests/wpt/metadata/html/browsers/history/the-history-interface/history_pushstate_nooptionalparam.html.ini delete mode 100644 tests/wpt/metadata/html/browsers/history/the-history-interface/history_replacestate.html.ini delete mode 100644 tests/wpt/metadata/html/browsers/history/the-history-interface/history_replacestate_err.html.ini delete mode 100644 tests/wpt/metadata/html/browsers/history/the-history-interface/history_replacestate_nooptionalparam.html.ini delete mode 100644 tests/wpt/metadata/html/browsers/history/the-history-interface/history_state.html.ini diff --git a/components/constellation/constellation.rs b/components/constellation/constellation.rs index e3aefdeaa46f..13e3deb1ae5a 100644 --- a/components/constellation/constellation.rs +++ b/components/constellation/constellation.rs @@ -82,7 +82,7 @@ use ipc_channel::ipc::{self, IpcSender}; use ipc_channel::router::ROUTER; use layout_traits::LayoutThreadFactory; use log::{Log, LogLevel, LogLevelFilter, LogMetadata, LogRecord}; -use msg::constellation_msg::{FrameId, FrameType, PipelineId}; +use msg::constellation_msg::{FrameId, FrameType, HistoryStateId, PipelineId}; use msg::constellation_msg::{Key, KeyModifiers, KeyState}; use msg::constellation_msg::{PipelineNamespace, PipelineNamespaceId, TraversalDirection}; use net_traits::{self, IpcSend, ResourceThreads}; @@ -940,6 +940,11 @@ impl Constellation debug!("constellation got joint session history length message from script"); self.handle_joint_session_history_length(pipeline_id, sender); } + // Handle a history state pushed request. + FromScriptMsg::HistoryStatePushed(pipeline_id, state_id) => { + debug!("constellation got histort state pushed message from script"); + self.handle_history_state_pushed(pipeline_id, state_id); + } // Notification that the new document is ready to become active FromScriptMsg::ActivateDocument(pipeline_id) => { debug!("constellation got activate document message"); @@ -1713,6 +1718,21 @@ impl Constellation let _ = sender.send(length as u32); } + fn handle_history_state_pushed(&mut self, pipeline_id: PipelineId, state_id: HistoryStateId) { + if !self.pipeline_is_in_current_frame(pipeline_id) { + return warn!("Received push state from not fully active pipeline {:?}", pipeline_id); + } + let frame_id = match self.pipelines.get(&pipeline_id) { + Some(pipeline) => pipeline.frame_id, + None => return warn!("Pipeline closed after history state was pushed."), + }; + let frame = match self.frames.get_mut(&frame_id) { + Some(frame) => frame, + None => return warn!("Frame closed after history state was pushed."), + }; + frame.push_state(state_id); + } + fn handle_key_msg(&mut self, ch: Option, key: Key, state: KeyState, mods: KeyModifiers) { // Send to the explicitly focused pipeline (if it exists), or the root // frame's current pipeline. If neither exist, fall back to sending to @@ -2061,6 +2081,16 @@ impl Constellation // Set paint permissions correctly for the compositor layers. self.send_frame_tree(); + // Notify the corresponding browsing context to activate the specified history state. + match self.pipelines.get(&pipeline_id) { + Some(pipeline) => { + let msg = ConstellationControlMsg::ActivateHistoryState(pipeline_id, + entry.state_id); + let _ = pipeline.event_loop.send(msg); + }, + None => return warn!("Pipeline {:?} traversed after closure.", pipeline_id), + }; + // Update the owning iframe to point to the new pipeline id. // This makes things like contentDocument work correctly. if let Some((parent_pipeline_id, _)) = parent_info { @@ -2364,13 +2394,31 @@ impl Constellation .map(|frame| frame.id) .collect(); for frame_id in frame_ids { - let evicted = match self.frames.get_mut(&frame_id) { - Some(frame) => frame.remove_forward_entries(), + let (current_pipeline_id, forward_entries) = match self.frames.get_mut(&frame_id) { + Some(frame) => (frame.pipeline_id, frame.remove_forward_entries()), None => continue, }; - for entry in evicted { + let mut discarded_history_states = vec!(); + for entry in forward_entries { if let Some(pipeline_id) = entry.pipeline_id { - self.close_pipeline(pipeline_id, DiscardBrowsingContext::No, ExitPipelineMode::Normal); + if pipeline_id == current_pipeline_id { + discarded_history_states.push(entry.state_id); + } else { + self.close_pipeline(pipeline_id, DiscardBrowsingContext::No, ExitPipelineMode::Normal); + } + } + } + + // Notify the BrowsingContext in the script thread to remove the HistoryState entries + // that are now no longer accesible. + if !discarded_history_states.is_empty() { + match self.pipelines.get(¤t_pipeline_id) { + Some(pipeline) => { + let msg = ConstellationControlMsg::RemoveHistoryStateEntries(current_pipeline_id, + discarded_history_states); + let _ = pipeline.event_loop.send(msg); + }, + None => return warn!("Pipeline {:?} closed after removing state entries", current_pipeline_id), } } } diff --git a/components/constellation/frame.rs b/components/constellation/frame.rs index daa443b2b80f..c6961822f869 100644 --- a/components/constellation/frame.rs +++ b/components/constellation/frame.rs @@ -2,7 +2,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -use msg::constellation_msg::{FrameId, PipelineId}; +use msg::constellation_msg::{FrameId, HistoryStateId, PipelineId}; use pipeline::Pipeline; use servo_url::ServoUrl; use std::collections::HashMap; @@ -29,6 +29,9 @@ pub struct Frame { /// The pipeline for the current session history entry pub pipeline_id: PipelineId, + /// The id that maps to the history state entry in the script thread + pub state_id: HistoryStateId, + /// The URL for the current session history entry pub url: ServoUrl, @@ -45,8 +48,9 @@ impl Frame { pub fn new(id: FrameId, pipeline_id: PipelineId, url: ServoUrl) -> Frame { Frame { id: id, - pipeline_id: pipeline_id, instant: Instant::now(), + pipeline_id: pipeline_id, + state_id: HistoryStateId(0), url: url, prev: vec!(), next: vec!(), @@ -57,9 +61,10 @@ impl Frame { pub fn current(&self) -> FrameState { FrameState { instant: self.instant, - frame_id: self.id, pipeline_id: Some(self.pipeline_id), url: self.url.clone(), + frame_id: self.id, + state_id: self.state_id, } } @@ -70,8 +75,17 @@ impl Frame { self.instant = Instant::now(); self.pipeline_id = pipeline_id; self.url = url; + self.state_id = HistoryStateId(0); } + /// Add an entry representing a new history state. + pub fn push_state(&mut self, state_id: HistoryStateId) { + let current = self.current(); + self.prev.push(current); + // Only update the time stampt and history state + self.instant = Instant::now(); + self.state_id = state_id; + } /// Set the future to be empty. pub fn remove_forward_entries(&mut self) -> Vec { replace(&mut self.next, vec!()) @@ -82,6 +96,7 @@ impl Frame { self.pipeline_id = pipeline_id; self.instant = entry.instant; self.url = entry.url.clone(); + self.state_id = entry.state_id; } } @@ -104,6 +119,9 @@ pub struct FrameState { /// The frame that this session history entry is part of pub frame_id: FrameId, + + /// The id that maps to the history state entry in the script thread + pub state_id: HistoryStateId, } impl FrameState { @@ -112,6 +130,7 @@ impl FrameState { pub fn replace_pipeline(&mut self, pipeline_id: PipelineId, url: ServoUrl) { self.pipeline_id = Some(pipeline_id); self.url = url; + self.state_id = HistoryStateId(0); } } @@ -213,11 +232,19 @@ impl<'a> Iterator for FullFrameTreeIterator<'a> { continue; }, }; - let child_frame_ids = frame.prev.iter().chain(frame.next.iter()) + let mut session_pipelines = frame.prev.iter().chain(frame.next.iter()) .filter_map(|entry| entry.pipeline_id) .chain(once(frame.pipeline_id)) + .collect::>(); + + // The session history may contain multiple entries with the same PipelineId. + // These duplicates need to be removed. + session_pipelines.dedup(); + + let child_frame_ids = session_pipelines.iter() .filter_map(|pipeline_id| pipelines.get(&pipeline_id)) .flat_map(|pipeline| pipeline.children.iter()); + self.stack.extend(child_frame_ids); return Some(frame) } diff --git a/components/msg/constellation_msg.rs b/components/msg/constellation_msg.rs index dddfb0c00422..51a7bf4458dd 100644 --- a/components/msg/constellation_msg.rs +++ b/components/msg/constellation_msg.rs @@ -217,6 +217,9 @@ impl PipelineNamespace { thread_local!(pub static PIPELINE_NAMESPACE: Cell> = Cell::new(None)); +#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Copy, Hash, Debug, Deserialize, Serialize, HeapSizeOf)] +pub struct HistoryStateId(pub u32); + #[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Copy, Hash, Debug, Deserialize, Serialize, HeapSizeOf)] pub struct PipelineNamespaceId(pub u32); diff --git a/components/script/dom/bindings/trace.rs b/components/script/dom/bindings/trace.rs index 6f211f82bef3..157344760322 100644 --- a/components/script/dom/bindings/trace.rs +++ b/components/script/dom/bindings/trace.rs @@ -58,7 +58,7 @@ use js::glue::{CallObjectTracer, CallUnbarrieredObjectTracer, CallValueTracer}; use js::jsapi::{GCTraceKindToAscii, Heap, JSObject, JSTracer, TraceKind}; use js::jsval::JSVal; use js::rust::Runtime; -use msg::constellation_msg::{FrameId, FrameType, PipelineId}; +use msg::constellation_msg::{FrameId, FrameType, HistoryStateId, PipelineId}; use net_traits::{Metadata, NetworkError, ReferrerPolicy, ResourceThreads}; use net_traits::filemanager_thread::RelativePos; use net_traits::image::base::{Image, ImageMetadata}; @@ -331,7 +331,7 @@ unsafe_no_jsmanaged_fields!(TrustedPromise); unsafe_no_jsmanaged_fields!(PropertyDeclarationBlock); // These three are interdependent, if you plan to put jsmanaged data // in one of these make sure it is propagated properly to containing structs -unsafe_no_jsmanaged_fields!(FrameId, FrameType, WindowSizeData, WindowSizeType, PipelineId); +unsafe_no_jsmanaged_fields!(FrameId, FrameType, HistoryStateId, WindowSizeData, WindowSizeType, PipelineId); unsafe_no_jsmanaged_fields!(TimerEventId, TimerSource); unsafe_no_jsmanaged_fields!(TimelineMarkerType); unsafe_no_jsmanaged_fields!(WorkerId); diff --git a/components/script/dom/browsingcontext.rs b/components/script/dom/browsingcontext.rs index 1c2ca66b33e1..1156ca4a67f7 100644 --- a/components/script/dom/browsingcontext.rs +++ b/components/script/dom/browsingcontext.rs @@ -2,28 +2,39 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +use dom::bindings::cell::DOMRefCell; +use dom::bindings::codegen::Bindings::WindowBinding::WindowMethods; use dom::bindings::conversions::{ToJSValConvertible, root_from_handleobject}; +use dom::bindings::inheritance::Castable; use dom::bindings::js::{JS, Root, RootedReference}; use dom::bindings::proxyhandler::{fill_property_descriptor, get_property_descriptor}; use dom::bindings::reflector::{DomObject, MutDomObject, Reflector}; +use dom::bindings::str::DOMString; use dom::bindings::trace::JSTraceable; use dom::bindings::utils::WindowProxyHandler; use dom::bindings::utils::get_array_index_from_id; use dom::element::Element; +use dom::eventtarget::EventTarget; +use dom::globalscope::GlobalScope; +use dom::popstateevent::PopStateEvent; use dom::window::Window; use js::JSCLASS_IS_GLOBAL; use js::glue::{CreateWrapperProxyHandler, ProxyTraps, NewWindowProxy}; use js::glue::{GetProxyPrivate, SetProxyExtra, GetProxyExtra}; -use js::jsapi::{Handle, HandleId, HandleObject, HandleValue}; +use js::jsapi::{Handle, HandleId, HandleObject, HandleValue, Heap}; use js::jsapi::{JSAutoCompartment, JSContext, JSErrNum, JSFreeOp, JSObject}; use js::jsapi::{JSPROP_READONLY, JSTracer, JS_DefinePropertyById}; use js::jsapi::{JS_ForwardGetPropertyTo, JS_ForwardSetPropertyTo}; use js::jsapi::{JS_GetOwnPropertyDescriptorById, JS_HasPropertyById}; use js::jsapi::{MutableHandle, MutableHandleObject, MutableHandleValue}; use js::jsapi::{ObjectOpResult, PropertyDescriptor}; -use js::jsval::{UndefinedValue, PrivateValue}; +use js::jsval::{JSVal, PrivateValue, UndefinedValue}; use js::rust::get_object_class; +use msg::constellation_msg::HistoryStateId; +use script_traits::ScriptMsg as ConstellationMsg; +use servo_url::ServoUrl; use std::cell::Cell; +use std::collections::HashMap; #[dom_struct] // NOTE: the browsing context for a window is managed in two places: @@ -33,24 +44,38 @@ use std::cell::Cell; pub struct BrowsingContext { reflector: Reflector, + window: JS, + /// Has this browsing context been discarded? discarded: Cell, + active_state: Cell, + + next_state_id: Cell, + + states: DOMRefCell>, + /// The containing iframe element, if this is a same-origin iframe frame_element: Option>, } impl BrowsingContext { - pub fn new_inherited(frame_element: Option<&Element>) -> BrowsingContext { + pub fn new_inherited(window: &Window, frame_element: Option<&Element>, url: ServoUrl) -> BrowsingContext { + let mut states = HashMap::new(); + states.insert(HistoryStateId(0), HistoryState::new(None, None, url)); BrowsingContext { reflector: Reflector::new(), + window: JS::from_ref(window), discarded: Cell::new(false), + active_state: Cell::new(HistoryStateId(0)), + next_state_id: Cell::new(HistoryStateId(1)), + states: DOMRefCell::new(states), frame_element: frame_element.map(JS::from_ref), } } #[allow(unsafe_code)] - pub fn new(window: &Window, frame_element: Option<&Element>) -> Root { + pub fn new(window: &Window, frame_element: Option<&Element>, url: ServoUrl) -> Root { unsafe { let WindowProxyHandler(handler) = window.windowproxy_handler(); assert!(!handler.is_null()); @@ -63,7 +88,7 @@ impl BrowsingContext { rooted!(in(cx) let window_proxy = NewWindowProxy(cx, parent, handler)); assert!(!window_proxy.is_null()); - let object = box BrowsingContext::new_inherited(frame_element); + let object = box BrowsingContext::new_inherited(window, frame_element, url); let raw = Box::into_raw(object); SetProxyExtra(window_proxy.get(), 0, &PrivateValue(raw as *const _)); @@ -78,10 +103,67 @@ impl BrowsingContext { self.discarded.set(true); } + fn next_state_id(&self) -> HistoryStateId { + let next_id = self.next_state_id.get(); + self.next_state_id.set(HistoryStateId(next_id.0 + 1)); + next_id + } + + // TODO(ConnorGBrewster): Store and do something with `title`, and `url` + pub fn replace_session_history_entry(&self, + title: DOMString, + url: ServoUrl, + state: HandleValue) { + let mut states = self.states.borrow_mut(); + states.insert(self.active_state.get(), HistoryState::new(Some(state), Some(title), url)); + // NOTE: We do not need to notify the constellation, as the history state id + // will stay the same and no new entry is added. + } + + pub fn push_session_history_entry(&self, + title: DOMString, + url: ServoUrl, + state: HandleValue) { + let window = &*self.window; + let next_id = self.next_state_id(); + window.Document().set_url(url.clone()); + self.states.borrow_mut().insert(next_id, HistoryState::new(Some(state), Some(title), url)); + self.active_state.set(next_id); + + // Notify the constellation about this new entry so it can be added to the + // joint session history. + let global_scope = window.upcast::(); + let msg = ConstellationMsg::HistoryStatePushed(global_scope.pipeline_id(), next_id); + let _ = global_scope.constellation_chan().send(msg); + } + + pub fn remove_history_state_entries(&self, state_ids: Vec) { + let mut states = self.states.borrow_mut(); + for state_id in state_ids { + states.remove(&state_id); + } + } + + pub fn activate_history_state(&self, state_id: HistoryStateId) { + let window = &*self.window; + let (handle, url) = { + let states = self.states.borrow(); + let state = states.get(&state_id).expect("Activated nonexistent history state."); + (state.state.handle(), state.url.clone()) + }; + window.Document().set_url(url); + PopStateEvent::dispatch_jsval(window.upcast::(), window.upcast::(), handle); + self.active_state.set(state_id); + } + pub fn is_discarded(&self) -> bool { self.discarded.get() } + pub fn state(&self) -> JSVal { + self.states.borrow().get(&self.active_state.get()).expect("No active state.").state.get() + } + pub fn frame_element(&self) -> Option<&Element> { self.frame_element.r() } @@ -93,6 +175,27 @@ impl BrowsingContext { } } +#[derive(JSTraceable, HeapSizeOf)] +struct HistoryState { + title: Option, + url: ServoUrl, + state: Heap, +} + +impl HistoryState { + fn new(state: Option, title: Option, url: ServoUrl) -> HistoryState { + let mut jsval: Heap = Default::default(); + let state = state.unwrap_or(HandleValue::null()); + jsval.set(state.get()); + HistoryState { + title: title, + url: url, + state: jsval, + } + } +} + + #[allow(unsafe_code)] unsafe fn GetSubframeWindow(cx: *mut JSContext, proxy: HandleObject, diff --git a/components/script/dom/history.rs b/components/script/dom/history.rs index 1a971eae0092..a375d941c0c9 100644 --- a/components/script/dom/history.rs +++ b/components/script/dom/history.rs @@ -6,12 +6,17 @@ use dom::bindings::codegen::Bindings::HistoryBinding; use dom::bindings::codegen::Bindings::HistoryBinding::HistoryMethods; use dom::bindings::codegen::Bindings::LocationBinding::LocationMethods; use dom::bindings::codegen::Bindings::WindowBinding::WindowMethods; +use dom::bindings::error::{Error, ErrorResult}; use dom::bindings::inheritance::Castable; use dom::bindings::js::{JS, Root}; use dom::bindings::reflector::{Reflector, reflect_dom_object}; +use dom::bindings::str::{DOMString, USVString}; +use dom::bindings::structuredclone::StructuredCloneData; use dom::globalscope::GlobalScope; use dom::window::Window; use ipc_channel::ipc; +use js::jsapi::{HandleValue, JSContext}; +use js::jsval::{JSVal, NullValue}; use msg::constellation_msg::TraversalDirection; use script_traits::ScriptMsg as ConstellationMsg; @@ -35,6 +40,65 @@ impl History { window, HistoryBinding::Wrap) } + + // https://html.spec.whatwg.org/multipage/#dom-history-pushstate + fn add_state(&self, + cx: *mut JSContext, + data: HandleValue, + title: DOMString, + url: Option, + replace: bool) -> ErrorResult { + // Step 1 + let document = self.window.Document(); + // Step 2 + if !document.is_fully_active() { + return Err(Error::Security); + } + // Step 5 + let cloned_data = try!(StructuredCloneData::write(cx, data)); + rooted!(in(cx) let mut state = NullValue()); + cloned_data.read(self.window.upcast::(), state.handle_mut()); + let url = match url { + Some(url) => { + // Step 6 + let document_url = document.url(); + // 6.1 + let url = match document_url.join(&url.0) { + Ok(url) => url, + // 6.2 + Err(_) => return Err(Error::Security), + }; + + // 6.4 + if url.scheme() != document_url.scheme() || + url.username() != document_url.username() || + url.password() != document_url.password() || + url.host() != document_url.host() || + url.port() != document_url.port() { + return Err(Error::Security); + } + + // 6.5 + if url.origin() != document_url.origin() && + (url.path() != document_url.path() || url.query() != document_url.query()) { + return Err(Error::Security); + } + + url + }, + // Step 7 + None => document.url().clone(), + }; + + // Step 8 + if replace { + self.window.browsing_context().replace_session_history_entry(title, url, state.handle()); + } else { + self.window.browsing_context().push_session_history_entry(title, url, state.handle()); + } + + Ok(()) + } } impl History { @@ -57,6 +121,12 @@ impl HistoryMethods for History { recv.recv().unwrap() } + #[allow(unsafe_code)] + // https://html.spec.whatwg.org/multipage/#dom-history-state + unsafe fn State(&self, _cx: *mut JSContext) -> JSVal { + self.window.browsing_context().state() + } + // https://html.spec.whatwg.org/multipage/#dom-history-go fn Go(&self, delta: i32) { let direction = if delta > 0 { @@ -80,4 +150,24 @@ impl HistoryMethods for History { fn Forward(&self) { self.traverse_history(TraversalDirection::Forward(1)); } + + #[allow(unsafe_code)] + // https://html.spec.whatwg.org/multipage/#dom-history-pushstate + unsafe fn PushState(&self, + cx: *mut JSContext, + data: HandleValue, + title: DOMString, + url: Option) -> ErrorResult { + self.add_state(cx, data, title, url, false) + } + + #[allow(unsafe_code)] + // https://html.spec.whatwg.org/multipage/#dom-history-replacestate + unsafe fn ReplaceState(&self, + cx: *mut JSContext, + data: HandleValue, + title: DOMString, + url: Option) -> ErrorResult { + self.add_state(cx, data, title, url, true) + } } diff --git a/components/script/dom/popstateevent.rs b/components/script/dom/popstateevent.rs index 44183f7483f4..3df8b3d9424f 100644 --- a/components/script/dom/popstateevent.rs +++ b/components/script/dom/popstateevent.rs @@ -11,6 +11,7 @@ use dom::bindings::js::{MutHeapJSVal, Root}; use dom::bindings::reflector::reflect_dom_object; use dom::bindings::str::DOMString; use dom::event::Event; +use dom::eventtarget::EventTarget; use dom::globalscope::GlobalScope; use js::jsapi::{HandleValue, JSContext}; use js::jsval::JSVal; @@ -66,6 +67,16 @@ impl PopStateEvent { } } +impl PopStateEvent { + pub fn dispatch_jsval(target: &EventTarget, + scope: &GlobalScope, + state: HandleValue) { + let pop_state_event = PopStateEvent::new( + scope, Atom::from("popstate"), true, false, state); + pop_state_event.upcast::().fire(target); + } +} + impl PopStateEventMethods for PopStateEvent { #[allow(unsafe_code)] // https://html.spec.whatwg.org/multipage/#dom-popstateevent-state diff --git a/components/script/dom/webidls/History.webidl b/components/script/dom/webidls/History.webidl index c0c1635264a3..918403b35ad4 100644 --- a/components/script/dom/webidls/History.webidl +++ b/components/script/dom/webidls/History.webidl @@ -9,10 +9,12 @@ interface History { readonly attribute unsigned long length; // attribute ScrollRestoration scrollRestoration; - // readonly attribute any state; + readonly attribute any state; void go(optional long delta = 0); void back(); void forward(); - // void pushState(any data, DOMString title, optional USVString? url = null); - // void replaceState(any data, DOMString title, optional USVString? url = null); + [Throws] + void pushState(any data, DOMString title, optional USVString? url = null); + [Throws] + void replaceState(any data, DOMString title, optional USVString? url = null); }; diff --git a/components/script/script_thread.rs b/components/script/script_thread.rs index 655825710255..b52e3c1828ed 100644 --- a/components/script/script_thread.rs +++ b/components/script/script_thread.rs @@ -70,7 +70,7 @@ use js::jsval::UndefinedValue; use js::rust::Runtime; use layout_wrapper::ServoLayoutNode; use mem::heap_size_of_self_and_children; -use msg::constellation_msg::{FrameId, FrameType, PipelineId, PipelineNamespace}; +use msg::constellation_msg::{FrameId, FrameType, HistoryStateId, PipelineId, PipelineNamespace}; use net_traits::{CoreResourceMsg, FetchMetadata, FetchResponseListener}; use net_traits::{IpcSend, Metadata, ReferrerPolicy, ResourceThreads}; use net_traits::image_cache_thread::{ImageCacheChan, ImageCacheResult, ImageCacheThread}; @@ -1019,6 +1019,10 @@ impl ScriptThread { self.handle_exit_pipeline_msg(pipeline_id, discard_browsing_context), ConstellationControlMsg::WebVREvent(pipeline_id, event) => self.handle_webvr_event(pipeline_id, event), + ConstellationControlMsg::ActivateHistoryState(pipeline_id, state_id) => + self.handle_activate_history_state(pipeline_id, state_id), + ConstellationControlMsg::RemoveHistoryStateEntries(pipeline_id, state_ids) => + self.handle_remove_history_state_entries(pipeline_id, state_ids), msg @ ConstellationControlMsg::AttachLayout(..) | msg @ ConstellationControlMsg::Viewport(..) | msg @ ConstellationControlMsg::SetScrollState(..) | @@ -1760,7 +1764,7 @@ impl ScriptThread { self.webvr_thread.clone()); let frame_element = frame_element.r().map(Castable::upcast); - let browsing_context = BrowsingContext::new(&window, frame_element); + let browsing_context = BrowsingContext::new(&window, frame_element, incomplete.url.clone()); window.init_browsing_context(&browsing_context); let last_modified = metadata.headers.as_ref().and_then(|headers| { @@ -2223,6 +2227,20 @@ impl ScriptThread { } } + fn handle_activate_history_state(&self, pipeline_id: PipelineId, state_id: HistoryStateId) { + if let Some(window) = self.documents.borrow().find_window(pipeline_id) { + let browsing_context = window.browsing_context(); + browsing_context.activate_history_state(state_id); + } + } + + fn handle_remove_history_state_entries(&self, pipeline_id: PipelineId, state_ids: Vec) { + if let Some(window) = self.documents.borrow().find_window(pipeline_id) { + let browsing_context = window.browsing_context(); + browsing_context.remove_history_state_entries(state_ids); + } + } + pub fn enqueue_promise_job(job: EnqueuedPromiseCallback, global: &GlobalScope) { 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 c01311583269..bc134fe9ccd9 100644 --- a/components/script_traits/lib.rs +++ b/components/script_traits/lib.rs @@ -55,7 +55,7 @@ use hyper::header::Headers; use hyper::method::Method; use ipc_channel::ipc::{IpcReceiver, IpcSender}; use libc::c_void; -use msg::constellation_msg::{FrameId, FrameType, Key, KeyModifiers, KeyState}; +use msg::constellation_msg::{FrameId, FrameType, HistoryStateId, Key, KeyModifiers, KeyState}; use msg::constellation_msg::{PipelineId, PipelineNamespaceId, TraversalDirection}; use net_traits::{ReferrerPolicy, ResourceThreads}; use net_traits::image::base::Image; @@ -265,7 +265,11 @@ pub enum ConstellationControlMsg { /// Reload the given page. Reload(PipelineId), /// Notifies the script thread of a WebVR device event - WebVREvent(PipelineId, WebVREventMsg) + WebVREvent(PipelineId, WebVREventMsg), + /// Notifies a browsing context to activate the specified history state. + ActivateHistoryState(PipelineId, HistoryStateId), + /// Notifies a browsing context to remove the specified history state entries. + RemoveHistoryStateEntries(PipelineId, Vec), } impl fmt::Debug for ConstellationControlMsg { @@ -299,6 +303,8 @@ impl fmt::Debug for ConstellationControlMsg { ReportCSSError(..) => "ReportCSSError", Reload(..) => "Reload", WebVREvent(..) => "WebVREvent", + ActivateHistoryState(..) => "ActivateHistoryStateZ", + RemoveHistoryStateEntries(..) => "RemoveHistoryStateEntries", }; write!(formatter, "ConstellationMsg::{}", variant) } diff --git a/components/script_traits/script_msg.rs b/components/script_traits/script_msg.rs index fc29563cbbd1..4d55eaab276a 100644 --- a/components/script_traits/script_msg.rs +++ b/components/script_traits/script_msg.rs @@ -19,7 +19,7 @@ use euclid::size::Size2D; use gfx_traits::ScrollRootId; use ipc_channel::ipc::IpcSender; use msg::constellation_msg::{FrameId, PipelineId, TraversalDirection}; -use msg::constellation_msg::{Key, KeyModifiers, KeyState}; +use msg::constellation_msg::{HistoryStateId, Key, KeyModifiers, KeyState}; use net_traits::CoreResourceMsg; use net_traits::storage_thread::StorageType; use offscreen_gl_context::{GLContextAttributes, GLLimits}; @@ -97,6 +97,8 @@ pub enum ScriptMsg { TraverseHistory(Option, TraversalDirection), /// Gets the length of the joint session history from the constellation. JointSessionHistoryLength(PipelineId, IpcSender), + /// Notifies the constellation that a history state entry has been pushed + HistoryStatePushed(PipelineId, HistoryStateId), /// Favicon detected NewFavicon(ServoUrl), /// Status message to be displayed in the chrome, eg. a link URL on mouseover. diff --git a/etc/ci/former_intermittents_wpt.txt b/etc/ci/former_intermittents_wpt.txt index 6001c12b3a23..e877f0433da3 100644 --- a/etc/ci/former_intermittents_wpt.txt +++ b/etc/ci/former_intermittents_wpt.txt @@ -1,2 +1,4 @@ /_mozilla/mozilla/css/canvas_over_area.html /_mozilla/mozilla/css/iframe/hide_layers2.html +/html/browsers/history/the-history-interface/001.html +/html/browsers/history/the-history-interface/002.html diff --git a/tests/wpt/metadata/html/browsers/history/the-history-interface/001.html.ini b/tests/wpt/metadata/html/browsers/history/the-history-interface/001.html.ini index 86c15b26af03..a30c5885307a 100644 --- a/tests/wpt/metadata/html/browsers/history/the-history-interface/001.html.ini +++ b/tests/wpt/metadata/html/browsers/history/the-history-interface/001.html.ini @@ -1,48 +1,8 @@ [001.html] type: testharness - disabled: https://github.com/servo/servo/issues/12580 [history.length should update when setting location.hash] expected: FAIL - [history.pushState must exist] - expected: FAIL - - [history.pushState must exist within iframes] - expected: FAIL - - [initial history.state should be null] - expected: FAIL - - [history.length should update when pushing a state] - expected: FAIL - - [history.state should update after a state is pushed] - expected: FAIL - - [traversing history must traverse pushed states] - expected: FAIL - - [pushState must not be allowed to create invalid URLs] - expected: FAIL - - [pushState must not be allowed to create cross-origin URLs] - expected: FAIL - - [pushState must not be allowed to create cross-origin URLs (about:blank)] - expected: FAIL - - [pushState must not be allowed to create cross-origin URLs (data:URI)] - expected: FAIL - - [pushState should not actually load the new URL] - expected: FAIL - - [security errors are expected to be thrown in the context of the document that owns the history object] - expected: FAIL - - [location.hash must be allowed to change (part 1)] - expected: FAIL - [location.hash must be allowed to change (part 2)] expected: FAIL @@ -52,30 +12,6 @@ [pushState must remove all history after the current state] expected: FAIL - [pushState must be able to set location.hash] - expected: FAIL - - [pushState must remove any tasks queued by the history traversal task source] - expected: FAIL - - [pushState must be able to set location.pathname] - expected: FAIL - - [pushState must be able to set absolute URLs to the same host] - expected: FAIL - - [pushState must not be able to use a function as data] - expected: FAIL - - [pushState must not be able to use a DOM node as data] - expected: FAIL - - [pushState must not be able to use an error object as data] - expected: FAIL - - [security errors are expected to be thrown in the context of the document that owns the history object (2)] - expected: FAIL - [pushState must be able to make structured clones of complex objects] expected: FAIL @@ -83,7 +19,8 @@ expected: FAIL [popstate event should fire when navigation occurs] - expected: FAIL + expected: + if debug and (os == "mac") and (version == "OS X 10.12") and (processor == "x86_64") and (bits == 64) and (backend == "webrender"): PASS [popstate event should pass the state data] expected: FAIL @@ -92,7 +29,8 @@ expected: FAIL [state data should be a clone of the original object, not a reference to it] - expected: FAIL + expected: + if debug and (os == "mac") and (version == "OS X 10.12") and (processor == "x86_64") and (bits == 64) and (backend == "webrender"): PASS [history.state should also reference a clone of the original object (2)] expected: FAIL diff --git a/tests/wpt/metadata/html/browsers/history/the-history-interface/002.html.ini b/tests/wpt/metadata/html/browsers/history/the-history-interface/002.html.ini index c8350da8e2eb..462488d6339c 100644 --- a/tests/wpt/metadata/html/browsers/history/the-history-interface/002.html.ini +++ b/tests/wpt/metadata/html/browsers/history/the-history-interface/002.html.ini @@ -1,51 +1,17 @@ [002.html] type: testharness - disabled: https://github.com/servo/servo/issues/12580 [history.length should update when setting location.hash] expected: FAIL - [history.replaceState must exist] - expected: FAIL - - [history.replaceState must exist within iframes] - expected: FAIL - - [initial history.state should be null] - expected: FAIL - - [history.length should not update when replacing a state with no URL] - expected: FAIL - - [history.state should update after a state is pushed] - expected: FAIL - [hash should not change when replaceState is called without a URL] expected: FAIL - [history.length should not update when replacing a state with a URL] - expected: FAIL - [hash should change when replaceState is called with a URL] expected: FAIL [replaceState must replace the existing state without altering the forward history] expected: FAIL - [replaceState must not be allowed to create invalid URLs] - expected: FAIL - - [replaceState must not be allowed to create cross-origin URLs] - expected: FAIL - - [replaceState must not be allowed to create cross-origin URLs (about:blank)] - expected: FAIL - - [replaceState must not be allowed to create cross-origin URLs (data:URI)] - expected: FAIL - - [security errors are expected to be thrown in the context of the document that owns the history object] - expected: FAIL - [replaceState must be able to set location.pathname] expected: FAIL @@ -58,42 +24,24 @@ [.go must queue a task with the history traversal task source (run asynchronously)] expected: FAIL - [replaceState must not be able to use a function as data] - expected: FAIL - - [replaceState must not be able to use a DOM node as data] - expected: FAIL - - [replaceState must not be able to use an error object as data] - expected: FAIL - - [replaceState should not actually load the new URL] - expected: FAIL - - [security errors are expected to be thrown in the context of the document that owns the history object (2)] - expected: FAIL - [replaceState must be able to make structured clones of complex objects] expected: FAIL [history.state should also reference a clone of the original object] expected: FAIL - [popstate event should fire when navigation occurs] - expected: FAIL - [popstate event should pass the state data] expected: FAIL [state data should cope with circular object references] expected: FAIL - [state data should be a clone of the original object, not a reference to it] - expected: FAIL - [history.state should also reference a clone of the original object (2)] expected: FAIL [history.state should be a separate clone of the object, not a reference to the object passed to the event handler] expected: FAIL + [replaceState should not actually load the new URL] + expected: FAIL + diff --git a/tests/wpt/metadata/html/browsers/history/the-history-interface/005.html.ini b/tests/wpt/metadata/html/browsers/history/the-history-interface/005.html.ini index 760996066882..9de54ad21540 100644 --- a/tests/wpt/metadata/html/browsers/history/the-history-interface/005.html.ini +++ b/tests/wpt/metadata/html/browsers/history/the-history-interface/005.html.ini @@ -1,5 +1,6 @@ [005.html] type: testharness + expected: TIMEOUT [history.pushState support is needed for this testcase] expected: FAIL diff --git a/tests/wpt/metadata/html/browsers/history/the-history-interface/006.html.ini b/tests/wpt/metadata/html/browsers/history/the-history-interface/006.html.ini deleted file mode 100644 index 505c9b8cf838..000000000000 --- a/tests/wpt/metadata/html/browsers/history/the-history-interface/006.html.ini +++ /dev/null @@ -1,14 +0,0 @@ -[006.html] - type: testharness - [history.state should initially be null] - expected: FAIL - - [history.state should still be null onload] - expected: FAIL - - [history.state should still be null after onload] - expected: FAIL - - [writing to history.state should be silently ignored and not throw an error] - expected: FAIL - diff --git a/tests/wpt/metadata/html/browsers/history/the-history-interface/007.html.ini b/tests/wpt/metadata/html/browsers/history/the-history-interface/007.html.ini deleted file mode 100644 index 5c3b95e454e7..000000000000 --- a/tests/wpt/metadata/html/browsers/history/the-history-interface/007.html.ini +++ /dev/null @@ -1,23 +0,0 @@ -[007.html] - type: testharness - [history.state should initially be null] - expected: FAIL - - [history.pushState support is needed for this testcase] - expected: FAIL - - [history.state should reflect pushed state] - expected: FAIL - - [popstate event should fire before onload fires] - expected: FAIL - - [the correct state should be restored when navigating during initial load] - expected: FAIL - - [history.state should reflect the navigated state onload] - expected: FAIL - - [history.state should reflect the navigated state after onload] - expected: FAIL - diff --git a/tests/wpt/metadata/html/browsers/history/the-history-interface/008.html.ini b/tests/wpt/metadata/html/browsers/history/the-history-interface/008.html.ini index 5af01f618f1d..b0269b37f5e4 100644 --- a/tests/wpt/metadata/html/browsers/history/the-history-interface/008.html.ini +++ b/tests/wpt/metadata/html/browsers/history/the-history-interface/008.html.ini @@ -1,8 +1,5 @@ [008.html] type: testharness - [history.pushState URL resolving should be done relative to the document, not the script] - expected: FAIL - [history.replaceState URL resolving should be done relative to the document, not the script] expected: FAIL diff --git a/tests/wpt/metadata/html/browsers/history/the-history-interface/009.html.ini b/tests/wpt/metadata/html/browsers/history/the-history-interface/009.html.ini deleted file mode 100644 index 775bd6adf7d8..000000000000 --- a/tests/wpt/metadata/html/browsers/history/the-history-interface/009.html.ini +++ /dev/null @@ -1,14 +0,0 @@ -[009.html] - type: testharness - [HTTP Referer should use the pushed state] - expected: FAIL - - [document.referrer should use the pushed state] - expected: FAIL - - [HTTP Referer should use the replaced state] - expected: FAIL - - [document.referrer should use the replaced state] - expected: FAIL - diff --git a/tests/wpt/metadata/html/browsers/history/the-history-interface/010.html.ini b/tests/wpt/metadata/html/browsers/history/the-history-interface/010.html.ini deleted file mode 100644 index cd895f71c05b..000000000000 --- a/tests/wpt/metadata/html/browsers/history/the-history-interface/010.html.ini +++ /dev/null @@ -1,14 +0,0 @@ -[010.html] - type: testharness - [HTTP Referer should use the pushed state (before onload)] - expected: FAIL - - [document.referrer should use the pushed state (before onload)] - expected: FAIL - - [HTTP Referer should use the replaced state (before onload)] - expected: FAIL - - [document.referrer should use the replaced state (before onload)] - expected: FAIL - diff --git a/tests/wpt/metadata/html/browsers/history/the-history-interface/011.html.ini b/tests/wpt/metadata/html/browsers/history/the-history-interface/011.html.ini deleted file mode 100644 index 0867b0401e09..000000000000 --- a/tests/wpt/metadata/html/browsers/history/the-history-interface/011.html.ini +++ /dev/null @@ -1,11 +0,0 @@ -[011.html] - type: testharness - [pushState should be able to set the location state] - expected: FAIL - - [pushed location should be reflected immediately] - expected: FAIL - - [pushed location should be retained after the page has loaded] - expected: FAIL - diff --git a/tests/wpt/metadata/html/browsers/history/the-history-interface/012.html.ini b/tests/wpt/metadata/html/browsers/history/the-history-interface/012.html.ini index b153bc5f21ce..6d4c74df6ee9 100644 --- a/tests/wpt/metadata/html/browsers/history/the-history-interface/012.html.ini +++ b/tests/wpt/metadata/html/browsers/history/the-history-interface/012.html.ini @@ -1,8 +1,5 @@ [012.html] type: testharness - [replaceState should be able to set the location state] - expected: FAIL - [replaced location should be reflected immediately] expected: FAIL diff --git a/tests/wpt/metadata/html/browsers/history/the-history-interface/combination_history_001.html.ini b/tests/wpt/metadata/html/browsers/history/the-history-interface/combination_history_001.html.ini deleted file mode 100644 index 6c1948b3884f..000000000000 --- a/tests/wpt/metadata/html/browsers/history/the-history-interface/combination_history_001.html.ini +++ /dev/null @@ -1,5 +0,0 @@ -[combination_history_001.html] - type: testharness - [Combine pushState and replaceSate methods] - expected: FAIL - diff --git a/tests/wpt/metadata/html/browsers/history/the-history-interface/combination_history_002.html.ini b/tests/wpt/metadata/html/browsers/history/the-history-interface/combination_history_002.html.ini deleted file mode 100644 index b298a5d7c07c..000000000000 --- a/tests/wpt/metadata/html/browsers/history/the-history-interface/combination_history_002.html.ini +++ /dev/null @@ -1,5 +0,0 @@ -[combination_history_002.html] - type: testharness - [After calling of pushState method, check length] - expected: FAIL - diff --git a/tests/wpt/metadata/html/browsers/history/the-history-interface/combination_history_003.html.ini b/tests/wpt/metadata/html/browsers/history/the-history-interface/combination_history_003.html.ini deleted file mode 100644 index 0329eef96dec..000000000000 --- a/tests/wpt/metadata/html/browsers/history/the-history-interface/combination_history_003.html.ini +++ /dev/null @@ -1,5 +0,0 @@ -[combination_history_003.html] - type: testharness - [After calling of pushState and replaceState methods, check length] - expected: FAIL - diff --git a/tests/wpt/metadata/html/browsers/history/the-history-interface/combination_history_004.html.ini b/tests/wpt/metadata/html/browsers/history/the-history-interface/combination_history_004.html.ini deleted file mode 100644 index 703bccbb3347..000000000000 --- a/tests/wpt/metadata/html/browsers/history/the-history-interface/combination_history_004.html.ini +++ /dev/null @@ -1,5 +0,0 @@ -[combination_history_004.html] - type: testharness - [After calling of back method, check length] - expected: FAIL - diff --git a/tests/wpt/metadata/html/browsers/history/the-history-interface/combination_history_005.html.ini b/tests/wpt/metadata/html/browsers/history/the-history-interface/combination_history_005.html.ini deleted file mode 100644 index 969bd2d84f1b..000000000000 --- a/tests/wpt/metadata/html/browsers/history/the-history-interface/combination_history_005.html.ini +++ /dev/null @@ -1,5 +0,0 @@ -[combination_history_005.html] - type: testharness - [After calling of forward method, check length] - expected: FAIL - diff --git a/tests/wpt/metadata/html/browsers/history/the-history-interface/combination_history_006.html.ini b/tests/wpt/metadata/html/browsers/history/the-history-interface/combination_history_006.html.ini deleted file mode 100644 index 416b9e58d13c..000000000000 --- a/tests/wpt/metadata/html/browsers/history/the-history-interface/combination_history_006.html.ini +++ /dev/null @@ -1,5 +0,0 @@ -[combination_history_006.html] - type: testharness - [After calling of go method, check length] - expected: FAIL - diff --git a/tests/wpt/metadata/html/browsers/history/the-history-interface/history_back.html.ini b/tests/wpt/metadata/html/browsers/history/the-history-interface/history_back.html.ini deleted file mode 100644 index 5e01759025de..000000000000 --- a/tests/wpt/metadata/html/browsers/history/the-history-interface/history_back.html.ini +++ /dev/null @@ -1,5 +0,0 @@ -[history_back.html] - type: testharness - [history back] - expected: FAIL - diff --git a/tests/wpt/metadata/html/browsers/history/the-history-interface/history_forward.html.ini b/tests/wpt/metadata/html/browsers/history/the-history-interface/history_forward.html.ini deleted file mode 100644 index d3c12080dfa9..000000000000 --- a/tests/wpt/metadata/html/browsers/history/the-history-interface/history_forward.html.ini +++ /dev/null @@ -1,5 +0,0 @@ -[history_forward.html] - type: testharness - [history forward] - expected: FAIL - diff --git a/tests/wpt/metadata/html/browsers/history/the-history-interface/history_go_minus.html.ini b/tests/wpt/metadata/html/browsers/history/the-history-interface/history_go_minus.html.ini deleted file mode 100644 index 01f21b309605..000000000000 --- a/tests/wpt/metadata/html/browsers/history/the-history-interface/history_go_minus.html.ini +++ /dev/null @@ -1,5 +0,0 @@ -[history_go_minus.html] - type: testharness - [history go minus] - expected: FAIL - diff --git a/tests/wpt/metadata/html/browsers/history/the-history-interface/history_go_plus.html.ini b/tests/wpt/metadata/html/browsers/history/the-history-interface/history_go_plus.html.ini deleted file mode 100644 index e2999746053f..000000000000 --- a/tests/wpt/metadata/html/browsers/history/the-history-interface/history_go_plus.html.ini +++ /dev/null @@ -1,5 +0,0 @@ -[history_go_plus.html] - type: testharness - [history go plus] - expected: FAIL - diff --git a/tests/wpt/metadata/html/browsers/history/the-history-interface/history_pushstate.html.ini b/tests/wpt/metadata/html/browsers/history/the-history-interface/history_pushstate.html.ini deleted file mode 100644 index d9c5e0b38af1..000000000000 --- a/tests/wpt/metadata/html/browsers/history/the-history-interface/history_pushstate.html.ini +++ /dev/null @@ -1,5 +0,0 @@ -[history_pushstate.html] - type: testharness - [history pushState] - expected: FAIL - diff --git a/tests/wpt/metadata/html/browsers/history/the-history-interface/history_pushstate_err.html.ini b/tests/wpt/metadata/html/browsers/history/the-history-interface/history_pushstate_err.html.ini deleted file mode 100644 index 5a4e399ac99d..000000000000 --- a/tests/wpt/metadata/html/browsers/history/the-history-interface/history_pushstate_err.html.ini +++ /dev/null @@ -1,5 +0,0 @@ -[history_pushstate_err.html] - type: testharness - [history pushState SECURITY_ERR] - expected: FAIL - diff --git a/tests/wpt/metadata/html/browsers/history/the-history-interface/history_pushstate_nooptionalparam.html.ini b/tests/wpt/metadata/html/browsers/history/the-history-interface/history_pushstate_nooptionalparam.html.ini deleted file mode 100644 index 40a1deb0cc3e..000000000000 --- a/tests/wpt/metadata/html/browsers/history/the-history-interface/history_pushstate_nooptionalparam.html.ini +++ /dev/null @@ -1,5 +0,0 @@ -[history_pushstate_nooptionalparam.html] - type: testharness - [history pushState NoOptionalParam] - expected: FAIL - diff --git a/tests/wpt/metadata/html/browsers/history/the-history-interface/history_replacestate.html.ini b/tests/wpt/metadata/html/browsers/history/the-history-interface/history_replacestate.html.ini deleted file mode 100644 index e2068698c0d6..000000000000 --- a/tests/wpt/metadata/html/browsers/history/the-history-interface/history_replacestate.html.ini +++ /dev/null @@ -1,5 +0,0 @@ -[history_replacestate.html] - type: testharness - [history replaceState] - expected: FAIL - diff --git a/tests/wpt/metadata/html/browsers/history/the-history-interface/history_replacestate_err.html.ini b/tests/wpt/metadata/html/browsers/history/the-history-interface/history_replacestate_err.html.ini deleted file mode 100644 index 316097c5b4d1..000000000000 --- a/tests/wpt/metadata/html/browsers/history/the-history-interface/history_replacestate_err.html.ini +++ /dev/null @@ -1,5 +0,0 @@ -[history_replacestate_err.html] - type: testharness - [history replaceState SECURITY_ERR] - expected: FAIL - diff --git a/tests/wpt/metadata/html/browsers/history/the-history-interface/history_replacestate_nooptionalparam.html.ini b/tests/wpt/metadata/html/browsers/history/the-history-interface/history_replacestate_nooptionalparam.html.ini deleted file mode 100644 index d523d0b78d0c..000000000000 --- a/tests/wpt/metadata/html/browsers/history/the-history-interface/history_replacestate_nooptionalparam.html.ini +++ /dev/null @@ -1,5 +0,0 @@ -[history_replacestate_nooptionalparam.html] - type: testharness - [history replaceStateNoOptionalParam] - expected: FAIL - diff --git a/tests/wpt/metadata/html/browsers/history/the-history-interface/history_state.html.ini b/tests/wpt/metadata/html/browsers/history/the-history-interface/history_state.html.ini deleted file mode 100644 index 2819759ee82b..000000000000 --- a/tests/wpt/metadata/html/browsers/history/the-history-interface/history_state.html.ini +++ /dev/null @@ -1,5 +0,0 @@ -[history_state.html] - type: testharness - [history state] - expected: FAIL -