Track hash changes in session history

Notify history changed on pushState and scroll to frag
This commit is contained in:
Connor Brewster 2018-06-12 22:12:17 +02:00
parent c1cc2aaf9c
commit 61442cce4b
22 changed files with 110 additions and 87 deletions

View file

@ -85,7 +85,10 @@ impl History {
// Step 6
let hash_changed = old_url.fragment() != url.fragment();
// TODO: Step 8 - scroll restoration
// Step 8
if let Some(fragment) = url.fragment() {
document.check_and_scroll_fragment(fragment);
}
// Step 11
let state_changed = state_id != self.state_id.get();

View file

@ -33,7 +33,10 @@ use dom::cssstyledeclaration::{CSSModificationAccess, CSSStyleDeclaration, CSSSt
use dom::customelementregistry::CustomElementRegistry;
use dom::document::{AnimationFrameCallback, Document};
use dom::element::Element;
use dom::event::Event;
use dom::eventtarget::EventTarget;
use dom::globalscope::GlobalScope;
use dom::hashchangeevent::HashChangeEvent;
use dom::history::History;
use dom::location::Location;
use dom::mediaquerylist::{MediaQueryList, WeakMediaQueryListVec};
@ -1582,13 +1585,33 @@ impl Window {
referrer_policy: Option<ReferrerPolicy>) {
let doc = self.Document();
let referrer_policy = referrer_policy.or(doc.get_referrer_policy());
// https://html.spec.whatwg.org/multipage/#navigating-across-documents
if !force_reload && url.as_url()[..Position::AfterQuery] ==
doc.url().as_url()[..Position::AfterQuery] {
// Step 6
if let Some(fragment) = url.fragment() {
self.send_to_constellation(ScriptMsg::NavigatedToFragment(url.clone(), replace));
doc.check_and_scroll_fragment(fragment);
let this = Trusted::new(self);
let old_url = doc.url().into_string();
let new_url = url.clone().into_string();
let task = task!(hashchange_event: move || {
let this = this.root();
let event = HashChangeEvent::new(
&this,
atom!("hashchange"),
false,
false,
old_url,
new_url);
event.upcast::<Event>().fire(this.upcast::<EventTarget>());
});
// FIXME(nox): Why are errors silenced here?
let _ = self.script_chan.send(CommonScriptMsg::Task(
ScriptThreadEventCategory::DomEvent,
Box::new(self.task_canceller(TaskSourceName::DOMManipulation).wrap_task(task)),
self.pipeline_id()
));
doc.set_url(url.clone());
return
}