mirror of
https://github.com/servo/servo.git
synced 2025-08-07 14:35:33 +01:00
clean-up navigation
security: check target and source origin before executing JS url implement replacement-enabled flag as a HistoryEntryReplacement enum add source origin string on loaddata add LoadOrigin iframe: remove optional load-data auxiliaries: add load-data into info constellation: remove url from Pipeline::new check load origin: link to whatwg issue switch loadorigin toplevel to constellation
This commit is contained in:
parent
973a3448a4
commit
571beec179
14 changed files with 402 additions and 220 deletions
|
@ -145,11 +145,11 @@ use script_traits::{
|
|||
use script_traits::{
|
||||
ConstellationControlMsg, ConstellationMsg as FromCompositorMsg, DiscardBrowsingContext,
|
||||
};
|
||||
use script_traits::{DocumentActivity, DocumentState, LayoutControlMsg, LoadData};
|
||||
use script_traits::{DocumentActivity, DocumentState, LayoutControlMsg, LoadData, LoadOrigin};
|
||||
use script_traits::{HistoryEntryReplacement, IFrameSizeMsg, WindowSizeData, WindowSizeType};
|
||||
use script_traits::{
|
||||
IFrameLoadInfo, IFrameLoadInfoWithData, IFrameSandboxState, TimerSchedulerMsg,
|
||||
};
|
||||
use script_traits::{IFrameSizeMsg, WindowSizeData, WindowSizeType};
|
||||
use script_traits::{LayoutMsg as FromLayoutMsg, ScriptMsg as FromScriptMsg, ScriptThreadFactory};
|
||||
use script_traits::{SWManagerMsg, ScopeThings, UpdatePipelineIdReason, WebDriverCommandMsg};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
@ -171,7 +171,7 @@ use style_traits::viewport::ViewportConstraints;
|
|||
use style_traits::CSSPixel;
|
||||
use webvr_traits::{WebVREvent, WebVRMsg};
|
||||
|
||||
type PendingApprovalNavigations = HashMap<PipelineId, (LoadData, bool)>;
|
||||
type PendingApprovalNavigations = HashMap<PipelineId, (LoadData, HistoryEntryReplacement)>;
|
||||
|
||||
/// Servo supports tabs (referred to as browsers), so `Constellation` needs to
|
||||
/// store browser specific data for bookkeeping.
|
||||
|
@ -1320,7 +1320,7 @@ where
|
|||
// If there is already a pending page (self.pending_changes), it will not be overridden;
|
||||
// However, if the id is not encompassed by another change, it will be.
|
||||
FromCompositorMsg::LoadUrl(top_level_browsing_context_id, url) => {
|
||||
let load_data = LoadData::new(url, None, None, None);
|
||||
let load_data = LoadData::new(LoadOrigin::Constellation, url, None, None, None);
|
||||
let ctx_id = BrowsingContextId::from(top_level_browsing_context_id);
|
||||
let pipeline_id = match self.browsing_contexts.get(&ctx_id) {
|
||||
Some(ctx) => ctx.pipeline_id,
|
||||
|
@ -1333,7 +1333,12 @@ where
|
|||
};
|
||||
// Since this is a top-level load, initiated by the embedder, go straight to load_url,
|
||||
// bypassing schedule_navigation.
|
||||
self.load_url(top_level_browsing_context_id, pipeline_id, load_data, false);
|
||||
self.load_url(
|
||||
top_level_browsing_context_id,
|
||||
pipeline_id,
|
||||
load_data,
|
||||
HistoryEntryReplacement::Disabled,
|
||||
);
|
||||
},
|
||||
FromCompositorMsg::IsReadyToSaveImage(pipeline_states) => {
|
||||
let is_ready = self.handle_is_ready_to_save_image(pipeline_states);
|
||||
|
@ -1916,7 +1921,7 @@ where
|
|||
warn!("creating replacement pipeline for about:failure");
|
||||
|
||||
let new_pipeline_id = PipelineId::new();
|
||||
let load_data = LoadData::new(failure_url, None, None, None);
|
||||
let load_data = LoadData::new(LoadOrigin::Constellation, failure_url, None, None, None);
|
||||
let sandbox = IFrameSandboxState::IFrameSandboxed;
|
||||
let is_private = false;
|
||||
self.new_pipeline(
|
||||
|
@ -2035,7 +2040,7 @@ where
|
|||
);
|
||||
self.embedder_proxy.send(msg);
|
||||
let browsing_context_id = BrowsingContextId::from(top_level_browsing_context_id);
|
||||
let load_data = LoadData::new(url, None, None, None);
|
||||
let load_data = LoadData::new(LoadOrigin::Constellation, url, None, None, None);
|
||||
let sandbox = IFrameSandboxState::IFrameUnsandboxed;
|
||||
let is_private = false;
|
||||
let is_visible = true;
|
||||
|
@ -2196,7 +2201,9 @@ where
|
|||
// see https://html.spec.whatwg.org/multipage/#the-iframe-element:completely-loaded
|
||||
debug!("checking old pipeline? {:?}", load_info.old_pipeline_id);
|
||||
if let Some(old_pipeline) = old_pipeline {
|
||||
replace |= !old_pipeline.completely_loaded;
|
||||
if !old_pipeline.completely_loaded {
|
||||
replace = HistoryEntryReplacement::Enabled;
|
||||
}
|
||||
debug!(
|
||||
"old pipeline is {}completely loaded",
|
||||
if old_pipeline.completely_loaded {
|
||||
|
@ -2207,16 +2214,6 @@ where
|
|||
);
|
||||
}
|
||||
|
||||
let load_data = load_info.load_data.unwrap_or_else(|| {
|
||||
let url = match old_pipeline {
|
||||
Some(old_pipeline) => old_pipeline.url.clone(),
|
||||
None => ServoUrl::parse("about:blank").expect("infallible"),
|
||||
};
|
||||
|
||||
// TODO - loaddata here should have referrer info (not None, None)
|
||||
LoadData::new(url, Some(parent_pipeline_id), None, None)
|
||||
});
|
||||
|
||||
let is_parent_private = {
|
||||
let parent_browsing_context_id = match self.pipelines.get(&parent_pipeline_id) {
|
||||
Some(pipeline) => pipeline.browsing_context_id,
|
||||
|
@ -2250,10 +2247,11 @@ where
|
|||
},
|
||||
};
|
||||
|
||||
let replace = if replace {
|
||||
Some(NeedsToReload::No(browsing_context.pipeline_id))
|
||||
} else {
|
||||
None
|
||||
let replace = match replace {
|
||||
HistoryEntryReplacement::Enabled => {
|
||||
Some(NeedsToReload::No(browsing_context.pipeline_id))
|
||||
},
|
||||
HistoryEntryReplacement::Disabled => None,
|
||||
};
|
||||
|
||||
// https://github.com/rust-lang/rust/issues/59159
|
||||
|
@ -2268,7 +2266,7 @@ where
|
|||
Some(parent_pipeline_id),
|
||||
None,
|
||||
browsing_context_size,
|
||||
load_data,
|
||||
load_info.load_data,
|
||||
load_info.sandbox,
|
||||
is_private,
|
||||
browsing_context_is_visible,
|
||||
|
@ -2285,7 +2283,7 @@ where
|
|||
|
||||
fn handle_script_new_iframe(
|
||||
&mut self,
|
||||
load_info: IFrameLoadInfo,
|
||||
load_info: IFrameLoadInfoWithData,
|
||||
layout_sender: IpcSender<LayoutControlMsg>,
|
||||
) {
|
||||
let IFrameLoadInfo {
|
||||
|
@ -2295,12 +2293,7 @@ where
|
|||
top_level_browsing_context_id,
|
||||
is_private,
|
||||
..
|
||||
} = load_info;
|
||||
|
||||
let url = ServoUrl::parse("about:blank").expect("infallible");
|
||||
|
||||
// TODO: Referrer?
|
||||
let load_data = LoadData::new(url.clone(), Some(parent_pipeline_id), None, None);
|
||||
} = load_info.info;
|
||||
|
||||
let (script_sender, parent_browsing_context_id) =
|
||||
match self.pipelines.get(&parent_pipeline_id) {
|
||||
|
@ -2326,9 +2319,8 @@ where
|
|||
script_sender,
|
||||
layout_sender,
|
||||
self.compositor_proxy.clone(),
|
||||
url,
|
||||
is_parent_visible,
|
||||
load_data,
|
||||
load_info.load_data,
|
||||
);
|
||||
|
||||
assert!(!self.pipelines.contains_key(&new_pipeline_id));
|
||||
|
@ -2353,17 +2345,13 @@ where
|
|||
layout_sender: IpcSender<LayoutControlMsg>,
|
||||
) {
|
||||
let AuxiliaryBrowsingContextLoadInfo {
|
||||
load_data,
|
||||
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 (script_sender, opener_browsing_context_id) =
|
||||
match self.pipelines.get(&opener_pipeline_id) {
|
||||
Some(pipeline) => (pipeline.event_loop.clone(), pipeline.browsing_context_id),
|
||||
|
@ -2392,7 +2380,6 @@ where
|
|||
script_sender,
|
||||
layout_sender,
|
||||
self.compositor_proxy.clone(),
|
||||
url,
|
||||
is_opener_visible,
|
||||
load_data,
|
||||
);
|
||||
|
@ -2496,7 +2483,7 @@ where
|
|||
top_level_browsing_context_id: TopLevelBrowsingContextId,
|
||||
source_id: PipelineId,
|
||||
load_data: LoadData,
|
||||
replace: bool,
|
||||
replace: HistoryEntryReplacement,
|
||||
) {
|
||||
match self.pending_approval_navigations.entry(source_id) {
|
||||
Entry::Occupied(_) => {
|
||||
|
@ -2522,13 +2509,15 @@ where
|
|||
top_level_browsing_context_id: TopLevelBrowsingContextId,
|
||||
source_id: PipelineId,
|
||||
load_data: LoadData,
|
||||
replace: bool,
|
||||
replace: HistoryEntryReplacement,
|
||||
) -> Option<PipelineId> {
|
||||
let replace_debug = match replace {
|
||||
HistoryEntryReplacement::Enabled => "",
|
||||
HistoryEntryReplacement::Disabled => "not",
|
||||
};
|
||||
debug!(
|
||||
"Loading {} in pipeline {}, {}replacing.",
|
||||
load_data.url,
|
||||
source_id,
|
||||
if replace { "" } else { "not " }
|
||||
load_data.url, source_id, replace_debug
|
||||
);
|
||||
// If this load targets an iframe, its framing element may exist
|
||||
// in a separate script thread than the framed document that initiated
|
||||
|
@ -2569,7 +2558,7 @@ where
|
|||
Some(parent_pipeline_id) => {
|
||||
// Find the script thread for the pipeline containing the iframe
|
||||
// and issue an iframe load through there.
|
||||
let msg = ConstellationControlMsg::Navigate(
|
||||
let msg = ConstellationControlMsg::NavigateIframe(
|
||||
parent_pipeline_id,
|
||||
browsing_context_id,
|
||||
load_data,
|
||||
|
@ -2612,10 +2601,9 @@ where
|
|||
|
||||
// Create the new pipeline
|
||||
|
||||
let replace = if replace {
|
||||
Some(NeedsToReload::No(pipeline_id))
|
||||
} else {
|
||||
None
|
||||
let replace = match replace {
|
||||
HistoryEntryReplacement::Enabled => Some(NeedsToReload::No(pipeline_id)),
|
||||
HistoryEntryReplacement::Disabled => None,
|
||||
};
|
||||
|
||||
let new_pipeline_id = PipelineId::new();
|
||||
|
@ -2730,7 +2718,7 @@ where
|
|||
&mut self,
|
||||
pipeline_id: PipelineId,
|
||||
new_url: ServoUrl,
|
||||
replacement_enabled: bool,
|
||||
replacement_enabled: HistoryEntryReplacement,
|
||||
) {
|
||||
let (top_level_browsing_context_id, old_url) = match self.pipelines.get_mut(&pipeline_id) {
|
||||
Some(pipeline) => {
|
||||
|
@ -2745,15 +2733,18 @@ where
|
|||
},
|
||||
};
|
||||
|
||||
if !replacement_enabled {
|
||||
let diff = SessionHistoryDiff::HashDiff {
|
||||
pipeline_reloader: NeedsToReload::No(pipeline_id),
|
||||
new_url,
|
||||
old_url,
|
||||
};
|
||||
self.get_joint_session_history(top_level_browsing_context_id)
|
||||
.push_diff(diff);
|
||||
self.notify_history_changed(top_level_browsing_context_id);
|
||||
match replacement_enabled {
|
||||
HistoryEntryReplacement::Disabled => {
|
||||
let diff = SessionHistoryDiff::HashDiff {
|
||||
pipeline_reloader: NeedsToReload::No(pipeline_id),
|
||||
new_url,
|
||||
old_url,
|
||||
};
|
||||
self.get_joint_session_history(top_level_browsing_context_id)
|
||||
.push_diff(diff);
|
||||
self.notify_history_changed(top_level_browsing_context_id);
|
||||
},
|
||||
HistoryEntryReplacement::Enabled => {},
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3395,7 +3386,12 @@ where
|
|||
));
|
||||
},
|
||||
WebDriverCommandMsg::LoadUrl(top_level_browsing_context_id, load_data, reply) => {
|
||||
self.load_url_for_webdriver(top_level_browsing_context_id, load_data, reply, false);
|
||||
self.load_url_for_webdriver(
|
||||
top_level_browsing_context_id,
|
||||
load_data,
|
||||
reply,
|
||||
HistoryEntryReplacement::Disabled,
|
||||
);
|
||||
},
|
||||
WebDriverCommandMsg::Refresh(top_level_browsing_context_id, reply) => {
|
||||
let browsing_context_id = BrowsingContextId::from(top_level_browsing_context_id);
|
||||
|
@ -3412,7 +3408,12 @@ where
|
|||
Some(pipeline) => pipeline.load_data.clone(),
|
||||
None => return warn!("Pipeline {} refresh after closure.", pipeline_id),
|
||||
};
|
||||
self.load_url_for_webdriver(top_level_browsing_context_id, load_data, reply, true);
|
||||
self.load_url_for_webdriver(
|
||||
top_level_browsing_context_id,
|
||||
load_data,
|
||||
reply,
|
||||
HistoryEntryReplacement::Enabled,
|
||||
);
|
||||
},
|
||||
WebDriverCommandMsg::ScriptCommand(browsing_context_id, cmd) => {
|
||||
let pipeline_id = match self.browsing_contexts.get(&browsing_context_id) {
|
||||
|
@ -3595,7 +3596,7 @@ where
|
|||
top_level_browsing_context_id: TopLevelBrowsingContextId,
|
||||
load_data: LoadData,
|
||||
reply: IpcSender<webdriver_msg::LoadStatus>,
|
||||
replace: bool,
|
||||
replace: HistoryEntryReplacement,
|
||||
) {
|
||||
let browsing_context_id = BrowsingContextId::from(top_level_browsing_context_id);
|
||||
let pipeline_id = match self.browsing_contexts.get(&browsing_context_id) {
|
||||
|
|
|
@ -215,8 +215,6 @@ impl Pipeline {
|
|||
device_pixel_ratio: state.device_pixel_ratio,
|
||||
};
|
||||
|
||||
let url = state.load_data.url.clone();
|
||||
|
||||
let (script_chan, sampler_chan) = match state.event_loop {
|
||||
Some(script_chan) => {
|
||||
let new_layout_info = NewLayoutInfo {
|
||||
|
@ -336,7 +334,6 @@ impl Pipeline {
|
|||
script_chan,
|
||||
pipeline_chan,
|
||||
state.compositor_proxy,
|
||||
url,
|
||||
state.prev_visibility,
|
||||
state.load_data,
|
||||
);
|
||||
|
@ -356,7 +353,6 @@ impl Pipeline {
|
|||
event_loop: Rc<EventLoop>,
|
||||
layout_chan: IpcSender<LayoutControlMsg>,
|
||||
compositor_proxy: CompositorProxy,
|
||||
url: ServoUrl,
|
||||
is_visible: bool,
|
||||
load_data: LoadData,
|
||||
) -> Pipeline {
|
||||
|
@ -368,7 +364,7 @@ impl Pipeline {
|
|||
event_loop: event_loop,
|
||||
layout_chan: layout_chan,
|
||||
compositor_proxy: compositor_proxy,
|
||||
url: url,
|
||||
url: load_data.url.clone(),
|
||||
children: vec![],
|
||||
running_animations: false,
|
||||
load_data: load_data,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue