mirror of
https://github.com/servo/servo.git
synced 2025-08-06 14:10:11 +01:00
Auto merge of #20671 - cbrewster:history_url, r=asajeffrey
Make session history aware of URLs <!-- Please describe your changes on the following line: --> --- <!-- 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 build-geckolib` does not report any errors - [X] `./mach test-tidy` does not report any errors - [ ] These changes fix #__ (github issue number if applicable). <!-- Either: --> - [x] There are tests for these changes OR - [ ] These changes do not require tests because _____ <!-- Also, please make sure that "Allow edits from maintainers" checkbox is checked, so that we can help you if you get stuck somewhere along the way.--> <!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. --> <!-- 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/20671) <!-- Reviewable:end -->
This commit is contained in:
commit
847115ba04
11 changed files with 192 additions and 56 deletions
|
@ -12,8 +12,10 @@ use dom::bindings::reflector::{DomObject, Reflector, reflect_dom_object};
|
|||
use dom::bindings::root::{Dom, DomRoot};
|
||||
use dom::bindings::str::{DOMString, USVString};
|
||||
use dom::bindings::structuredclone::StructuredCloneData;
|
||||
use dom::event::Event;
|
||||
use dom::eventtarget::EventTarget;
|
||||
use dom::globalscope::GlobalScope;
|
||||
use dom::hashchangeevent::HashChangeEvent;
|
||||
use dom::popstateevent::PopStateEvent;
|
||||
use dom::window::Window;
|
||||
use dom_struct::dom_struct;
|
||||
|
@ -71,8 +73,22 @@ impl History {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/#history-traversal
|
||||
// Steps 5-16
|
||||
#[allow(unsafe_code)]
|
||||
pub fn activate_state(&self, state_id: Option<HistoryStateId>) {
|
||||
pub fn activate_state(&self, state_id: Option<HistoryStateId>, url: ServoUrl) {
|
||||
// Steps 5
|
||||
let document = self.window.Document();
|
||||
let old_url = document.url().clone();
|
||||
document.set_url(url.clone());
|
||||
|
||||
// Step 6
|
||||
let hash_changed = old_url.fragment() != url.fragment();
|
||||
|
||||
// TODO: Step 8 - scroll restoration
|
||||
|
||||
// Step 11
|
||||
let state_changed = state_id != self.state_id.get();
|
||||
self.state_id.set(state_id);
|
||||
let serialized_data = match state_id {
|
||||
Some(state_id) => {
|
||||
|
@ -98,8 +114,26 @@ impl History {
|
|||
}
|
||||
}
|
||||
|
||||
unsafe {
|
||||
PopStateEvent::dispatch_jsval(self.window.upcast::<EventTarget>(), &*self.window, self.state.handle());
|
||||
// TODO: Queue events on DOM Manipulation task source if non-blocking flag is set.
|
||||
// Step 16.1
|
||||
if state_changed {
|
||||
PopStateEvent::dispatch_jsval(
|
||||
self.window.upcast::<EventTarget>(),
|
||||
&*self.window,
|
||||
unsafe { self.state.handle() }
|
||||
);
|
||||
}
|
||||
|
||||
// Step 16.3
|
||||
if hash_changed {
|
||||
let event = HashChangeEvent::new(
|
||||
&self.window,
|
||||
atom!("hashchange"),
|
||||
true,
|
||||
false,
|
||||
old_url.into_string(),
|
||||
url.into_string());
|
||||
event.upcast::<Event>().fire(self.window.upcast::<EventTarget>());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -175,7 +209,7 @@ impl History {
|
|||
PushOrReplace::Push => {
|
||||
let state_id = HistoryStateId::new();
|
||||
self.state_id.set(Some(state_id));
|
||||
let msg = ScriptMsg::PushHistoryState(state_id);
|
||||
let msg = ScriptMsg::PushHistoryState(state_id, new_url.clone());
|
||||
let _ = self.window.upcast::<GlobalScope>().script_to_constellation_chan().send(msg);
|
||||
state_id
|
||||
},
|
||||
|
@ -188,7 +222,7 @@ impl History {
|
|||
state_id
|
||||
},
|
||||
};
|
||||
let msg = ScriptMsg::ReplaceHistoryState(state_id);
|
||||
let msg = ScriptMsg::ReplaceHistoryState(state_id, new_url.clone());
|
||||
let _ = self.window.upcast::<GlobalScope>().script_to_constellation_chan().send(msg);
|
||||
state_id
|
||||
},
|
||||
|
|
|
@ -1169,7 +1169,7 @@ impl ScriptThread {
|
|||
Navigate(id, ..) => Some(id),
|
||||
PostMessage(id, ..) => Some(id),
|
||||
UpdatePipelineId(_, _, id, _) => Some(id),
|
||||
UpdateHistoryStateId(id, ..) => Some(id),
|
||||
UpdateHistoryState(id, ..) => Some(id),
|
||||
RemoveHistoryStates(id, ..) => Some(id),
|
||||
FocusIFrame(id, ..) => Some(id),
|
||||
WebDriverScriptCommand(id, ..) => Some(id),
|
||||
|
@ -1297,8 +1297,8 @@ impl ScriptThread {
|
|||
browsing_context_id,
|
||||
new_pipeline_id,
|
||||
reason),
|
||||
ConstellationControlMsg::UpdateHistoryStateId(pipeline_id, history_state_id) =>
|
||||
self.handle_update_history_state_id_msg(pipeline_id, history_state_id),
|
||||
ConstellationControlMsg::UpdateHistoryState(pipeline_id, history_state_id, url) =>
|
||||
self.handle_update_history_state_msg(pipeline_id, history_state_id, url),
|
||||
ConstellationControlMsg::RemoveHistoryStates(pipeline_id, history_states) =>
|
||||
self.handle_remove_history_states(pipeline_id, history_states),
|
||||
ConstellationControlMsg::FocusIFrame(parent_pipeline_id, frame_id) =>
|
||||
|
@ -1679,10 +1679,14 @@ impl ScriptThread {
|
|||
}
|
||||
}
|
||||
|
||||
fn handle_update_history_state_id_msg(&self, pipeline_id: PipelineId, history_state_id: Option<HistoryStateId>) {
|
||||
fn handle_update_history_state_msg(
|
||||
&self, pipeline_id: PipelineId,
|
||||
history_state_id: Option<HistoryStateId>,
|
||||
url: ServoUrl,
|
||||
) {
|
||||
match { self.documents.borrow().find_window(pipeline_id) } {
|
||||
None => return warn!("update history state after pipeline {} closed.", pipeline_id),
|
||||
Some(window) => window.History().r().activate_state(history_state_id),
|
||||
Some(window) => window.History().r().activate_state(history_state_id, url),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue