mirror of
https://github.com/servo/servo.git
synced 2025-07-23 07:13:52 +01:00
Make non-initial about:blank loads asynchronous
Don't update iframe pipeline until load completes To preserve the previous functionality of delaying load events when a new navigation is triggered, pending pipeline id represents the current pending load. The load event is only fired if the load message's pipeline id matches the pending pipeline id. Track frame size on Frame instead of Pipeline Disabled matchMedia test Track creator pipeline id
This commit is contained in:
parent
f579405510
commit
d004db95cf
18 changed files with 305 additions and 200 deletions
|
@ -903,7 +903,8 @@ impl<Window: WindowMethods> IOCompositor<Window> {
|
||||||
match ServoUrl::parse(&url_string) {
|
match ServoUrl::parse(&url_string) {
|
||||||
Ok(url) => {
|
Ok(url) => {
|
||||||
let msg = match self.root_pipeline {
|
let msg = match self.root_pipeline {
|
||||||
Some(ref pipeline) => ConstellationMsg::LoadUrl(pipeline.id, LoadData::new(url, None, None)),
|
Some(ref pipeline) =>
|
||||||
|
ConstellationMsg::LoadUrl(pipeline.id, LoadData::new(url, Some(pipeline.id), None, None)),
|
||||||
None => ConstellationMsg::InitLoadUrl(url)
|
None => ConstellationMsg::InitLoadUrl(url)
|
||||||
};
|
};
|
||||||
if let Err(e) = self.constellation_chan.send(msg) {
|
if let Err(e) = self.constellation_chan.send(msg) {
|
||||||
|
|
|
@ -101,7 +101,7 @@ use script_traits::{IFrameLoadInfo, IFrameLoadInfoWithData, IFrameSandboxState,
|
||||||
use script_traits::{LayoutMsg as FromLayoutMsg, ScriptMsg as FromScriptMsg, ScriptThreadFactory};
|
use script_traits::{LayoutMsg as FromLayoutMsg, ScriptMsg as FromScriptMsg, ScriptThreadFactory};
|
||||||
use script_traits::{LogEntry, ServiceWorkerMsg, webdriver_msg};
|
use script_traits::{LogEntry, ServiceWorkerMsg, webdriver_msg};
|
||||||
use script_traits::{MozBrowserErrorType, MozBrowserEvent, WebDriverCommandMsg, WindowSizeData};
|
use script_traits::{MozBrowserErrorType, MozBrowserEvent, WebDriverCommandMsg, WindowSizeData};
|
||||||
use script_traits::{SWManagerMsg, ScopeThings, WindowSizeType};
|
use script_traits::{SWManagerMsg, ScopeThings, UpdatePipelineIdReason, WindowSizeType};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use servo_config::opts;
|
use servo_config::opts;
|
||||||
use servo_config::prefs::PREFS;
|
use servo_config::prefs::PREFS;
|
||||||
|
@ -599,17 +599,31 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
|
||||||
|
|
||||||
let (event_loop, host) = match sandbox {
|
let (event_loop, host) = match sandbox {
|
||||||
IFrameSandboxState::IFrameSandboxed => (None, None),
|
IFrameSandboxState::IFrameSandboxed => (None, None),
|
||||||
IFrameSandboxState::IFrameUnsandboxed => match reg_host(&load_data.url) {
|
IFrameSandboxState::IFrameUnsandboxed => {
|
||||||
None => (None, None),
|
// If this is an about:blank load, it must share the creator's event loop.
|
||||||
Some(host) => {
|
// This must match the logic in the script thread when determining the proper origin.
|
||||||
let event_loop = self.event_loops.get(&top_level_frame_id)
|
if load_data.url.as_str() != "about:blank" {
|
||||||
.and_then(|map| map.get(&host))
|
match reg_host(&load_data.url) {
|
||||||
.and_then(|weak| weak.upgrade());
|
None => (None, None),
|
||||||
match event_loop {
|
Some(host) => {
|
||||||
None => (None, Some(host)),
|
let event_loop = self.event_loops.get(&top_level_frame_id)
|
||||||
Some(event_loop) => (Some(event_loop.clone()), None),
|
.and_then(|map| map.get(&host))
|
||||||
|
.and_then(|weak| weak.upgrade());
|
||||||
|
match event_loop {
|
||||||
|
None => (None, Some(host)),
|
||||||
|
Some(event_loop) => (Some(event_loop.clone()), None),
|
||||||
|
}
|
||||||
|
},
|
||||||
}
|
}
|
||||||
},
|
} else if let Some(parent) = parent_info
|
||||||
|
.and_then(|(pipeline_id, _)| self.pipelines.get(&pipeline_id)) {
|
||||||
|
(Some(parent.event_loop.clone()), None)
|
||||||
|
} else if let Some(creator) = load_data.creator_pipeline_id
|
||||||
|
.and_then(|pipeline_id| self.pipelines.get(&pipeline_id)) {
|
||||||
|
(Some(creator.event_loop.clone()), None)
|
||||||
|
} else {
|
||||||
|
(None, None)
|
||||||
|
}
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -735,7 +749,10 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a new frame and update the internal bookkeeping.
|
/// Create a new frame and update the internal bookkeeping.
|
||||||
fn new_frame(&mut self, frame_id: FrameId, pipeline_id: PipelineId, load_data: LoadData) {
|
fn new_frame(&mut self,
|
||||||
|
frame_id: FrameId,
|
||||||
|
pipeline_id: PipelineId,
|
||||||
|
load_data: LoadData) {
|
||||||
let frame = Frame::new(frame_id, pipeline_id, load_data);
|
let frame = Frame::new(frame_id, pipeline_id, load_data);
|
||||||
self.frames.insert(frame_id, frame);
|
self.frames.insert(frame_id, frame);
|
||||||
|
|
||||||
|
@ -915,11 +932,11 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
|
||||||
load_info.info.new_pipeline_id);
|
load_info.info.new_pipeline_id);
|
||||||
self.handle_script_loaded_url_in_iframe_msg(load_info);
|
self.handle_script_loaded_url_in_iframe_msg(load_info);
|
||||||
}
|
}
|
||||||
FromScriptMsg::ScriptLoadedAboutBlankInIFrame(load_info, lc) => {
|
FromScriptMsg::ScriptNewIFrame(load_info, layout_sender) => {
|
||||||
debug!("constellation got loaded `about:blank` in iframe message {:?} {:?}",
|
debug!("constellation got loaded `about:blank` in iframe message {:?} {:?}",
|
||||||
load_info.parent_pipeline_id,
|
load_info.parent_pipeline_id,
|
||||||
load_info.new_pipeline_id);
|
load_info.new_pipeline_id);
|
||||||
self.handle_script_loaded_about_blank_in_iframe_msg(load_info, lc);
|
self.handle_script_new_iframe(load_info, layout_sender);
|
||||||
}
|
}
|
||||||
FromScriptMsg::ChangeRunningAnimationsState(pipeline_id, animation_state) => {
|
FromScriptMsg::ChangeRunningAnimationsState(pipeline_id, animation_state) => {
|
||||||
self.handle_change_running_animations_state(pipeline_id, animation_state)
|
self.handle_change_running_animations_state(pipeline_id, animation_state)
|
||||||
|
@ -1277,10 +1294,19 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
|
||||||
// Notify the browser chrome that the pipeline has failed
|
// Notify the browser chrome that the pipeline has failed
|
||||||
self.trigger_mozbrowsererror(top_level_frame_id, reason, backtrace);
|
self.trigger_mozbrowsererror(top_level_frame_id, reason, backtrace);
|
||||||
|
|
||||||
let pipeline_id = self.frames.get(&top_level_frame_id).map(|frame| frame.pipeline_id);
|
let (window_size, pipeline_id) = {
|
||||||
let pipeline_url = pipeline_id.and_then(|id| self.pipelines.get(&id).map(|pipeline| pipeline.url.clone()));
|
let frame = self.frames.get(&top_level_frame_id);
|
||||||
let parent_info = pipeline_id.and_then(|id| self.pipelines.get(&id).and_then(|pipeline| pipeline.parent_info));
|
let window_size = frame.and_then(|frame| frame.size);
|
||||||
let window_size = pipeline_id.and_then(|id| self.pipelines.get(&id).and_then(|pipeline| pipeline.size));
|
let pipeline_id = frame.map(|frame| frame.pipeline_id);
|
||||||
|
(window_size, pipeline_id)
|
||||||
|
};
|
||||||
|
|
||||||
|
let (pipeline_url, parent_info) = {
|
||||||
|
let pipeline = pipeline_id.and_then(|id| self.pipelines.get(&id));
|
||||||
|
let pipeline_url = pipeline.map(|pipeline| pipeline.url.clone());
|
||||||
|
let parent_info = pipeline.and_then(|pipeline| pipeline.parent_info);
|
||||||
|
(pipeline_url, parent_info)
|
||||||
|
};
|
||||||
|
|
||||||
self.close_frame_children(top_level_frame_id, DiscardBrowsingContext::No, ExitPipelineMode::Force);
|
self.close_frame_children(top_level_frame_id, DiscardBrowsingContext::No, ExitPipelineMode::Force);
|
||||||
|
|
||||||
|
@ -1295,7 +1321,7 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
|
||||||
warn!("creating replacement pipeline for about:failure");
|
warn!("creating replacement pipeline for about:failure");
|
||||||
|
|
||||||
let new_pipeline_id = PipelineId::new();
|
let new_pipeline_id = PipelineId::new();
|
||||||
let load_data = LoadData::new(failure_url, None, None);
|
let load_data = LoadData::new(failure_url, None, None, None);
|
||||||
let sandbox = IFrameSandboxState::IFrameSandboxed;
|
let sandbox = IFrameSandboxState::IFrameSandboxed;
|
||||||
self.new_pipeline(new_pipeline_id, top_level_frame_id, parent_info,
|
self.new_pipeline(new_pipeline_id, top_level_frame_id, parent_info,
|
||||||
window_size, load_data.clone(), sandbox, false);
|
window_size, load_data.clone(), sandbox, false);
|
||||||
|
@ -1340,7 +1366,7 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
|
||||||
let window_size = self.window_size.initial_viewport;
|
let window_size = self.window_size.initial_viewport;
|
||||||
let root_pipeline_id = PipelineId::new();
|
let root_pipeline_id = PipelineId::new();
|
||||||
let root_frame_id = self.root_frame_id;
|
let root_frame_id = self.root_frame_id;
|
||||||
let load_data = LoadData::new(url.clone(), None, None);
|
let load_data = LoadData::new(url.clone(), None, None, None);
|
||||||
let sandbox = IFrameSandboxState::IFrameUnsandboxed;
|
let sandbox = IFrameSandboxState::IFrameUnsandboxed;
|
||||||
self.new_pipeline(root_pipeline_id, root_frame_id, None, Some(window_size), load_data.clone(), sandbox, false);
|
self.new_pipeline(root_pipeline_id, root_frame_id, None, Some(window_size), load_data.clone(), sandbox, false);
|
||||||
self.handle_load_start_msg(root_pipeline_id);
|
self.handle_load_start_msg(root_pipeline_id);
|
||||||
|
@ -1353,29 +1379,14 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_frame_size_msg(&mut self,
|
fn handle_frame_size_msg(&mut self,
|
||||||
iframe_sizes: Vec<(PipelineId, TypedSize2D<f32, CSSPixel>)>) {
|
iframe_sizes: Vec<(FrameId, TypedSize2D<f32, CSSPixel>)>) {
|
||||||
for (pipeline_id, size) in iframe_sizes {
|
for (frame_id, size) in iframe_sizes {
|
||||||
let result = {
|
let window_size = WindowSizeData {
|
||||||
let pipeline = match self.pipelines.get_mut(&pipeline_id) {
|
initial_viewport: size,
|
||||||
Some(pipeline) => pipeline,
|
device_pixel_ratio: self.window_size.device_pixel_ratio,
|
||||||
None => continue,
|
|
||||||
};
|
|
||||||
|
|
||||||
if pipeline.size == Some(size) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
pipeline.size = Some(size);
|
|
||||||
let msg = ConstellationControlMsg::Resize(pipeline_id, WindowSizeData {
|
|
||||||
initial_viewport: size,
|
|
||||||
device_pixel_ratio: self.window_size.device_pixel_ratio,
|
|
||||||
}, WindowSizeType::Initial);
|
|
||||||
|
|
||||||
pipeline.event_loop.send(msg)
|
|
||||||
};
|
};
|
||||||
if let Err(e) = result {
|
|
||||||
self.handle_send_error(pipeline_id, e);
|
self.resize_frame(window_size, WindowSizeType::Initial, frame_id);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1423,12 +1434,12 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
|
||||||
};
|
};
|
||||||
|
|
||||||
// TODO - loaddata here should have referrer info (not None, None)
|
// TODO - loaddata here should have referrer info (not None, None)
|
||||||
LoadData::new(url, None, None)
|
LoadData::new(url, Some(source_pipeline.id), None, None)
|
||||||
});
|
});
|
||||||
|
|
||||||
let is_private = load_info.info.is_private || source_pipeline.is_private;
|
let is_private = load_info.info.is_private || source_pipeline.is_private;
|
||||||
|
|
||||||
let window_size = old_pipeline.and_then(|old_pipeline| old_pipeline.size);
|
let window_size = self.frames.get(&load_info.info.frame_id).and_then(|frame| frame.size);
|
||||||
|
|
||||||
(load_data, window_size, is_private)
|
(load_data, window_size, is_private)
|
||||||
};
|
};
|
||||||
|
@ -1456,9 +1467,9 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
|
||||||
is_private);
|
is_private);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_script_loaded_about_blank_in_iframe_msg(&mut self,
|
fn handle_script_new_iframe(&mut self,
|
||||||
load_info: IFrameLoadInfo,
|
load_info: IFrameLoadInfo,
|
||||||
layout_sender: IpcSender<LayoutControlMsg>) {
|
layout_sender: IpcSender<LayoutControlMsg>) {
|
||||||
let IFrameLoadInfo {
|
let IFrameLoadInfo {
|
||||||
parent_pipeline_id,
|
parent_pipeline_id,
|
||||||
new_pipeline_id,
|
new_pipeline_id,
|
||||||
|
@ -1486,12 +1497,11 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
|
||||||
self.compositor_proxy.clone_compositor_proxy(),
|
self.compositor_proxy.clone_compositor_proxy(),
|
||||||
is_private || parent_pipeline.is_private,
|
is_private || parent_pipeline.is_private,
|
||||||
url.clone(),
|
url.clone(),
|
||||||
None,
|
|
||||||
parent_pipeline.visible)
|
parent_pipeline.visible)
|
||||||
};
|
};
|
||||||
|
|
||||||
// TODO: Referrer?
|
// TODO: Referrer?
|
||||||
let load_data = LoadData::new(url, None, None);
|
let load_data = LoadData::new(url, Some(parent_pipeline_id), None, None);
|
||||||
|
|
||||||
let replace_instant = if replace {
|
let replace_instant = if replace {
|
||||||
self.frames.get(&frame_id).map(|frame| frame.instant)
|
self.frames.get(&frame_id).map(|frame| frame.instant)
|
||||||
|
@ -1641,7 +1651,7 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
|
||||||
// changes would be overridden by changing the subframe associated with source_id.
|
// changes would be overridden by changing the subframe associated with source_id.
|
||||||
|
|
||||||
// Create the new pipeline
|
// Create the new pipeline
|
||||||
let window_size = self.pipelines.get(&source_id).and_then(|source| source.size);
|
let window_size = self.frames.get(&root_frame_id).and_then(|frame| frame.size);
|
||||||
let new_pipeline_id = PipelineId::new();
|
let new_pipeline_id = PipelineId::new();
|
||||||
let sandbox = IFrameSandboxState::IFrameUnsandboxed;
|
let sandbox = IFrameSandboxState::IFrameUnsandboxed;
|
||||||
let replace_instant = if replace {
|
let replace_instant = if replace {
|
||||||
|
@ -1959,7 +1969,7 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
|
||||||
},
|
},
|
||||||
WebDriverCommandMsg::Refresh(pipeline_id, reply) => {
|
WebDriverCommandMsg::Refresh(pipeline_id, reply) => {
|
||||||
let load_data = match self.pipelines.get(&pipeline_id) {
|
let load_data = match self.pipelines.get(&pipeline_id) {
|
||||||
Some(pipeline) => LoadData::new(pipeline.url.clone(), None, None),
|
Some(pipeline) => LoadData::new(pipeline.url.clone(), None, None, None),
|
||||||
None => return warn!("Pipeline {:?} Refresh after closure.", pipeline_id),
|
None => return warn!("Pipeline {:?} Refresh after closure.", pipeline_id),
|
||||||
};
|
};
|
||||||
self.load_url_for_webdriver(pipeline_id, load_data, reply, true);
|
self.load_url_for_webdriver(pipeline_id, load_data, reply, true);
|
||||||
|
@ -2019,8 +2029,8 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
|
||||||
let load_data = entry.load_data;
|
let load_data = entry.load_data;
|
||||||
let (parent_info, window_size, is_private) = match self.frames.get(&frame_id) {
|
let (parent_info, window_size, is_private) = match self.frames.get(&frame_id) {
|
||||||
Some(frame) => match self.pipelines.get(&frame.pipeline_id) {
|
Some(frame) => match self.pipelines.get(&frame.pipeline_id) {
|
||||||
Some(pipeline) => (pipeline.parent_info, pipeline.size, pipeline.is_private),
|
Some(pipeline) => (pipeline.parent_info, frame.size, pipeline.is_private),
|
||||||
None => (None, None, false),
|
None => (None, frame.size, false),
|
||||||
},
|
},
|
||||||
None => return warn!("no frame to traverse"),
|
None => return warn!("no frame to traverse"),
|
||||||
};
|
};
|
||||||
|
@ -2101,7 +2111,8 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
|
||||||
// Update the owning iframe to point to the new pipeline id.
|
// Update the owning iframe to point to the new pipeline id.
|
||||||
// This makes things like contentDocument work correctly.
|
// This makes things like contentDocument work correctly.
|
||||||
if let Some((parent_pipeline_id, _)) = parent_info {
|
if let Some((parent_pipeline_id, _)) = parent_info {
|
||||||
let msg = ConstellationControlMsg::UpdatePipelineId(parent_pipeline_id, frame_id, pipeline_id);
|
let msg = ConstellationControlMsg::UpdatePipelineId(parent_pipeline_id,
|
||||||
|
frame_id, pipeline_id, UpdatePipelineIdReason::Traversal);
|
||||||
let result = match self.pipelines.get(&parent_pipeline_id) {
|
let result = match self.pipelines.get(&parent_pipeline_id) {
|
||||||
None => return warn!("Pipeline {:?} child traversed after closure.", parent_pipeline_id),
|
None => return warn!("Pipeline {:?} child traversed after closure.", parent_pipeline_id),
|
||||||
Some(pipeline) => pipeline.event_loop.send(msg),
|
Some(pipeline) => pipeline.event_loop.send(msg),
|
||||||
|
@ -2245,7 +2256,9 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
|
||||||
}
|
}
|
||||||
|
|
||||||
if new_frame {
|
if new_frame {
|
||||||
self.new_frame(frame_change.frame_id, frame_change.new_pipeline_id, frame_change.load_data);
|
self.new_frame(frame_change.frame_id,
|
||||||
|
frame_change.new_pipeline_id,
|
||||||
|
frame_change.load_data);
|
||||||
self.update_activity(frame_change.new_pipeline_id);
|
self.update_activity(frame_change.new_pipeline_id);
|
||||||
self.notify_history_changed(frame_change.new_pipeline_id);
|
self.notify_history_changed(frame_change.new_pipeline_id);
|
||||||
};
|
};
|
||||||
|
@ -2275,7 +2288,8 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
|
||||||
if let Some(pipeline) = self.pipelines.get(&pipeline_id) {
|
if let Some(pipeline) = self.pipelines.get(&pipeline_id) {
|
||||||
if let Some((parent_pipeline_id, _)) = pipeline.parent_info {
|
if let Some((parent_pipeline_id, _)) = pipeline.parent_info {
|
||||||
if let Some(parent_pipeline) = self.pipelines.get(&parent_pipeline_id) {
|
if let Some(parent_pipeline) = self.pipelines.get(&parent_pipeline_id) {
|
||||||
let msg = ConstellationControlMsg::FramedContentChanged(parent_pipeline_id, pipeline.frame_id);
|
let msg = ConstellationControlMsg::UpdatePipelineId(parent_pipeline_id,
|
||||||
|
pipeline.frame_id, pipeline_id, UpdatePipelineIdReason::Navigation);
|
||||||
let _ = parent_pipeline.event_loop.send(msg);
|
let _ = parent_pipeline.event_loop.send(msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2298,45 +2312,8 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
|
||||||
fn handle_window_size_msg(&mut self, new_size: WindowSizeData, size_type: WindowSizeType) {
|
fn handle_window_size_msg(&mut self, new_size: WindowSizeData, size_type: WindowSizeType) {
|
||||||
debug!("handle_window_size_msg: {:?}", new_size.initial_viewport.to_untyped());
|
debug!("handle_window_size_msg: {:?}", new_size.initial_viewport.to_untyped());
|
||||||
|
|
||||||
if let Some(frame) = self.frames.get(&self.root_frame_id) {
|
let frame_id = self.root_frame_id;
|
||||||
// Send Resize (or ResizeInactive) messages to each
|
self.resize_frame(new_size, size_type, frame_id);
|
||||||
// pipeline in the frame tree.
|
|
||||||
let pipeline_id = frame.pipeline_id;
|
|
||||||
let pipeline = match self.pipelines.get(&pipeline_id) {
|
|
||||||
None => return warn!("Pipeline {:?} resized after closing.", pipeline_id),
|
|
||||||
Some(pipeline) => pipeline,
|
|
||||||
};
|
|
||||||
let _ = pipeline.event_loop.send(ConstellationControlMsg::Resize(
|
|
||||||
pipeline.id,
|
|
||||||
new_size,
|
|
||||||
size_type
|
|
||||||
));
|
|
||||||
let pipelines = frame.prev.iter().chain(frame.next.iter())
|
|
||||||
.filter_map(|entry| entry.pipeline_id)
|
|
||||||
.filter_map(|pipeline_id| self.pipelines.get(&pipeline_id));
|
|
||||||
for pipeline in pipelines {
|
|
||||||
let _ = pipeline.event_loop.send(ConstellationControlMsg::ResizeInactive(
|
|
||||||
pipeline.id,
|
|
||||||
new_size
|
|
||||||
));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Send resize message to any pending pipelines that aren't loaded yet.
|
|
||||||
for pending_frame in &self.pending_frames {
|
|
||||||
let pipeline_id = pending_frame.new_pipeline_id;
|
|
||||||
let pipeline = match self.pipelines.get(&pipeline_id) {
|
|
||||||
None => { warn!("Pending pipeline {:?} is closed", pipeline_id); continue; }
|
|
||||||
Some(pipeline) => pipeline,
|
|
||||||
};
|
|
||||||
if pipeline.parent_info.is_none() {
|
|
||||||
let _ = pipeline.event_loop.send(ConstellationControlMsg::Resize(
|
|
||||||
pipeline.id,
|
|
||||||
new_size,
|
|
||||||
size_type
|
|
||||||
));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(resize_channel) = self.webdriver.resize_channel.take() {
|
if let Some(resize_channel) = self.webdriver.resize_channel.take() {
|
||||||
let _ = resize_channel.send(new_size);
|
let _ = resize_channel.send(new_size);
|
||||||
|
@ -2422,7 +2399,7 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
|
||||||
// size for the pipeline, then its painting should be up to date. If the constellation
|
// size for the pipeline, then its painting should be up to date. If the constellation
|
||||||
// *hasn't* received a size, it could be that the layer was hidden by script before the
|
// *hasn't* received a size, it could be that the layer was hidden by script before the
|
||||||
// compositor discovered it, so we just don't check the layer.
|
// compositor discovered it, so we just don't check the layer.
|
||||||
if let Some(size) = pipeline.size {
|
if let Some(size) = frame.size {
|
||||||
// If the rectangle for this pipeline is zero sized, it will
|
// If the rectangle for this pipeline is zero sized, it will
|
||||||
// never be painted. In this case, don't query the layout
|
// never be painted. In this case, don't query the layout
|
||||||
// thread as it won't contribute to the final output image.
|
// thread as it won't contribute to the final output image.
|
||||||
|
@ -2509,6 +2486,54 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
|
||||||
self.set_activity(pipeline_id, self.get_activity(pipeline_id));
|
self.set_activity(pipeline_id, self.get_activity(pipeline_id));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Handle updating the size of a frame. This notifies every pipeline in the frame of the new
|
||||||
|
/// size.
|
||||||
|
fn resize_frame(&mut self, new_size: WindowSizeData, size_type: WindowSizeType, frame_id: FrameId) {
|
||||||
|
if let Some(frame) = self.frames.get_mut(&frame_id) {
|
||||||
|
frame.size = Some(new_size.initial_viewport);
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(frame) = self.frames.get(&frame_id) {
|
||||||
|
// Send Resize (or ResizeInactive) messages to each
|
||||||
|
// pipeline in the frame tree.
|
||||||
|
let pipeline_id = frame.pipeline_id;
|
||||||
|
let pipeline = match self.pipelines.get(&pipeline_id) {
|
||||||
|
None => return warn!("Pipeline {:?} resized after closing.", pipeline_id),
|
||||||
|
Some(pipeline) => pipeline,
|
||||||
|
};
|
||||||
|
let _ = pipeline.event_loop.send(ConstellationControlMsg::Resize(
|
||||||
|
pipeline.id,
|
||||||
|
new_size,
|
||||||
|
size_type
|
||||||
|
));
|
||||||
|
let pipelines = frame.prev.iter().chain(frame.next.iter())
|
||||||
|
.filter_map(|entry| entry.pipeline_id)
|
||||||
|
.filter_map(|pipeline_id| self.pipelines.get(&pipeline_id));
|
||||||
|
for pipeline in pipelines {
|
||||||
|
let _ = pipeline.event_loop.send(ConstellationControlMsg::ResizeInactive(
|
||||||
|
pipeline.id,
|
||||||
|
new_size
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send resize message to any pending pipelines that aren't loaded yet.
|
||||||
|
for pending_frame in &self.pending_frames {
|
||||||
|
let pipeline_id = pending_frame.new_pipeline_id;
|
||||||
|
let pipeline = match self.pipelines.get(&pipeline_id) {
|
||||||
|
None => { warn!("Pending pipeline {:?} is closed", pipeline_id); continue; }
|
||||||
|
Some(pipeline) => pipeline,
|
||||||
|
};
|
||||||
|
if pipeline.frame_id == frame_id {
|
||||||
|
let _ = pipeline.event_loop.send(ConstellationControlMsg::Resize(
|
||||||
|
pipeline.id,
|
||||||
|
new_size,
|
||||||
|
size_type
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn clear_joint_session_future(&mut self, frame_id: FrameId) {
|
fn clear_joint_session_future(&mut self, frame_id: FrameId) {
|
||||||
let frame_ids: Vec<FrameId> = self.full_frame_tree_iter(frame_id)
|
let frame_ids: Vec<FrameId> = self.full_frame_tree_iter(frame_id)
|
||||||
.map(|frame| frame.id)
|
.map(|frame| frame.id)
|
||||||
|
@ -2652,7 +2677,7 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
|
||||||
self.pipelines.get(&frame.pipeline_id).map(|pipeline: &Pipeline| {
|
self.pipelines.get(&frame.pipeline_id).map(|pipeline: &Pipeline| {
|
||||||
let mut frame_tree = SendableFrameTree {
|
let mut frame_tree = SendableFrameTree {
|
||||||
pipeline: pipeline.to_sendable(),
|
pipeline: pipeline.to_sendable(),
|
||||||
size: pipeline.size,
|
size: frame.size,
|
||||||
children: vec!(),
|
children: vec!(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* 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/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
use euclid::size::TypedSize2D;
|
||||||
use msg::constellation_msg::{FrameId, PipelineId};
|
use msg::constellation_msg::{FrameId, PipelineId};
|
||||||
use pipeline::Pipeline;
|
use pipeline::Pipeline;
|
||||||
use script_traits::LoadData;
|
use script_traits::LoadData;
|
||||||
|
@ -9,6 +10,7 @@ use std::collections::HashMap;
|
||||||
use std::iter::once;
|
use std::iter::once;
|
||||||
use std::mem::replace;
|
use std::mem::replace;
|
||||||
use std::time::Instant;
|
use std::time::Instant;
|
||||||
|
use style_traits::CSSPixel;
|
||||||
|
|
||||||
/// A frame in the frame tree.
|
/// A frame in the frame tree.
|
||||||
/// Each frame is the constellation's view of a browsing context.
|
/// Each frame is the constellation's view of a browsing context.
|
||||||
|
@ -22,13 +24,16 @@ pub struct Frame {
|
||||||
/// The frame id.
|
/// The frame id.
|
||||||
pub id: FrameId,
|
pub id: FrameId,
|
||||||
|
|
||||||
/// The timestamp for the current session history entry
|
/// The size of the frame.
|
||||||
|
pub size: Option<TypedSize2D<f32, CSSPixel>>,
|
||||||
|
|
||||||
|
/// The timestamp for the current session history entry.
|
||||||
pub instant: Instant,
|
pub instant: Instant,
|
||||||
|
|
||||||
/// The pipeline for the current session history entry
|
/// The pipeline for the current session history entry.
|
||||||
pub pipeline_id: PipelineId,
|
pub pipeline_id: PipelineId,
|
||||||
|
|
||||||
/// The load data for the current session history entry
|
/// The load data for the current session history entry.
|
||||||
pub load_data: LoadData,
|
pub load_data: LoadData,
|
||||||
|
|
||||||
/// The past session history, ordered chronologically.
|
/// The past session history, ordered chronologically.
|
||||||
|
@ -44,6 +49,7 @@ impl Frame {
|
||||||
pub fn new(id: FrameId, pipeline_id: PipelineId, load_data: LoadData) -> Frame {
|
pub fn new(id: FrameId, pipeline_id: PipelineId, load_data: LoadData) -> Frame {
|
||||||
Frame {
|
Frame {
|
||||||
id: id,
|
id: id,
|
||||||
|
size: None,
|
||||||
pipeline_id: pipeline_id,
|
pipeline_id: pipeline_id,
|
||||||
instant: Instant::now(),
|
instant: Instant::now(),
|
||||||
load_data: load_data,
|
load_data: load_data,
|
||||||
|
|
|
@ -76,10 +76,6 @@ pub struct Pipeline {
|
||||||
/// The title of the most recently-loaded page.
|
/// The title of the most recently-loaded page.
|
||||||
pub title: Option<String>,
|
pub title: Option<String>,
|
||||||
|
|
||||||
/// The size of the frame.
|
|
||||||
/// TODO: move this field to `Frame`.
|
|
||||||
pub size: Option<TypedSize2D<f32, CSSPixel>>,
|
|
||||||
|
|
||||||
/// Whether this pipeline is currently running animations. Pipelines that are running
|
/// Whether this pipeline is currently running animations. Pipelines that are running
|
||||||
/// animations cause composites to be continually scheduled.
|
/// animations cause composites to be continually scheduled.
|
||||||
pub running_animations: bool,
|
pub running_animations: bool,
|
||||||
|
@ -291,7 +287,6 @@ impl Pipeline {
|
||||||
state.compositor_proxy,
|
state.compositor_proxy,
|
||||||
state.is_private,
|
state.is_private,
|
||||||
url,
|
url,
|
||||||
state.window_size,
|
|
||||||
state.prev_visibility.unwrap_or(true)))
|
state.prev_visibility.unwrap_or(true)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -305,7 +300,6 @@ impl Pipeline {
|
||||||
compositor_proxy: Box<CompositorProxy + 'static + Send>,
|
compositor_proxy: Box<CompositorProxy + 'static + Send>,
|
||||||
is_private: bool,
|
is_private: bool,
|
||||||
url: ServoUrl,
|
url: ServoUrl,
|
||||||
size: Option<TypedSize2D<f32, CSSPixel>>,
|
|
||||||
visible: bool)
|
visible: bool)
|
||||||
-> Pipeline {
|
-> Pipeline {
|
||||||
let pipeline = Pipeline {
|
let pipeline = Pipeline {
|
||||||
|
@ -318,7 +312,6 @@ impl Pipeline {
|
||||||
url: url,
|
url: url,
|
||||||
title: None,
|
title: None,
|
||||||
children: vec!(),
|
children: vec!(),
|
||||||
size: size,
|
|
||||||
running_animations: false,
|
running_animations: false,
|
||||||
visible: visible,
|
visible: visible,
|
||||||
is_private: is_private,
|
is_private: is_private,
|
||||||
|
|
|
@ -34,7 +34,7 @@ use inline::{FIRST_FRAGMENT_OF_ELEMENT, InlineFlow, LAST_FRAGMENT_OF_ELEMENT};
|
||||||
use ipc_channel::ipc;
|
use ipc_channel::ipc;
|
||||||
use list_item::ListItemFlow;
|
use list_item::ListItemFlow;
|
||||||
use model::{self, MaybeAuto, specified};
|
use model::{self, MaybeAuto, specified};
|
||||||
use msg::constellation_msg::PipelineId;
|
use msg::constellation_msg::FrameId;
|
||||||
use net_traits::image::base::PixelFormat;
|
use net_traits::image::base::PixelFormat;
|
||||||
use net_traits::image_cache::UsePlaceholder;
|
use net_traits::image_cache::UsePlaceholder;
|
||||||
use range::Range;
|
use range::Range;
|
||||||
|
@ -173,7 +173,7 @@ pub struct DisplayListBuildState<'a> {
|
||||||
|
|
||||||
/// Vector containing iframe sizes, used to inform the constellation about
|
/// Vector containing iframe sizes, used to inform the constellation about
|
||||||
/// new iframe sizes
|
/// new iframe sizes
|
||||||
pub iframe_sizes: Vec<(PipelineId, TypedSize2D<f32, CSSPixel>)>,
|
pub iframe_sizes: Vec<(FrameId, TypedSize2D<f32, CSSPixel>)>,
|
||||||
|
|
||||||
/// A stack of clips used to cull display list entries that are outside the
|
/// A stack of clips used to cull display list entries that are outside the
|
||||||
/// rendered region.
|
/// rendered region.
|
||||||
|
@ -1809,7 +1809,7 @@ impl FragmentDisplayListBuilding for Fragment {
|
||||||
|
|
||||||
let size = Size2D::new(item.bounds().size.width.to_f32_px(),
|
let size = Size2D::new(item.bounds().size.width.to_f32_px(),
|
||||||
item.bounds().size.height.to_f32_px());
|
item.bounds().size.height.to_f32_px());
|
||||||
state.iframe_sizes.push((fragment_info.pipeline_id, TypedSize2D::from_untyped(&size)));
|
state.iframe_sizes.push((fragment_info.frame_id, TypedSize2D::from_untyped(&size)));
|
||||||
|
|
||||||
state.add_display_item(item);
|
state.add_display_item(item);
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,7 @@ use ipc_channel::ipc::IpcSender;
|
||||||
use layout_debug;
|
use layout_debug;
|
||||||
use model::{self, IntrinsicISizes, IntrinsicISizesContribution, MaybeAuto, SizeConstraint};
|
use model::{self, IntrinsicISizes, IntrinsicISizesContribution, MaybeAuto, SizeConstraint};
|
||||||
use model::{style_length, ToGfxMatrix};
|
use model::{style_length, ToGfxMatrix};
|
||||||
use msg::constellation_msg::PipelineId;
|
use msg::constellation_msg::{FrameId, PipelineId};
|
||||||
use net_traits::image::base::{Image, ImageMetadata};
|
use net_traits::image::base::{Image, ImageMetadata};
|
||||||
use net_traits::image_cache::{ImageOrMetadataAvailable, UsePlaceholder};
|
use net_traits::image_cache::{ImageOrMetadataAvailable, UsePlaceholder};
|
||||||
use range::*;
|
use range::*;
|
||||||
|
@ -467,19 +467,23 @@ impl ImageFragmentInfo {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A fragment that represents an inline frame (iframe). This stores the pipeline ID so that the
|
/// A fragment that represents an inline frame (iframe). This stores the frame ID so that the
|
||||||
/// size of this iframe can be communicated via the constellation to the iframe's own layout thread.
|
/// size of this iframe can be communicated via the constellation to the iframe's own layout thread.
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct IframeFragmentInfo {
|
pub struct IframeFragmentInfo {
|
||||||
/// The pipeline ID of this iframe.
|
/// The frame ID of this iframe.
|
||||||
|
pub frame_id: FrameId,
|
||||||
|
/// The pipelineID of this iframe.
|
||||||
pub pipeline_id: PipelineId,
|
pub pipeline_id: PipelineId,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl IframeFragmentInfo {
|
impl IframeFragmentInfo {
|
||||||
/// Creates the information specific to an iframe fragment.
|
/// Creates the information specific to an iframe fragment.
|
||||||
pub fn new<N: ThreadSafeLayoutNode>(node: &N) -> IframeFragmentInfo {
|
pub fn new<N: ThreadSafeLayoutNode>(node: &N) -> IframeFragmentInfo {
|
||||||
|
let frame_id = node.iframe_frame_id();
|
||||||
let pipeline_id = node.iframe_pipeline_id();
|
let pipeline_id = node.iframe_pipeline_id();
|
||||||
IframeFragmentInfo {
|
IframeFragmentInfo {
|
||||||
|
frame_id: frame_id,
|
||||||
pipeline_id: pipeline_id,
|
pipeline_id: pipeline_id,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -310,3 +310,4 @@ pub enum FrameType {
|
||||||
IFrame,
|
IFrame,
|
||||||
MozBrowserIFrame,
|
MozBrowserIFrame,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -345,7 +345,7 @@ impl HTMLFormElement {
|
||||||
let _target = submitter.target();
|
let _target = submitter.target();
|
||||||
// TODO: Handle browsing contexts, partially loaded documents (step 16-17)
|
// TODO: Handle browsing contexts, partially loaded documents (step 16-17)
|
||||||
|
|
||||||
let mut load_data = LoadData::new(action_components, doc.get_referrer_policy(), Some(doc.url()));
|
let mut load_data = LoadData::new(action_components, None, doc.get_referrer_policy(), Some(doc.url()));
|
||||||
|
|
||||||
// Step 18
|
// Step 18
|
||||||
match (&*scheme, method) {
|
match (&*scheme, method) {
|
||||||
|
|
|
@ -44,7 +44,7 @@ use msg::constellation_msg::{FrameType, FrameId, PipelineId, TraversalDirection}
|
||||||
use net_traits::response::HttpsState;
|
use net_traits::response::HttpsState;
|
||||||
use script_layout_interface::message::ReflowQueryType;
|
use script_layout_interface::message::ReflowQueryType;
|
||||||
use script_thread::{ScriptThread, Runnable};
|
use script_thread::{ScriptThread, Runnable};
|
||||||
use script_traits::{IFrameLoadInfo, IFrameLoadInfoWithData, LoadData};
|
use script_traits::{IFrameLoadInfo, IFrameLoadInfoWithData, LoadData, UpdatePipelineIdReason};
|
||||||
use script_traits::{MozBrowserEvent, NewLayoutInfo, ScriptMsg as ConstellationMsg};
|
use script_traits::{MozBrowserEvent, NewLayoutInfo, ScriptMsg as ConstellationMsg};
|
||||||
use script_traits::IFrameSandboxState::{IFrameSandboxed, IFrameUnsandboxed};
|
use script_traits::IFrameSandboxState::{IFrameSandboxed, IFrameUnsandboxed};
|
||||||
use servo_atoms::Atom;
|
use servo_atoms::Atom;
|
||||||
|
@ -69,6 +69,12 @@ bitflags! {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(PartialEq)]
|
||||||
|
pub enum NavigationType {
|
||||||
|
InitialAboutBlank,
|
||||||
|
Regular,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(PartialEq)]
|
#[derive(PartialEq)]
|
||||||
enum ProcessingMode {
|
enum ProcessingMode {
|
||||||
FirstTime,
|
FirstTime,
|
||||||
|
@ -80,6 +86,7 @@ pub struct HTMLIFrameElement {
|
||||||
htmlelement: HTMLElement,
|
htmlelement: HTMLElement,
|
||||||
frame_id: FrameId,
|
frame_id: FrameId,
|
||||||
pipeline_id: Cell<Option<PipelineId>>,
|
pipeline_id: Cell<Option<PipelineId>>,
|
||||||
|
pending_pipeline_id: Cell<Option<PipelineId>>,
|
||||||
sandbox: MutNullableJS<DOMTokenList>,
|
sandbox: MutNullableJS<DOMTokenList>,
|
||||||
sandbox_allowance: Cell<Option<SandboxAllowance>>,
|
sandbox_allowance: Cell<Option<SandboxAllowance>>,
|
||||||
load_blocker: DOMRefCell<Option<LoadBlocker>>,
|
load_blocker: DOMRefCell<Option<LoadBlocker>>,
|
||||||
|
@ -108,12 +115,14 @@ impl HTMLIFrameElement {
|
||||||
pub fn generate_new_pipeline_id(&self) -> (Option<PipelineId>, PipelineId) {
|
pub fn generate_new_pipeline_id(&self) -> (Option<PipelineId>, PipelineId) {
|
||||||
let old_pipeline_id = self.pipeline_id.get();
|
let old_pipeline_id = self.pipeline_id.get();
|
||||||
let new_pipeline_id = PipelineId::new();
|
let new_pipeline_id = PipelineId::new();
|
||||||
self.pipeline_id.set(Some(new_pipeline_id));
|
|
||||||
debug!("Frame {} created pipeline {}.", self.frame_id, new_pipeline_id);
|
debug!("Frame {} created pipeline {}.", self.frame_id, new_pipeline_id);
|
||||||
(old_pipeline_id, new_pipeline_id)
|
(old_pipeline_id, new_pipeline_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn navigate_or_reload_child_browsing_context(&self, load_data: Option<LoadData>, replace: bool) {
|
pub fn navigate_or_reload_child_browsing_context(&self,
|
||||||
|
load_data: Option<LoadData>,
|
||||||
|
nav_type: NavigationType,
|
||||||
|
replace: bool) {
|
||||||
let sandboxed = if self.is_sandboxed() {
|
let sandboxed = if self.is_sandboxed() {
|
||||||
IFrameSandboxed
|
IFrameSandboxed
|
||||||
} else {
|
} else {
|
||||||
|
@ -136,6 +145,7 @@ impl HTMLIFrameElement {
|
||||||
|
|
||||||
let window = window_from_node(self);
|
let window = window_from_node(self);
|
||||||
let (old_pipeline_id, new_pipeline_id) = self.generate_new_pipeline_id();
|
let (old_pipeline_id, new_pipeline_id) = self.generate_new_pipeline_id();
|
||||||
|
self.pending_pipeline_id.set(Some(new_pipeline_id));
|
||||||
let private_iframe = self.privatebrowsing();
|
let private_iframe = self.privatebrowsing();
|
||||||
let frame_type = if self.Mozbrowser() { FrameType::MozBrowserIFrame } else { FrameType::IFrame };
|
let frame_type = if self.Mozbrowser() { FrameType::MozBrowserIFrame } else { FrameType::IFrame };
|
||||||
|
|
||||||
|
@ -149,37 +159,41 @@ impl HTMLIFrameElement {
|
||||||
replace: replace,
|
replace: replace,
|
||||||
};
|
};
|
||||||
|
|
||||||
if load_data.as_ref().map_or(false, |d| d.url.as_str() == "about:blank") {
|
match nav_type {
|
||||||
let (pipeline_sender, pipeline_receiver) = ipc::channel().unwrap();
|
NavigationType::InitialAboutBlank => {
|
||||||
|
let (pipeline_sender, pipeline_receiver) = ipc::channel().unwrap();
|
||||||
|
|
||||||
global_scope
|
global_scope
|
||||||
.constellation_chan()
|
.constellation_chan()
|
||||||
.send(ConstellationMsg::ScriptLoadedAboutBlankInIFrame(load_info, pipeline_sender))
|
.send(ConstellationMsg::ScriptNewIFrame(load_info, pipeline_sender))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let new_layout_info = NewLayoutInfo {
|
let new_layout_info = NewLayoutInfo {
|
||||||
parent_info: Some((global_scope.pipeline_id(), frame_type)),
|
parent_info: Some((global_scope.pipeline_id(), frame_type)),
|
||||||
new_pipeline_id: new_pipeline_id,
|
new_pipeline_id: new_pipeline_id,
|
||||||
frame_id: self.frame_id,
|
frame_id: self.frame_id,
|
||||||
load_data: load_data.unwrap(),
|
load_data: load_data.unwrap(),
|
||||||
pipeline_port: pipeline_receiver,
|
pipeline_port: pipeline_receiver,
|
||||||
content_process_shutdown_chan: None,
|
content_process_shutdown_chan: None,
|
||||||
window_size: None,
|
window_size: None,
|
||||||
layout_threads: PREFS.get("layout.threads").as_u64().expect("count") as usize,
|
layout_threads: PREFS.get("layout.threads").as_u64().expect("count") as usize,
|
||||||
};
|
};
|
||||||
|
|
||||||
ScriptThread::process_attach_layout(new_layout_info, document.origin().clone());
|
self.pipeline_id.set(Some(new_pipeline_id));
|
||||||
} else {
|
ScriptThread::process_attach_layout(new_layout_info, document.origin().clone());
|
||||||
let load_info = IFrameLoadInfoWithData {
|
},
|
||||||
info: load_info,
|
NavigationType::Regular => {
|
||||||
load_data: load_data,
|
let load_info = IFrameLoadInfoWithData {
|
||||||
old_pipeline_id: old_pipeline_id,
|
info: load_info,
|
||||||
sandbox: sandboxed,
|
load_data: load_data,
|
||||||
};
|
old_pipeline_id: old_pipeline_id,
|
||||||
global_scope
|
sandbox: sandboxed,
|
||||||
|
};
|
||||||
|
global_scope
|
||||||
.constellation_chan()
|
.constellation_chan()
|
||||||
.send(ConstellationMsg::ScriptLoadedURLInIFrame(load_info))
|
.send(ConstellationMsg::ScriptLoadedURLInIFrame(load_info))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if PREFS.is_mozbrowser_enabled() {
|
if PREFS.is_mozbrowser_enabled() {
|
||||||
|
@ -192,9 +206,10 @@ impl HTMLIFrameElement {
|
||||||
fn process_the_iframe_attributes(&self, mode: ProcessingMode) {
|
fn process_the_iframe_attributes(&self, mode: ProcessingMode) {
|
||||||
// TODO: srcdoc
|
// TODO: srcdoc
|
||||||
|
|
||||||
|
let window = window_from_node(self);
|
||||||
|
|
||||||
// https://github.com/whatwg/html/issues/490
|
// https://github.com/whatwg/html/issues/490
|
||||||
if mode == ProcessingMode::FirstTime && !self.upcast::<Element>().has_attribute(&local_name!("src")) {
|
if mode == ProcessingMode::FirstTime && !self.upcast::<Element>().has_attribute(&local_name!("src")) {
|
||||||
let window = window_from_node(self);
|
|
||||||
let event_loop = window.dom_manipulation_task_source();
|
let event_loop = window.dom_manipulation_task_source();
|
||||||
let _ = event_loop.queue(box IFrameLoadEventSteps::new(self),
|
let _ = event_loop.queue(box IFrameLoadEventSteps::new(self),
|
||||||
window.upcast());
|
window.upcast());
|
||||||
|
@ -205,9 +220,15 @@ impl HTMLIFrameElement {
|
||||||
|
|
||||||
// TODO: check ancestor browsing contexts for same URL
|
// TODO: check ancestor browsing contexts for same URL
|
||||||
|
|
||||||
|
let creator_pipeline_id = if url.as_str() == "about:blank" {
|
||||||
|
Some(window.upcast::<GlobalScope>().pipeline_id())
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
|
||||||
let document = document_from_node(self);
|
let document = document_from_node(self);
|
||||||
self.navigate_or_reload_child_browsing_context(
|
let load_data = LoadData::new(url, creator_pipeline_id, document.get_referrer_policy(), Some(document.url()));
|
||||||
Some(LoadData::new(url, document.get_referrer_policy(), Some(document.url()))), false);
|
self.navigate_or_reload_child_browsing_context(Some(load_data), NavigationType::Regular, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(unsafe_code)]
|
#[allow(unsafe_code)]
|
||||||
|
@ -225,19 +246,30 @@ impl HTMLIFrameElement {
|
||||||
// Synchronously create a new context and navigate it to about:blank.
|
// Synchronously create a new context and navigate it to about:blank.
|
||||||
let url = ServoUrl::parse("about:blank").unwrap();
|
let url = ServoUrl::parse("about:blank").unwrap();
|
||||||
let document = document_from_node(self);
|
let document = document_from_node(self);
|
||||||
let load_data = LoadData::new(url,
|
let pipeline_id = Some(window_from_node(self).upcast::<GlobalScope>().pipeline_id());
|
||||||
document.get_referrer_policy(),
|
let load_data = LoadData::new(url, pipeline_id, document.get_referrer_policy(), Some(document.url().clone()));
|
||||||
Some(document.url().clone()));
|
self.navigate_or_reload_child_browsing_context(Some(load_data), NavigationType::InitialAboutBlank, false);
|
||||||
self.navigate_or_reload_child_browsing_context(Some(load_data), false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn update_pipeline_id(&self, new_pipeline_id: PipelineId) {
|
pub fn update_pipeline_id(&self, new_pipeline_id: PipelineId, reason: UpdatePipelineIdReason) {
|
||||||
|
if self.pending_pipeline_id.get() != Some(new_pipeline_id) && reason == UpdatePipelineIdReason::Navigation {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
self.pipeline_id.set(Some(new_pipeline_id));
|
self.pipeline_id.set(Some(new_pipeline_id));
|
||||||
|
|
||||||
let mut blocker = self.load_blocker.borrow_mut();
|
// Only terminate the load blocker if the pipeline id was updated due to a traversal.
|
||||||
LoadBlocker::terminate(&mut blocker);
|
// The load blocker will be terminated for a navigation in iframe_load_event_steps.
|
||||||
|
if reason == UpdatePipelineIdReason::Traversal {
|
||||||
|
let mut blocker = self.load_blocker.borrow_mut();
|
||||||
|
LoadBlocker::terminate(&mut blocker);
|
||||||
|
}
|
||||||
|
|
||||||
self.upcast::<Node>().dirty(NodeDamage::OtherNodeDamage);
|
self.upcast::<Node>().dirty(NodeDamage::OtherNodeDamage);
|
||||||
|
let window = window_from_node(self);
|
||||||
|
window.reflow(ReflowGoal::ForDisplay,
|
||||||
|
ReflowQueryType::NoQuery,
|
||||||
|
ReflowReason::FramedContentChanged);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn new_inherited(local_name: LocalName,
|
fn new_inherited(local_name: LocalName,
|
||||||
|
@ -247,6 +279,7 @@ impl HTMLIFrameElement {
|
||||||
htmlelement: HTMLElement::new_inherited(local_name, prefix, document),
|
htmlelement: HTMLElement::new_inherited(local_name, prefix, document),
|
||||||
frame_id: FrameId::new(),
|
frame_id: FrameId::new(),
|
||||||
pipeline_id: Cell::new(None),
|
pipeline_id: Cell::new(None),
|
||||||
|
pending_pipeline_id: Cell::new(None),
|
||||||
sandbox: Default::default(),
|
sandbox: Default::default(),
|
||||||
sandbox_allowance: Cell::new(None),
|
sandbox_allowance: Cell::new(None),
|
||||||
load_blocker: DOMRefCell::new(None),
|
load_blocker: DOMRefCell::new(None),
|
||||||
|
@ -296,7 +329,7 @@ impl HTMLIFrameElement {
|
||||||
pub fn iframe_load_event_steps(&self, loaded_pipeline: PipelineId) {
|
pub fn iframe_load_event_steps(&self, loaded_pipeline: PipelineId) {
|
||||||
// TODO(#9592): assert that the load blocker is present at all times when we
|
// TODO(#9592): assert that the load blocker is present at all times when we
|
||||||
// can guarantee that it's created for the case of iframe.reload().
|
// can guarantee that it's created for the case of iframe.reload().
|
||||||
if Some(loaded_pipeline) != self.pipeline_id() { return; }
|
if Some(loaded_pipeline) != self.pending_pipeline_id.get() { return; }
|
||||||
|
|
||||||
// TODO A cross-origin child document would not be easily accessible
|
// TODO A cross-origin child document would not be easily accessible
|
||||||
// from this script thread. It's unclear how to implement
|
// from this script thread. It's unclear how to implement
|
||||||
|
@ -330,7 +363,8 @@ impl HTMLIFrameElement {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait HTMLIFrameElementLayoutMethods {
|
pub trait HTMLIFrameElementLayoutMethods {
|
||||||
fn pipeline_id(self) -> Option<PipelineId>;
|
fn pipeline_id(&self) -> Option<PipelineId>;
|
||||||
|
fn frame_id(&self) -> FrameId;
|
||||||
fn get_width(&self) -> LengthOrPercentageOrAuto;
|
fn get_width(&self) -> LengthOrPercentageOrAuto;
|
||||||
fn get_height(&self) -> LengthOrPercentageOrAuto;
|
fn get_height(&self) -> LengthOrPercentageOrAuto;
|
||||||
}
|
}
|
||||||
|
@ -338,12 +372,21 @@ pub trait HTMLIFrameElementLayoutMethods {
|
||||||
impl HTMLIFrameElementLayoutMethods for LayoutJS<HTMLIFrameElement> {
|
impl HTMLIFrameElementLayoutMethods for LayoutJS<HTMLIFrameElement> {
|
||||||
#[inline]
|
#[inline]
|
||||||
#[allow(unsafe_code)]
|
#[allow(unsafe_code)]
|
||||||
fn pipeline_id(self) -> Option<PipelineId> {
|
fn pipeline_id(&self) -> Option<PipelineId> {
|
||||||
unsafe {
|
unsafe {
|
||||||
(*self.unsafe_get()).pipeline_id.get()
|
(*self.unsafe_get()).pipeline_id.get()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
#[allow(unsafe_code)]
|
||||||
|
fn frame_id(&self) -> FrameId {
|
||||||
|
unsafe {
|
||||||
|
(*self.unsafe_get()).frame_id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#[allow(unsafe_code)]
|
#[allow(unsafe_code)]
|
||||||
fn get_width(&self) -> LengthOrPercentageOrAuto {
|
fn get_width(&self) -> LengthOrPercentageOrAuto {
|
||||||
unsafe {
|
unsafe {
|
||||||
|
@ -563,7 +606,7 @@ impl HTMLIFrameElementMethods for HTMLIFrameElement {
|
||||||
fn Reload(&self, _hard_reload: bool) -> ErrorResult {
|
fn Reload(&self, _hard_reload: bool) -> ErrorResult {
|
||||||
if self.Mozbrowser() {
|
if self.Mozbrowser() {
|
||||||
if self.upcast::<Node>().is_in_doc_with_browsing_context() {
|
if self.upcast::<Node>().is_in_doc_with_browsing_context() {
|
||||||
self.navigate_or_reload_child_browsing_context(None, true);
|
self.navigate_or_reload_child_browsing_context(None, NavigationType::Regular, true);
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
|
@ -739,6 +782,7 @@ impl VirtualMethods for HTMLIFrameElement {
|
||||||
// a new iframe. Without this, the constellation gets very
|
// a new iframe. Without this, the constellation gets very
|
||||||
// confused.
|
// confused.
|
||||||
self.pipeline_id.set(None);
|
self.pipeline_id.set(None);
|
||||||
|
self.pending_pipeline_id.set(None);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -61,7 +61,7 @@ use heapsize::{HeapSizeOf, heap_size_of};
|
||||||
use html5ever::{Prefix, Namespace, QualName};
|
use html5ever::{Prefix, Namespace, QualName};
|
||||||
use js::jsapi::{JSContext, JSObject, JSRuntime};
|
use js::jsapi::{JSContext, JSObject, JSRuntime};
|
||||||
use libc::{self, c_void, uintptr_t};
|
use libc::{self, c_void, uintptr_t};
|
||||||
use msg::constellation_msg::PipelineId;
|
use msg::constellation_msg::{FrameId, PipelineId};
|
||||||
use ref_slice::ref_slice;
|
use ref_slice::ref_slice;
|
||||||
use script_layout_interface::{HTMLCanvasData, OpaqueStyleAndLayoutData, SVGSVGData};
|
use script_layout_interface::{HTMLCanvasData, OpaqueStyleAndLayoutData, SVGSVGData};
|
||||||
use script_layout_interface::{LayoutElementType, LayoutNodeType, TrustedNodeAddress};
|
use script_layout_interface::{LayoutElementType, LayoutNodeType, TrustedNodeAddress};
|
||||||
|
@ -970,6 +970,7 @@ pub trait LayoutNodeHelpers {
|
||||||
fn image_url(&self) -> Option<ServoUrl>;
|
fn image_url(&self) -> Option<ServoUrl>;
|
||||||
fn canvas_data(&self) -> Option<HTMLCanvasData>;
|
fn canvas_data(&self) -> Option<HTMLCanvasData>;
|
||||||
fn svg_data(&self) -> Option<SVGSVGData>;
|
fn svg_data(&self) -> Option<SVGSVGData>;
|
||||||
|
fn iframe_frame_id(&self) -> FrameId;
|
||||||
fn iframe_pipeline_id(&self) -> PipelineId;
|
fn iframe_pipeline_id(&self) -> PipelineId;
|
||||||
fn opaque(&self) -> OpaqueNode;
|
fn opaque(&self) -> OpaqueNode;
|
||||||
}
|
}
|
||||||
|
@ -1120,6 +1121,12 @@ impl LayoutNodeHelpers for LayoutJS<Node> {
|
||||||
.map(|svg| svg.data())
|
.map(|svg| svg.data())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn iframe_frame_id(&self) -> FrameId {
|
||||||
|
let iframe_element = self.downcast::<HTMLIFrameElement>()
|
||||||
|
.expect("not an iframe element!");
|
||||||
|
iframe_element.frame_id()
|
||||||
|
}
|
||||||
|
|
||||||
fn iframe_pipeline_id(&self) -> PipelineId {
|
fn iframe_pipeline_id(&self) -> PipelineId {
|
||||||
let iframe_element = self.downcast::<HTMLIFrameElement>()
|
let iframe_element = self.downcast::<HTMLIFrameElement>()
|
||||||
.expect("not an iframe element!");
|
.expect("not an iframe element!");
|
||||||
|
|
|
@ -1537,10 +1537,10 @@ impl Window {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let pipeline_id = self.upcast::<GlobalScope>().pipeline_id();
|
||||||
self.main_thread_script_chan().send(
|
self.main_thread_script_chan().send(
|
||||||
MainThreadScriptMsg::Navigate(self.upcast::<GlobalScope>().pipeline_id(),
|
MainThreadScriptMsg::Navigate(pipeline_id,
|
||||||
LoadData::new(url, referrer_policy, Some(doc.url())),
|
LoadData::new(url, Some(pipeline_id), referrer_policy, Some(doc.url())), replace)).unwrap();
|
||||||
replace)).unwrap();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn handle_fire_timer(&self, timer_id: TimerEventId) {
|
pub fn handle_fire_timer(&self, timer_id: TimerEventId) {
|
||||||
|
|
|
@ -44,7 +44,7 @@ use dom::node::{LayoutNodeHelpers, Node};
|
||||||
use dom::text::Text;
|
use dom::text::Text;
|
||||||
use gfx_traits::ByteIndex;
|
use gfx_traits::ByteIndex;
|
||||||
use html5ever::{LocalName, Namespace};
|
use html5ever::{LocalName, Namespace};
|
||||||
use msg::constellation_msg::PipelineId;
|
use msg::constellation_msg::{FrameId, PipelineId};
|
||||||
use range::Range;
|
use range::Range;
|
||||||
use script_layout_interface::{HTMLCanvasData, LayoutNodeType, SVGSVGData, TrustedNodeAddress};
|
use script_layout_interface::{HTMLCanvasData, LayoutNodeType, SVGSVGData, TrustedNodeAddress};
|
||||||
use script_layout_interface::{OpaqueStyleAndLayoutData, PartialPersistentLayoutData};
|
use script_layout_interface::{OpaqueStyleAndLayoutData, PartialPersistentLayoutData};
|
||||||
|
@ -908,6 +908,11 @@ impl<'ln> ThreadSafeLayoutNode for ServoThreadSafeLayoutNode<'ln> {
|
||||||
this.svg_data()
|
this.svg_data()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn iframe_frame_id(&self) -> FrameId {
|
||||||
|
let this = unsafe { self.get_jsmanaged() };
|
||||||
|
this.iframe_frame_id()
|
||||||
|
}
|
||||||
|
|
||||||
fn iframe_pipeline_id(&self) -> PipelineId {
|
fn iframe_pipeline_id(&self) -> PipelineId {
|
||||||
let this = unsafe { self.get_jsmanaged() };
|
let this = unsafe { self.get_jsmanaged() };
|
||||||
this.iframe_pipeline_id()
|
this.iframe_pipeline_id()
|
||||||
|
|
|
@ -46,7 +46,7 @@ use dom::element::Element;
|
||||||
use dom::event::{Event, EventBubbles, EventCancelable};
|
use dom::event::{Event, EventBubbles, EventCancelable};
|
||||||
use dom::globalscope::GlobalScope;
|
use dom::globalscope::GlobalScope;
|
||||||
use dom::htmlanchorelement::HTMLAnchorElement;
|
use dom::htmlanchorelement::HTMLAnchorElement;
|
||||||
use dom::htmliframeelement::HTMLIFrameElement;
|
use dom::htmliframeelement::{HTMLIFrameElement, NavigationType};
|
||||||
use dom::mutationobserver::MutationObserver;
|
use dom::mutationobserver::MutationObserver;
|
||||||
use dom::node::{Node, NodeDamage, window_from_node};
|
use dom::node::{Node, NodeDamage, window_from_node};
|
||||||
use dom::serviceworker::TrustedServiceWorkerAddress;
|
use dom::serviceworker::TrustedServiceWorkerAddress;
|
||||||
|
@ -87,7 +87,7 @@ use script_runtime::{ScriptPort, StackRootTLS, get_reports, new_rt_and_cx};
|
||||||
use script_traits::{CompositorEvent, ConstellationControlMsg};
|
use script_traits::{CompositorEvent, ConstellationControlMsg};
|
||||||
use script_traits::{DocumentActivity, DiscardBrowsingContext, EventResult};
|
use script_traits::{DocumentActivity, DiscardBrowsingContext, EventResult};
|
||||||
use script_traits::{InitialScriptState, LayoutMsg, LoadData, MouseButton, MouseEventType, MozBrowserEvent};
|
use script_traits::{InitialScriptState, LayoutMsg, LoadData, MouseButton, MouseEventType, MozBrowserEvent};
|
||||||
use script_traits::{NewLayoutInfo, ScriptMsg as ConstellationMsg};
|
use script_traits::{NewLayoutInfo, ScriptMsg as ConstellationMsg, UpdatePipelineIdReason};
|
||||||
use script_traits::{ScriptThreadFactory, TimerEvent, TimerSchedulerMsg, TimerSource};
|
use script_traits::{ScriptThreadFactory, TimerEvent, TimerSchedulerMsg, TimerSource};
|
||||||
use script_traits::{TouchEventType, TouchId, UntrustedNodeAddress, WindowSizeData, WindowSizeType};
|
use script_traits::{TouchEventType, TouchId, UntrustedNodeAddress, WindowSizeData, WindowSizeType};
|
||||||
use script_traits::CompositorEvent::{KeyEvent, MouseButtonEvent, MouseMoveEvent, ResizeEvent};
|
use script_traits::CompositorEvent::{KeyEvent, MouseButtonEvent, MouseMoveEvent, ResizeEvent};
|
||||||
|
@ -555,8 +555,8 @@ impl ScriptThreadFactory for ScriptThread {
|
||||||
let mut failsafe = ScriptMemoryFailsafe::new(&script_thread);
|
let mut failsafe = ScriptMemoryFailsafe::new(&script_thread);
|
||||||
|
|
||||||
let origin = MutableOrigin::new(load_data.url.origin());
|
let origin = MutableOrigin::new(load_data.url.origin());
|
||||||
let new_load = InProgressLoad::new(id, frame_id, parent_info, layout_chan, window_size,
|
let new_load = InProgressLoad::new(id, frame_id, parent_info,
|
||||||
load_data.url.clone(), origin);
|
layout_chan, window_size, load_data.url.clone(), origin);
|
||||||
script_thread.start_page_load(new_load, load_data);
|
script_thread.start_page_load(new_load, load_data);
|
||||||
|
|
||||||
let reporter_name = format!("script-reporter-{}", id);
|
let reporter_name = format!("script-reporter-{}", id);
|
||||||
|
@ -827,7 +827,22 @@ impl ScriptThread {
|
||||||
FromConstellation(ConstellationControlMsg::AttachLayout(
|
FromConstellation(ConstellationControlMsg::AttachLayout(
|
||||||
new_layout_info)) => {
|
new_layout_info)) => {
|
||||||
self.profile_event(ScriptThreadEventCategory::AttachLayout, || {
|
self.profile_event(ScriptThreadEventCategory::AttachLayout, || {
|
||||||
let origin = MutableOrigin::new(new_layout_info.load_data.url.origin());
|
// If this is an about:blank load, it must share the creator's origin.
|
||||||
|
// This must match the logic in the constellation when creating a new pipeline
|
||||||
|
let origin = if new_layout_info.load_data.url.as_str() != "about:blank" {
|
||||||
|
MutableOrigin::new(new_layout_info.load_data.url.origin())
|
||||||
|
} else if let Some(parent) = new_layout_info.parent_info
|
||||||
|
.and_then(|(pipeline_id, _)| self.documents.borrow()
|
||||||
|
.find_document(pipeline_id)) {
|
||||||
|
parent.origin().clone()
|
||||||
|
} else if let Some(creator) = new_layout_info.load_data.creator_pipeline_id
|
||||||
|
.and_then(|pipeline_id| self.documents.borrow()
|
||||||
|
.find_document(pipeline_id)) {
|
||||||
|
creator.origin().clone()
|
||||||
|
} else {
|
||||||
|
MutableOrigin::new(ImmutableOrigin::new_opaque())
|
||||||
|
};
|
||||||
|
|
||||||
self.handle_new_layout(new_layout_info, origin);
|
self.handle_new_layout(new_layout_info, origin);
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -1043,10 +1058,12 @@ impl ScriptThread {
|
||||||
event),
|
event),
|
||||||
ConstellationControlMsg::UpdatePipelineId(parent_pipeline_id,
|
ConstellationControlMsg::UpdatePipelineId(parent_pipeline_id,
|
||||||
frame_id,
|
frame_id,
|
||||||
new_pipeline_id) =>
|
new_pipeline_id,
|
||||||
|
reason) =>
|
||||||
self.handle_update_pipeline_id(parent_pipeline_id,
|
self.handle_update_pipeline_id(parent_pipeline_id,
|
||||||
frame_id,
|
frame_id,
|
||||||
new_pipeline_id),
|
new_pipeline_id,
|
||||||
|
reason),
|
||||||
ConstellationControlMsg::FocusIFrame(parent_pipeline_id, frame_id) =>
|
ConstellationControlMsg::FocusIFrame(parent_pipeline_id, frame_id) =>
|
||||||
self.handle_focus_iframe_msg(parent_pipeline_id, frame_id),
|
self.handle_focus_iframe_msg(parent_pipeline_id, frame_id),
|
||||||
ConstellationControlMsg::WebDriverScriptCommand(pipeline_id, msg) =>
|
ConstellationControlMsg::WebDriverScriptCommand(pipeline_id, msg) =>
|
||||||
|
@ -1062,8 +1079,6 @@ impl ScriptThread {
|
||||||
self.handle_frame_load_event(parent_id, frame_id, child_id),
|
self.handle_frame_load_event(parent_id, frame_id, child_id),
|
||||||
ConstellationControlMsg::DispatchStorageEvent(pipeline_id, storage, url, key, old_value, new_value) =>
|
ConstellationControlMsg::DispatchStorageEvent(pipeline_id, storage, url, key, old_value, new_value) =>
|
||||||
self.handle_storage_event(pipeline_id, storage, url, key, old_value, new_value),
|
self.handle_storage_event(pipeline_id, storage, url, key, old_value, new_value),
|
||||||
ConstellationControlMsg::FramedContentChanged(parent_pipeline_id, frame_id) =>
|
|
||||||
self.handle_framed_content_changed(parent_pipeline_id, frame_id),
|
|
||||||
ConstellationControlMsg::ReportCSSError(pipeline_id, filename, line, column, msg) =>
|
ConstellationControlMsg::ReportCSSError(pipeline_id, filename, line, column, msg) =>
|
||||||
self.handle_css_error_reporting(pipeline_id, filename, line, column, msg),
|
self.handle_css_error_reporting(pipeline_id, filename, line, column, msg),
|
||||||
ConstellationControlMsg::Reload(pipeline_id) =>
|
ConstellationControlMsg::Reload(pipeline_id) =>
|
||||||
|
@ -1399,20 +1414,6 @@ impl ScriptThread {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_framed_content_changed(&self,
|
|
||||||
parent_pipeline_id: PipelineId,
|
|
||||||
frame_id: FrameId) {
|
|
||||||
let doc = self.documents.borrow().find_document(parent_pipeline_id).unwrap();
|
|
||||||
let frame_element = doc.find_iframe(frame_id);
|
|
||||||
if let Some(ref frame_element) = frame_element {
|
|
||||||
frame_element.upcast::<Node>().dirty(NodeDamage::OtherNodeDamage);
|
|
||||||
let window = doc.window();
|
|
||||||
window.reflow(ReflowGoal::ForDisplay,
|
|
||||||
ReflowQueryType::NoQuery,
|
|
||||||
ReflowReason::FramedContentChanged);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn handle_post_message_msg(&self, pipeline_id: PipelineId, origin: Option<ImmutableOrigin>, data: Vec<u8>) {
|
fn handle_post_message_msg(&self, pipeline_id: PipelineId, origin: Option<ImmutableOrigin>, data: Vec<u8>) {
|
||||||
match { self.documents.borrow().find_window(pipeline_id) } {
|
match { self.documents.borrow().find_window(pipeline_id) } {
|
||||||
None => return warn!("postMessage after pipeline {} closed.", pipeline_id),
|
None => return warn!("postMessage after pipeline {} closed.", pipeline_id),
|
||||||
|
@ -1443,10 +1444,11 @@ impl ScriptThread {
|
||||||
fn handle_update_pipeline_id(&self,
|
fn handle_update_pipeline_id(&self,
|
||||||
parent_pipeline_id: PipelineId,
|
parent_pipeline_id: PipelineId,
|
||||||
frame_id: FrameId,
|
frame_id: FrameId,
|
||||||
new_pipeline_id: PipelineId) {
|
new_pipeline_id: PipelineId,
|
||||||
|
reason: UpdatePipelineIdReason) {
|
||||||
let frame_element = self.documents.borrow().find_iframe(parent_pipeline_id, frame_id);
|
let frame_element = self.documents.borrow().find_iframe(parent_pipeline_id, frame_id);
|
||||||
if let Some(frame_element) = frame_element {
|
if let Some(frame_element) = frame_element {
|
||||||
frame_element.update_pipeline_id(new_pipeline_id);
|
frame_element.update_pipeline_id(new_pipeline_id, reason);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2065,7 +2067,7 @@ impl ScriptThread {
|
||||||
Some(frame_id) => {
|
Some(frame_id) => {
|
||||||
let iframe = self.documents.borrow().find_iframe(parent_pipeline_id, frame_id);
|
let iframe = self.documents.borrow().find_iframe(parent_pipeline_id, frame_id);
|
||||||
if let Some(iframe) = iframe {
|
if let Some(iframe) = iframe {
|
||||||
iframe.navigate_or_reload_child_browsing_context(Some(load_data), replace);
|
iframe.navigate_or_reload_child_browsing_context(Some(load_data), NavigationType::Regular, replace);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
|
|
|
@ -11,7 +11,7 @@ use SVGSVGData;
|
||||||
use atomic_refcell::AtomicRefCell;
|
use atomic_refcell::AtomicRefCell;
|
||||||
use gfx_traits::{ByteIndex, FragmentType, combine_id_with_fragment_type};
|
use gfx_traits::{ByteIndex, FragmentType, combine_id_with_fragment_type};
|
||||||
use html5ever::{Namespace, LocalName};
|
use html5ever::{Namespace, LocalName};
|
||||||
use msg::constellation_msg::PipelineId;
|
use msg::constellation_msg::{FrameId, PipelineId};
|
||||||
use range::Range;
|
use range::Range;
|
||||||
use servo_url::ServoUrl;
|
use servo_url::ServoUrl;
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
|
@ -271,6 +271,10 @@ pub trait ThreadSafeLayoutNode: Clone + Copy + Debug + GetLayoutData + NodeInfo
|
||||||
|
|
||||||
fn svg_data(&self) -> Option<SVGSVGData>;
|
fn svg_data(&self) -> Option<SVGSVGData>;
|
||||||
|
|
||||||
|
/// If this node is an iframe element, returns its frame ID. If this node is
|
||||||
|
/// not an iframe element, fails.
|
||||||
|
fn iframe_frame_id(&self) -> FrameId;
|
||||||
|
|
||||||
/// If this node is an iframe element, returns its pipeline ID. If this node is
|
/// If this node is an iframe element, returns its pipeline ID. If this node is
|
||||||
/// not an iframe element, fails.
|
/// not an iframe element, fails.
|
||||||
fn iframe_pipeline_id(&self) -> PipelineId;
|
fn iframe_pipeline_id(&self) -> PipelineId;
|
||||||
|
|
|
@ -134,6 +134,8 @@ pub enum LayoutControlMsg {
|
||||||
pub struct LoadData {
|
pub struct LoadData {
|
||||||
/// The URL.
|
/// The URL.
|
||||||
pub url: ServoUrl,
|
pub url: ServoUrl,
|
||||||
|
/// The creator pipeline id if this is an about:blank load.
|
||||||
|
pub creator_pipeline_id: Option<PipelineId>,
|
||||||
/// The method.
|
/// The method.
|
||||||
#[serde(deserialize_with = "::hyper_serde::deserialize",
|
#[serde(deserialize_with = "::hyper_serde::deserialize",
|
||||||
serialize_with = "::hyper_serde::serialize")]
|
serialize_with = "::hyper_serde::serialize")]
|
||||||
|
@ -152,9 +154,14 @@ pub struct LoadData {
|
||||||
|
|
||||||
impl LoadData {
|
impl LoadData {
|
||||||
/// Create a new `LoadData` object.
|
/// Create a new `LoadData` object.
|
||||||
pub fn new(url: ServoUrl, referrer_policy: Option<ReferrerPolicy>, referrer_url: Option<ServoUrl>) -> LoadData {
|
pub fn new(url: ServoUrl,
|
||||||
|
creator_pipeline_id: Option<PipelineId>,
|
||||||
|
referrer_policy: Option<ReferrerPolicy>,
|
||||||
|
referrer_url: Option<ServoUrl>)
|
||||||
|
-> LoadData {
|
||||||
LoadData {
|
LoadData {
|
||||||
url: url,
|
url: url,
|
||||||
|
creator_pipeline_id: creator_pipeline_id,
|
||||||
method: Method::Get,
|
method: Method::Get,
|
||||||
headers: Headers::new(),
|
headers: Headers::new(),
|
||||||
data: None,
|
data: None,
|
||||||
|
@ -211,6 +218,15 @@ pub enum DocumentActivity {
|
||||||
FullyActive,
|
FullyActive,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The reason why the pipeline id of an iframe is being updated.
|
||||||
|
#[derive(Copy, Clone, PartialEq, Eq, Hash, HeapSizeOf, Debug, Deserialize, Serialize)]
|
||||||
|
pub enum UpdatePipelineIdReason {
|
||||||
|
/// The pipeline id is being updated due to a navigation.
|
||||||
|
Navigation,
|
||||||
|
/// The pipeline id is being updated due to a history traversal.
|
||||||
|
Traversal,
|
||||||
|
}
|
||||||
|
|
||||||
/// Messages sent from the constellation or layout to the script thread.
|
/// Messages sent from the constellation or layout to the script thread.
|
||||||
#[derive(Deserialize, Serialize)]
|
#[derive(Deserialize, Serialize)]
|
||||||
pub enum ConstellationControlMsg {
|
pub enum ConstellationControlMsg {
|
||||||
|
@ -249,7 +265,7 @@ pub enum ConstellationControlMsg {
|
||||||
MozBrowserEvent(PipelineId, Option<FrameId>, MozBrowserEvent),
|
MozBrowserEvent(PipelineId, Option<FrameId>, MozBrowserEvent),
|
||||||
/// Updates the current pipeline ID of a given iframe.
|
/// Updates the current pipeline ID of a given iframe.
|
||||||
/// First PipelineId is for the parent, second is the new PipelineId for the frame.
|
/// First PipelineId is for the parent, second is the new PipelineId for the frame.
|
||||||
UpdatePipelineId(PipelineId, FrameId, PipelineId),
|
UpdatePipelineId(PipelineId, FrameId, PipelineId, UpdatePipelineIdReason),
|
||||||
/// Set an iframe to be focused. Used when an element in an iframe gains focus.
|
/// Set an iframe to be focused. Used when an element in an iframe gains focus.
|
||||||
/// PipelineId is for the parent, FrameId is for the actual frame.
|
/// PipelineId is for the parent, FrameId is for the actual frame.
|
||||||
FocusIFrame(PipelineId, FrameId),
|
FocusIFrame(PipelineId, FrameId),
|
||||||
|
@ -274,9 +290,6 @@ pub enum ConstellationControlMsg {
|
||||||
/// Cause a `storage` event to be dispatched at the appropriate window.
|
/// Cause a `storage` event to be dispatched at the appropriate window.
|
||||||
/// The strings are key, old value and new value.
|
/// The strings are key, old value and new value.
|
||||||
DispatchStorageEvent(PipelineId, StorageType, ServoUrl, Option<String>, Option<String>, Option<String>),
|
DispatchStorageEvent(PipelineId, StorageType, ServoUrl, Option<String>, Option<String>, Option<String>),
|
||||||
/// Notifies a parent pipeline that one of its child frames is now active.
|
|
||||||
/// PipelineId is for the parent, FrameId is the child frame.
|
|
||||||
FramedContentChanged(PipelineId, FrameId),
|
|
||||||
/// Report an error from a CSS parser for the given pipeline
|
/// Report an error from a CSS parser for the given pipeline
|
||||||
ReportCSSError(PipelineId, String, usize, usize, String),
|
ReportCSSError(PipelineId, String, usize, usize, String),
|
||||||
/// Reload the given page.
|
/// Reload the given page.
|
||||||
|
@ -312,7 +325,6 @@ impl fmt::Debug for ConstellationControlMsg {
|
||||||
WebFontLoaded(..) => "WebFontLoaded",
|
WebFontLoaded(..) => "WebFontLoaded",
|
||||||
DispatchFrameLoadEvent { .. } => "DispatchFrameLoadEvent",
|
DispatchFrameLoadEvent { .. } => "DispatchFrameLoadEvent",
|
||||||
DispatchStorageEvent(..) => "DispatchStorageEvent",
|
DispatchStorageEvent(..) => "DispatchStorageEvent",
|
||||||
FramedContentChanged(..) => "FramedContentChanged",
|
|
||||||
ReportCSSError(..) => "ReportCSSError",
|
ReportCSSError(..) => "ReportCSSError",
|
||||||
Reload(..) => "Reload",
|
Reload(..) => "Reload",
|
||||||
WebVREvents(..) => "WebVREvents",
|
WebVREvents(..) => "WebVREvents",
|
||||||
|
|
|
@ -34,8 +34,8 @@ use webrender_traits::ClipId;
|
||||||
pub enum LayoutMsg {
|
pub enum LayoutMsg {
|
||||||
/// Indicates whether this pipeline is currently running animations.
|
/// Indicates whether this pipeline is currently running animations.
|
||||||
ChangeRunningAnimationsState(PipelineId, AnimationState),
|
ChangeRunningAnimationsState(PipelineId, AnimationState),
|
||||||
/// Inform the constellation of the size of the pipeline's viewport.
|
/// Inform the constellation of the size of the frame's viewport.
|
||||||
FrameSizes(Vec<(PipelineId, TypedSize2D<f32, CSSPixel>)>),
|
FrameSizes(Vec<(FrameId, TypedSize2D<f32, CSSPixel>)>),
|
||||||
/// Requests that the constellation inform the compositor of the a cursor change.
|
/// Requests that the constellation inform the compositor of the a cursor change.
|
||||||
SetCursor(Cursor),
|
SetCursor(Cursor),
|
||||||
/// Notifies the constellation that the viewport has been constrained in some manner
|
/// Notifies the constellation that the viewport has been constrained in some manner
|
||||||
|
@ -120,8 +120,8 @@ pub enum ScriptMsg {
|
||||||
VisibilityChangeComplete(PipelineId, bool),
|
VisibilityChangeComplete(PipelineId, bool),
|
||||||
/// A load has been requested in an IFrame.
|
/// A load has been requested in an IFrame.
|
||||||
ScriptLoadedURLInIFrame(IFrameLoadInfoWithData),
|
ScriptLoadedURLInIFrame(IFrameLoadInfoWithData),
|
||||||
/// A load of `about:blank` has been completed in an IFrame.
|
/// A load of the initial `about:blank` has been completed in an IFrame.
|
||||||
ScriptLoadedAboutBlankInIFrame(IFrameLoadInfo, IpcSender<LayoutControlMsg>),
|
ScriptNewIFrame(IFrameLoadInfo, IpcSender<LayoutControlMsg>),
|
||||||
/// Requests that the constellation set the contents of the clipboard
|
/// Requests that the constellation set the contents of the clipboard
|
||||||
SetClipboardContents(String),
|
SetClipboardContents(String),
|
||||||
/// Mark a new document as active
|
/// Mark a new document as active
|
||||||
|
|
|
@ -357,7 +357,7 @@ impl Handler {
|
||||||
|
|
||||||
let (sender, receiver) = ipc::channel().unwrap();
|
let (sender, receiver) = ipc::channel().unwrap();
|
||||||
|
|
||||||
let load_data = LoadData::new(url, None, None);
|
let load_data = LoadData::new(url, Some(pipeline_id), None, None);
|
||||||
let cmd_msg = WebDriverCommandMsg::LoadUrl(pipeline_id, load_data, sender.clone());
|
let cmd_msg = WebDriverCommandMsg::LoadUrl(pipeline_id, load_data, sender.clone());
|
||||||
self.constellation_chan.send(ConstellationMsg::WebDriverCommand(cmd_msg)).unwrap();
|
self.constellation_chan.send(ConstellationMsg::WebDriverCommand(cmd_msg)).unwrap();
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
[matchMedia.html]
|
[matchMedia.html]
|
||||||
|
disabled: true
|
||||||
type: testharness
|
type: testharness
|
||||||
[window.matchMedia exists]
|
[window.matchMedia exists]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue