diff options
author | bors-servo <lbergstrom+bors@mozilla.com> | 2016-07-22 15:34:14 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2016-07-22 15:34:14 -0500 |
commit | 0e887ca8d3327b63db43cc329dd83bf4c02e2a1c (patch) | |
tree | 5df69e86a3f85d31a005f7beddc4b65590bf7714 | |
parent | cdf225c26e04ac8a2f3294ab32999ec482db8cd4 (diff) | |
parent | 8d7a0c2cda0c8eb8a77046cbfc7fbbf0a626f398 (diff) | |
download | servo-0e887ca8d3327b63db43cc329dd83bf4c02e2a1c.tar.gz servo-0e887ca8d3327b63db43cc329dd83bf4c02e2a1c.zip |
Auto merge of #12552 - ConnorGBrewster:history_interface, r=asajeffrey
History interface Go, Back, and Forward
<!-- Please describe your changes on the following line: -->
r? @asajeffrey
---
<!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `__` with appropriate data: -->
- [X] `./mach build -d` does not report any errors
- [X] `./mach test-tidy` does not report any errors
- [X] These changes fix #5670 (github issue number if applicable).
<!-- Either: -->
- [X] There are tests for these changes OR
- [ ] These changes do not require tests because _____
<!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. -->
implement go, forward, back
<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/12552)
<!-- Reviewable:end -->
18 files changed, 324 insertions, 66 deletions
diff --git a/components/script/dom/history.rs b/components/script/dom/history.rs new file mode 100644 index 00000000000..061d7616f4a --- /dev/null +++ b/components/script/dom/history.rs @@ -0,0 +1,70 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * 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::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::global::GlobalRef; +use dom::bindings::js::{JS, Root}; +use dom::bindings::reflector::{Reflector, reflect_dom_object}; +use dom::window::Window; +use msg::constellation_msg::TraversalDirection; +use script_traits::ScriptMsg as ConstellationMsg; + +// https://html.spec.whatwg.org/multipage/#the-history-interface +#[dom_struct] +pub struct History { + reflector_: Reflector, + window: JS<Window>, +} + +impl History { + pub fn new_inherited(window: &Window) -> History { + History { + reflector_: Reflector::new(), + window: JS::from_ref(&window), + } + } + + pub fn new(window: &Window) -> Root<History> { + reflect_dom_object(box History::new_inherited(window), + GlobalRef::Window(window), + HistoryBinding::Wrap) + } +} + +impl History { + fn traverse_history(&self, direction: TraversalDirection) { + let pipeline = self.window.pipeline(); + let msg = ConstellationMsg::TraverseHistory(Some(pipeline), direction); + let _ = self.window.constellation_chan().send(msg); + } +} + +impl HistoryMethods for History { + // https://html.spec.whatwg.org/multipage/#dom-history-go + fn Go(&self, delta: i32) { + let direction = if delta > 0 { + TraversalDirection::Forward(delta as usize) + } else if delta < 0 { + TraversalDirection::Back(-delta as usize) + } else { + self.window.Location().Reload(); + return; + }; + + self.traverse_history(direction); + } + + // https://html.spec.whatwg.org/multipage/#dom-history-back + fn Back(&self) { + self.traverse_history(TraversalDirection::Back(1)); + } + + // https://html.spec.whatwg.org/multipage/#dom-history-forward + fn Forward(&self) { + self.traverse_history(TraversalDirection::Forward(1)); + } +} diff --git a/components/script/dom/mod.rs b/components/script/dom/mod.rs index 172026c4d8e..effc7f2c761 100644 --- a/components/script/dom/mod.rs +++ b/components/script/dom/mod.rs @@ -270,6 +270,7 @@ pub mod forcetouchevent; pub mod formdata; pub mod hashchangeevent; pub mod headers; +pub mod history; pub mod htmlanchorelement; pub mod htmlappletelement; pub mod htmlareaelement; diff --git a/components/script/dom/webidls/History.webidl b/components/script/dom/webidls/History.webidl new file mode 100644 index 00000000000..04742d52601 --- /dev/null +++ b/components/script/dom/webidls/History.webidl @@ -0,0 +1,18 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * 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/. */ + +// enum ScrollRestoration { "auto", "manual" }; + +// https://html.spec.whatwg.org/multipage/#the-history-interface +[Exposed=(Window,Worker)] +interface History { + // readonly attribute unsigned long length; + // attribute ScrollRestoration scrollRestoration; + // 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); +}; diff --git a/components/script/dom/webidls/Window.webidl b/components/script/dom/webidls/Window.webidl index bda73c9479a..651c7081305 100644 --- a/components/script/dom/webidls/Window.webidl +++ b/components/script/dom/webidls/Window.webidl @@ -11,7 +11,7 @@ [Unforgeable] readonly attribute Document document; // attribute DOMString name; [/*PutForwards=href, */Unforgeable] readonly attribute Location location; - //readonly attribute History history; + readonly attribute History history; //[Replaceable] readonly attribute BarProp locationbar; //[Replaceable] readonly attribute BarProp menubar; //[Replaceable] readonly attribute BarProp personalbar; diff --git a/components/script/dom/window.rs b/components/script/dom/window.rs index b4984bb2a4a..2237514bd3d 100644 --- a/components/script/dom/window.rs +++ b/components/script/dom/window.rs @@ -30,6 +30,7 @@ use dom::document::Document; use dom::element::Element; use dom::event::Event; use dom::eventtarget::EventTarget; +use dom::history::History; use dom::htmliframeelement::build_mozbrowser_custom_event; use dom::location::Location; use dom::navigator::Navigator; @@ -158,6 +159,7 @@ pub struct Window { #[ignore_heap_size_of = "channels are hard"] image_cache_chan: ImageCacheChan, browsing_context: MutNullableHeap<JS<BrowsingContext>>, + history: MutNullableHeap<JS<History>>, performance: MutNullableHeap<JS<Performance>>, navigation_start: u64, navigation_start_precise: f64, @@ -475,6 +477,11 @@ impl WindowMethods for Window { self.browsing_context().active_document() } + // https://html.spec.whatwg.org/multipage/#dom-history + fn History(&self) -> Root<History> { + self.history.or_init(|| History::new(self)) + } + // https://html.spec.whatwg.org/multipage/#dom-location fn Location(&self) -> Root<Location> { self.Document().GetLocation().unwrap() @@ -1648,6 +1655,7 @@ impl Window { mem_profiler_chan: mem_profiler_chan, time_profiler_chan: time_profiler_chan, devtools_chan: devtools_chan, + history: Default::default(), browsing_context: Default::default(), performance: Default::default(), navigation_start: (current_time.sec * 1000 + current_time.nsec as i64 / 1000000) as u64, diff --git a/tests/wpt/metadata/FileAPI/blob/Blob-XHR-revoke.html.ini b/tests/wpt/metadata/FileAPI/blob/Blob-XHR-revoke.html.ini index b7e66c83a20..6fb7d0ba5ca 100644 --- a/tests/wpt/metadata/FileAPI/blob/Blob-XHR-revoke.html.ini +++ b/tests/wpt/metadata/FileAPI/blob/Blob-XHR-revoke.html.ini @@ -2,4 +2,3 @@ type: testharness expected: CRASH bug: https://github.com/servo/servo/issues/10539 - diff --git a/tests/wpt/metadata/html/browsers/browsing-the-web/history-traversal/PopStateEvent.html.ini b/tests/wpt/metadata/html/browsers/browsing-the-web/history-traversal/PopStateEvent.html.ini deleted file mode 100644 index bd6d242444a..00000000000 --- a/tests/wpt/metadata/html/browsers/browsing-the-web/history-traversal/PopStateEvent.html.ini +++ /dev/null @@ -1,5 +0,0 @@ -[PopStateEvent.html] - type: testharness - [Dispatching a synthetic PopStateEvent] - expected: FAIL - diff --git a/tests/wpt/metadata/html/browsers/browsing-the-web/history-traversal/browsing_context_name_cross_origin.html.ini b/tests/wpt/metadata/html/browsers/browsing-the-web/history-traversal/browsing_context_name_cross_origin.html.ini index ee105e85389..2dac566a5d3 100644 --- a/tests/wpt/metadata/html/browsers/browsing-the-web/history-traversal/browsing_context_name_cross_origin.html.ini +++ b/tests/wpt/metadata/html/browsers/browsing-the-web/history-traversal/browsing_context_name_cross_origin.html.ini @@ -1,5 +1,3 @@ [browsing_context_name_cross_origin.html] type: testharness - [Restoring window.name on cross-origin history traversal] - expected: FAIL - + disabled: see https://github.com/whatwg/html/issues/490 diff --git a/tests/wpt/metadata/html/browsers/browsing-the-web/history-traversal/persisted-user-state-restoration/scroll-restoration-basic.html.ini b/tests/wpt/metadata/html/browsers/browsing-the-web/history-traversal/persisted-user-state-restoration/scroll-restoration-basic.html.ini index 3e73c51da3a..5e99880706b 100644 --- a/tests/wpt/metadata/html/browsers/browsing-the-web/history-traversal/persisted-user-state-restoration/scroll-restoration-basic.html.ini +++ b/tests/wpt/metadata/html/browsers/browsing-the-web/history-traversal/persisted-user-state-restoration/scroll-restoration-basic.html.ini @@ -3,9 +3,6 @@ [Default value is "auto"] expected: FAIL - [It is writable] - expected: FAIL - [Invalid values are ignored] expected: FAIL 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 b3538369e2e..46c10baad28 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,3 +1,101 @@ [001.html] type: testharness - expected: TIMEOUT + [history.length should update when loading pages in an iframe] + expected: FAIL + + [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 + + [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 + + [pushState must not alter location.hash when no URL is provided] + expected: FAIL + + [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 + + [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 + 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 29a2058d988..1228df18521 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,3 +1,98 @@ [002.html] type: testharness - expected: TIMEOUT + [history.length should update when loading pages in an iframe] + expected: FAIL + + [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 + + [replaceState must be able to set absolute URLs to the same host] + expected: FAIL + + [replaceState must not remove any tasks queued by the history traversal task source] + expected: FAIL + + [.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 + + [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 + diff --git a/tests/wpt/metadata/html/browsers/history/the-history-interface/004.html.ini b/tests/wpt/metadata/html/browsers/history/the-history-interface/004.html.ini index 2c1c228a251..fa42d1a0762 100644 --- a/tests/wpt/metadata/html/browsers/history/the-history-interface/004.html.ini +++ b/tests/wpt/metadata/html/browsers/history/the-history-interface/004.html.ini @@ -1,3 +1,11 @@ [004.html] type: testharness - expected: TIMEOUT + [.go commands should be queued until the thread has ended] + expected: FAIL + + [browser needs to support hashchange events for this testcase] + expected: FAIL + + [queued .go commands should all be executed when the queue is processed] + 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 4982b00f15c..76099606688 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,6 +1,11 @@ [005.html] type: testharness - expected: TIMEOUT [history.pushState support is needed for this testcase] expected: FAIL + [<body onpopstate="..."> should register a listener for the popstate event] + expected: FAIL + + [window.onpopstate should register a listener for the popstate event] + 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 index e346ad78fcf..5c3b95e454e 100644 --- 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 @@ -1,6 +1,5 @@ [007.html] type: testharness - expected: TIMEOUT [history.state should initially be null] expected: FAIL @@ -10,3 +9,15 @@ [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-location-interface/location_assign_about_blank.html.ini b/tests/wpt/metadata/html/browsers/history/the-location-interface/location_assign_about_blank.html.ini deleted file mode 100644 index c144ee2f49f..00000000000 --- a/tests/wpt/metadata/html/browsers/history/the-location-interface/location_assign_about_blank.html.ini +++ /dev/null @@ -1,5 +0,0 @@ -[location_assign_about_blank.html] - type: testharness - [location.assign with initial about:blank browsing context] - expected: FAIL - diff --git a/tests/wpt/metadata/html/dom/interfaces.html.ini b/tests/wpt/metadata/html/dom/interfaces.html.ini index 63aaf524f22..89a8654cd7e 100644 --- a/tests/wpt/metadata/html/dom/interfaces.html.ini +++ b/tests/wpt/metadata/html/dom/interfaces.html.ini @@ -5613,45 +5613,18 @@ [BarProp interface: attribute visible] expected: FAIL - [History interface: existence and properties of interface object] - expected: FAIL - - [History interface object length] - expected: FAIL - - [History interface: existence and properties of interface prototype object] - expected: FAIL - - [History interface: existence and properties of interface prototype object's "constructor" property] - expected: FAIL - [History interface: attribute length] expected: FAIL [History interface: attribute state] expected: FAIL - [History interface: operation go(long)] - expected: FAIL - - [History interface: operation back()] - expected: FAIL - - [History interface: operation forward()] - expected: FAIL - [History interface: operation pushState(any,DOMString,DOMString)] expected: FAIL [History interface: operation replaceState(any,DOMString,DOMString)] expected: FAIL - [History must be primary interface of window.history] - expected: FAIL - - [Stringification of window.history] - expected: FAIL - [History interface: window.history must inherit property "length" with the proper type (0)] expected: FAIL @@ -5661,9 +5634,6 @@ [History interface: window.history must inherit property "go" with the proper type (2)] expected: FAIL - [History interface: calling go(long) on window.history with too few arguments must throw TypeError] - expected: FAIL - [History interface: window.history must inherit property "back" with the proper type (3)] expected: FAIL @@ -7236,9 +7206,6 @@ [BarProp interface object name] expected: FAIL - [History interface object name] - expected: FAIL - [ApplicationCache interface object name] expected: FAIL @@ -7290,15 +7257,6 @@ [History interface: window.history must inherit property "state" with the proper type (2)] expected: FAIL - [History interface: window.history must inherit property "go" with the proper type (3)] - expected: FAIL - - [History interface: window.history must inherit property "back" with the proper type (4)] - expected: FAIL - - [History interface: window.history must inherit property "forward" with the proper type (5)] - expected: FAIL - [History interface: window.history must inherit property "pushState" with the proper type (6)] expected: FAIL diff --git a/tests/wpt/mozilla/tests/mozilla/interfaces.html b/tests/wpt/mozilla/tests/mozilla/interfaces.html index 95dfa65ad82..f037f9a879e 100644 --- a/tests/wpt/mozilla/tests/mozilla/interfaces.html +++ b/tests/wpt/mozilla/tests/mozilla/interfaces.html @@ -49,6 +49,7 @@ test_interfaces([ "FormData", "HashChangeEvent", "Headers", + "History", "HTMLAnchorElement", "HTMLAppletElement", "HTMLAreaElement", diff --git a/tests/wpt/mozilla/tests/mozilla/interfaces.worker.js b/tests/wpt/mozilla/tests/mozilla/interfaces.worker.js index 79b99d4f1de..4a9ae800987 100644 --- a/tests/wpt/mozilla/tests/mozilla/interfaces.worker.js +++ b/tests/wpt/mozilla/tests/mozilla/interfaces.worker.js @@ -44,7 +44,8 @@ test_interfaces([ "FocusEvent", "FormData", "HashChangeEvent", - "Headers", + "Headers", + "History", "HTMLAnchorElement", "HTMLAppletElement", "HTMLAreaElement", |