aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--components/compositing/compositor.rs3
-rw-r--r--components/constellation/constellation.rs219
-rw-r--r--components/constellation/frame.rs12
-rw-r--r--components/constellation/pipeline.rs7
-rw-r--r--components/layout/display_list_builder.rs6
-rw-r--r--components/layout/fragment.rs10
-rw-r--r--components/msg/constellation_msg.rs1
-rwxr-xr-xcomponents/script/dom/htmlformelement.rs2
-rw-r--r--components/script/dom/htmliframeelement.rs134
-rw-r--r--components/script/dom/node.rs9
-rw-r--r--components/script/dom/window.rs6
-rw-r--r--components/script/layout_wrapper.rs7
-rw-r--r--components/script/script_thread.rs54
-rw-r--r--components/script_layout_interface/wrapper_traits.rs6
-rw-r--r--components/script_traits/lib.rs24
-rw-r--r--components/script_traits/script_msg.rs8
-rw-r--r--components/webdriver_server/lib.rs2
-rw-r--r--tests/wpt/mozilla/meta/css/matchMedia.html.ini1
18 files changed, 308 insertions, 203 deletions
diff --git a/components/compositing/compositor.rs b/components/compositing/compositor.rs
index eb2a964ac23..cbe8e31667e 100644
--- a/components/compositing/compositor.rs
+++ b/components/compositing/compositor.rs
@@ -903,7 +903,8 @@ impl<Window: WindowMethods> IOCompositor<Window> {
match ServoUrl::parse(&url_string) {
Ok(url) => {
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)
};
if let Err(e) = self.constellation_chan.send(msg) {
diff --git a/components/constellation/constellation.rs b/components/constellation/constellation.rs
index 731486c4e16..01a59070730 100644
--- a/components/constellation/constellation.rs
+++ b/components/constellation/constellation.rs
@@ -101,7 +101,7 @@ use script_traits::{IFrameLoadInfo, IFrameLoadInfoWithData, IFrameSandboxState,
use script_traits::{LayoutMsg as FromLayoutMsg, ScriptMsg as FromScriptMsg, ScriptThreadFactory};
use script_traits::{LogEntry, ServiceWorkerMsg, webdriver_msg};
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 servo_config::opts;
use servo_config::prefs::PREFS;
@@ -599,17 +599,31 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
let (event_loop, host) = match sandbox {
IFrameSandboxState::IFrameSandboxed => (None, None),
- IFrameSandboxState::IFrameUnsandboxed => match reg_host(&load_data.url) {
- None => (None, None),
- Some(host) => {
- let event_loop = self.event_loops.get(&top_level_frame_id)
- .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),
+ IFrameSandboxState::IFrameUnsandboxed => {
+ // If this is an about:blank load, it must share the creator's event loop.
+ // This must match the logic in the script thread when determining the proper origin.
+ if load_data.url.as_str() != "about:blank" {
+ match reg_host(&load_data.url) {
+ None => (None, None),
+ Some(host) => {
+ let event_loop = self.event_loops.get(&top_level_frame_id)
+ .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.
- 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);
self.frames.insert(frame_id, frame);
@@ -915,11 +932,11 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
load_info.info.new_pipeline_id);
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 {:?} {:?}",
load_info.parent_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) => {
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
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 pipeline_url = pipeline_id.and_then(|id| self.pipelines.get(&id).map(|pipeline| pipeline.url.clone()));
- let parent_info = pipeline_id.and_then(|id| self.pipelines.get(&id).and_then(|pipeline| pipeline.parent_info));
- let window_size = pipeline_id.and_then(|id| self.pipelines.get(&id).and_then(|pipeline| pipeline.size));
+ let (window_size, pipeline_id) = {
+ let frame = self.frames.get(&top_level_frame_id);
+ let window_size = frame.and_then(|frame| frame.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);
@@ -1295,7 +1321,7 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
warn!("creating replacement pipeline for about:failure");
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;
self.new_pipeline(new_pipeline_id, top_level_frame_id, parent_info,
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 root_pipeline_id = PipelineId::new();
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;
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);
@@ -1353,29 +1379,14 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
}
fn handle_frame_size_msg(&mut self,
- iframe_sizes: Vec<(PipelineId, TypedSize2D<f32, CSSPixel>)>) {
- for (pipeline_id, size) in iframe_sizes {
- let result = {
- let pipeline = match self.pipelines.get_mut(&pipeline_id) {
- Some(pipeline) => pipeline,
- 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)
+ iframe_sizes: Vec<(FrameId, TypedSize2D<f32, CSSPixel>)>) {
+ for (frame_id, size) in iframe_sizes {
+ let window_size = WindowSizeData {
+ initial_viewport: size,
+ device_pixel_ratio: self.window_size.device_pixel_ratio,
};
- 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)
- 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 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)
};
@@ -1456,9 +1467,9 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
is_private);
}
- fn handle_script_loaded_about_blank_in_iframe_msg(&mut self,
- load_info: IFrameLoadInfo,
- layout_sender: IpcSender<LayoutControlMsg>) {
+ fn handle_script_new_iframe(&mut self,
+ load_info: IFrameLoadInfo,
+ layout_sender: IpcSender<LayoutControlMsg>) {
let IFrameLoadInfo {
parent_pipeline_id,
new_pipeline_id,
@@ -1486,12 +1497,11 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
self.compositor_proxy.clone_compositor_proxy(),
is_private || parent_pipeline.is_private,
url.clone(),
- None,
parent_pipeline.visible)
};
// 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 {
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.
// 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 sandbox = IFrameSandboxState::IFrameUnsandboxed;
let replace_instant = if replace {
@@ -1959,7 +1969,7 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
},
WebDriverCommandMsg::Refresh(pipeline_id, reply) => {
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),
};
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 (parent_info, window_size, is_private) = match self.frames.get(&frame_id) {
Some(frame) => match self.pipelines.get(&frame.pipeline_id) {
- Some(pipeline) => (pipeline.parent_info, pipeline.size, pipeline.is_private),
- None => (None, None, false),
+ Some(pipeline) => (pipeline.parent_info, frame.size, pipeline.is_private),
+ None => (None, frame.size, false),
},
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.
// This makes things like contentDocument work correctly.
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) {
None => return warn!("Pipeline {:?} child traversed after closure.", parent_pipeline_id),
Some(pipeline) => pipeline.event_loop.send(msg),
@@ -2245,7 +2256,9 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
}
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.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((parent_pipeline_id, _)) = pipeline.parent_info {
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);
}
}
@@ -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) {
debug!("handle_window_size_msg: {:?}", new_size.initial_viewport.to_untyped());
- if let Some(frame) = self.frames.get(&self.root_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.parent_info.is_none() {
- let _ = pipeline.event_loop.send(ConstellationControlMsg::Resize(
- pipeline.id,
- new_size,
- size_type
- ));
- }
- }
+ let frame_id = self.root_frame_id;
+ self.resize_frame(new_size, size_type, frame_id);
if let Some(resize_channel) = self.webdriver.resize_channel.take() {
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
// *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.
- if let Some(size) = pipeline.size {
+ if let Some(size) = frame.size {
// If the rectangle for this pipeline is zero sized, it will
// never be painted. In this case, don't query the layout
// 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));
}
+ /// 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) {
let frame_ids: Vec<FrameId> = self.full_frame_tree_iter(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| {
let mut frame_tree = SendableFrameTree {
pipeline: pipeline.to_sendable(),
- size: pipeline.size,
+ size: frame.size,
children: vec!(),
};
diff --git a/components/constellation/frame.rs b/components/constellation/frame.rs
index 74aabee2de0..ac85c14d214 100644
--- a/components/constellation/frame.rs
+++ b/components/constellation/frame.rs
@@ -2,6 +2,7 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+use euclid::size::TypedSize2D;
use msg::constellation_msg::{FrameId, PipelineId};
use pipeline::Pipeline;
use script_traits::LoadData;
@@ -9,6 +10,7 @@ use std::collections::HashMap;
use std::iter::once;
use std::mem::replace;
use std::time::Instant;
+use style_traits::CSSPixel;
/// A frame in the frame tree.
/// Each frame is the constellation's view of a browsing context.
@@ -22,13 +24,16 @@ pub struct Frame {
/// The frame id.
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,
- /// The pipeline for the current session history entry
+ /// The pipeline for the current session history entry.
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,
/// The past session history, ordered chronologically.
@@ -44,6 +49,7 @@ impl Frame {
pub fn new(id: FrameId, pipeline_id: PipelineId, load_data: LoadData) -> Frame {
Frame {
id: id,
+ size: None,
pipeline_id: pipeline_id,
instant: Instant::now(),
load_data: load_data,
diff --git a/components/constellation/pipeline.rs b/components/constellation/pipeline.rs
index aa380a8e5c1..60401f4313c 100644
--- a/components/constellation/pipeline.rs
+++ b/components/constellation/pipeline.rs
@@ -76,10 +76,6 @@ pub struct Pipeline {
/// The title of the most recently-loaded page.
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
/// animations cause composites to be continually scheduled.
pub running_animations: bool,
@@ -291,7 +287,6 @@ impl Pipeline {
state.compositor_proxy,
state.is_private,
url,
- state.window_size,
state.prev_visibility.unwrap_or(true)))
}
@@ -305,7 +300,6 @@ impl Pipeline {
compositor_proxy: Box<CompositorProxy + 'static + Send>,
is_private: bool,
url: ServoUrl,
- size: Option<TypedSize2D<f32, CSSPixel>>,
visible: bool)
-> Pipeline {
let pipeline = Pipeline {
@@ -318,7 +312,6 @@ impl Pipeline {
url: url,
title: None,
children: vec!(),
- size: size,
running_animations: false,
visible: visible,
is_private: is_private,
diff --git a/components/layout/display_list_builder.rs b/components/layout/display_list_builder.rs
index 472a34529ca..5f9a783c896 100644
--- a/components/layout/display_list_builder.rs
+++ b/components/layout/display_list_builder.rs
@@ -34,7 +34,7 @@ use inline::{FIRST_FRAGMENT_OF_ELEMENT, InlineFlow, LAST_FRAGMENT_OF_ELEMENT};
use ipc_channel::ipc;
use list_item::ListItemFlow;
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_cache::UsePlaceholder;
use range::Range;
@@ -173,7 +173,7 @@ pub struct DisplayListBuildState<'a> {
/// Vector containing iframe sizes, used to inform the constellation about
/// 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
/// rendered region.
@@ -1809,7 +1809,7 @@ impl FragmentDisplayListBuilding for Fragment {
let size = Size2D::new(item.bounds().size.width.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);
}
diff --git a/components/layout/fragment.rs b/components/layout/fragment.rs
index 9f98ff318ec..c4dfefcc696 100644
--- a/components/layout/fragment.rs
+++ b/components/layout/fragment.rs
@@ -26,7 +26,7 @@ use ipc_channel::ipc::IpcSender;
use layout_debug;
use model::{self, IntrinsicISizes, IntrinsicISizesContribution, MaybeAuto, SizeConstraint};
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_cache::{ImageOrMetadataAvailable, UsePlaceholder};
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.
#[derive(Clone)]
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,
}
impl IframeFragmentInfo {
/// Creates the information specific to an iframe fragment.
pub fn new<N: ThreadSafeLayoutNode>(node: &N) -> IframeFragmentInfo {
+ let frame_id = node.iframe_frame_id();
let pipeline_id = node.iframe_pipeline_id();
IframeFragmentInfo {
+ frame_id: frame_id,
pipeline_id: pipeline_id,
}
}
diff --git a/components/msg/constellation_msg.rs b/components/msg/constellation_msg.rs
index 5b5110099f6..02d4157f20c 100644
--- a/components/msg/constellation_msg.rs
+++ b/components/msg/constellation_msg.rs
@@ -310,3 +310,4 @@ pub enum FrameType {
IFrame,
MozBrowserIFrame,
}
+
diff --git a/components/script/dom/htmlformelement.rs b/components/script/dom/htmlformelement.rs
index 4397364f68f..53867c755f8 100755
--- a/components/script/dom/htmlformelement.rs
+++ b/components/script/dom/htmlformelement.rs
@@ -345,7 +345,7 @@ impl HTMLFormElement {
let _target = submitter.target();
// 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
match (&*scheme, method) {
diff --git a/components/script/dom/htmliframeelement.rs b/components/script/dom/htmliframeelement.rs
index e1a7fb7c672..554dc82f7d3 100644
--- a/components/script/dom/htmliframeelement.rs
+++ b/components/script/dom/htmliframeelement.rs
@@ -44,7 +44,7 @@ use msg::constellation_msg::{FrameType, FrameId, PipelineId, TraversalDirection}
use net_traits::response::HttpsState;
use script_layout_interface::message::ReflowQueryType;
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::IFrameSandboxState::{IFrameSandboxed, IFrameUnsandboxed};
use servo_atoms::Atom;
@@ -70,6 +70,12 @@ bitflags! {
}
#[derive(PartialEq)]
+pub enum NavigationType {
+ InitialAboutBlank,
+ Regular,
+}
+
+#[derive(PartialEq)]
enum ProcessingMode {
FirstTime,
NotFirstTime,
@@ -80,6 +86,7 @@ pub struct HTMLIFrameElement {
htmlelement: HTMLElement,
frame_id: FrameId,
pipeline_id: Cell<Option<PipelineId>>,
+ pending_pipeline_id: Cell<Option<PipelineId>>,
sandbox: MutNullableJS<DOMTokenList>,
sandbox_allowance: Cell<Option<SandboxAllowance>>,
load_blocker: DOMRefCell<Option<LoadBlocker>>,
@@ -108,12 +115,14 @@ impl HTMLIFrameElement {
pub fn generate_new_pipeline_id(&self) -> (Option<PipelineId>, PipelineId) {
let old_pipeline_id = self.pipeline_id.get();
let new_pipeline_id = PipelineId::new();
- self.pipeline_id.set(Some(new_pipeline_id));
debug!("Frame {} created pipeline {}.", self.frame_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() {
IFrameSandboxed
} else {
@@ -136,6 +145,7 @@ impl HTMLIFrameElement {
let window = window_from_node(self);
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 frame_type = if self.Mozbrowser() { FrameType::MozBrowserIFrame } else { FrameType::IFrame };
@@ -149,37 +159,41 @@ impl HTMLIFrameElement {
replace: replace,
};
- if load_data.as_ref().map_or(false, |d| d.url.as_str() == "about:blank") {
- let (pipeline_sender, pipeline_receiver) = ipc::channel().unwrap();
-
- global_scope
- .constellation_chan()
- .send(ConstellationMsg::ScriptLoadedAboutBlankInIFrame(load_info, pipeline_sender))
- .unwrap();
-
- let new_layout_info = NewLayoutInfo {
- parent_info: Some((global_scope.pipeline_id(), frame_type)),
- new_pipeline_id: new_pipeline_id,
- frame_id: self.frame_id,
- load_data: load_data.unwrap(),
- pipeline_port: pipeline_receiver,
- content_process_shutdown_chan: None,
- window_size: None,
- layout_threads: PREFS.get("layout.threads").as_u64().expect("count") as usize,
- };
-
- ScriptThread::process_attach_layout(new_layout_info, document.origin().clone());
- } else {
- let load_info = IFrameLoadInfoWithData {
- info: load_info,
- load_data: load_data,
- old_pipeline_id: old_pipeline_id,
- sandbox: sandboxed,
- };
- global_scope
+ match nav_type {
+ NavigationType::InitialAboutBlank => {
+ let (pipeline_sender, pipeline_receiver) = ipc::channel().unwrap();
+
+ global_scope
+ .constellation_chan()
+ .send(ConstellationMsg::ScriptNewIFrame(load_info, pipeline_sender))
+ .unwrap();
+
+ let new_layout_info = NewLayoutInfo {
+ parent_info: Some((global_scope.pipeline_id(), frame_type)),
+ new_pipeline_id: new_pipeline_id,
+ frame_id: self.frame_id,
+ load_data: load_data.unwrap(),
+ pipeline_port: pipeline_receiver,
+ content_process_shutdown_chan: None,
+ window_size: None,
+ layout_threads: PREFS.get("layout.threads").as_u64().expect("count") as usize,
+ };
+
+ self.pipeline_id.set(Some(new_pipeline_id));
+ ScriptThread::process_attach_layout(new_layout_info, document.origin().clone());
+ },
+ NavigationType::Regular => {
+ let load_info = IFrameLoadInfoWithData {
+ info: load_info,
+ load_data: load_data,
+ old_pipeline_id: old_pipeline_id,
+ sandbox: sandboxed,
+ };
+ global_scope
.constellation_chan()
.send(ConstellationMsg::ScriptLoadedURLInIFrame(load_info))
.unwrap();
+ }
}
if PREFS.is_mozbrowser_enabled() {
@@ -192,9 +206,10 @@ impl HTMLIFrameElement {
fn process_the_iframe_attributes(&self, mode: ProcessingMode) {
// TODO: srcdoc
+ let window = window_from_node(self);
+
// https://github.com/whatwg/html/issues/490
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.queue(box IFrameLoadEventSteps::new(self),
window.upcast());
@@ -205,9 +220,15 @@ impl HTMLIFrameElement {
// 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);
- self.navigate_or_reload_child_browsing_context(
- Some(LoadData::new(url, document.get_referrer_policy(), Some(document.url()))), false);
+ let load_data = LoadData::new(url, creator_pipeline_id, document.get_referrer_policy(), Some(document.url()));
+ self.navigate_or_reload_child_browsing_context(Some(load_data), NavigationType::Regular, false);
}
#[allow(unsafe_code)]
@@ -225,19 +246,30 @@ impl HTMLIFrameElement {
// Synchronously create a new context and navigate it to about:blank.
let url = ServoUrl::parse("about:blank").unwrap();
let document = document_from_node(self);
- let load_data = LoadData::new(url,
- document.get_referrer_policy(),
- Some(document.url().clone()));
- self.navigate_or_reload_child_browsing_context(Some(load_data), false);
+ let pipeline_id = Some(window_from_node(self).upcast::<GlobalScope>().pipeline_id());
+ let load_data = LoadData::new(url, pipeline_id, document.get_referrer_policy(), Some(document.url().clone()));
+ self.navigate_or_reload_child_browsing_context(Some(load_data), NavigationType::InitialAboutBlank, 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));
- let mut blocker = self.load_blocker.borrow_mut();
- LoadBlocker::terminate(&mut blocker);
+ // Only terminate the load blocker if the pipeline id was updated due to a traversal.
+ // 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);
+ let window = window_from_node(self);
+ window.reflow(ReflowGoal::ForDisplay,
+ ReflowQueryType::NoQuery,
+ ReflowReason::FramedContentChanged);
}
fn new_inherited(local_name: LocalName,
@@ -247,6 +279,7 @@ impl HTMLIFrameElement {
htmlelement: HTMLElement::new_inherited(local_name, prefix, document),
frame_id: FrameId::new(),
pipeline_id: Cell::new(None),
+ pending_pipeline_id: Cell::new(None),
sandbox: Default::default(),
sandbox_allowance: Cell::new(None),
load_blocker: DOMRefCell::new(None),
@@ -296,7 +329,7 @@ impl HTMLIFrameElement {
pub fn iframe_load_event_steps(&self, loaded_pipeline: PipelineId) {
// 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().
- 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
// from this script thread. It's unclear how to implement
@@ -330,7 +363,8 @@ impl HTMLIFrameElement {
}
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_height(&self) -> LengthOrPercentageOrAuto;
}
@@ -338,12 +372,21 @@ pub trait HTMLIFrameElementLayoutMethods {
impl HTMLIFrameElementLayoutMethods for LayoutJS<HTMLIFrameElement> {
#[inline]
#[allow(unsafe_code)]
- fn pipeline_id(self) -> Option<PipelineId> {
+ fn pipeline_id(&self) -> Option<PipelineId> {
unsafe {
(*self.unsafe_get()).pipeline_id.get()
}
}
+ #[inline]
+ #[allow(unsafe_code)]
+ fn frame_id(&self) -> FrameId {
+ unsafe {
+ (*self.unsafe_get()).frame_id
+ }
+ }
+
+
#[allow(unsafe_code)]
fn get_width(&self) -> LengthOrPercentageOrAuto {
unsafe {
@@ -563,7 +606,7 @@ impl HTMLIFrameElementMethods for HTMLIFrameElement {
fn Reload(&self, _hard_reload: bool) -> ErrorResult {
if self.Mozbrowser() {
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(())
} else {
@@ -739,6 +782,7 @@ impl VirtualMethods for HTMLIFrameElement {
// a new iframe. Without this, the constellation gets very
// confused.
self.pipeline_id.set(None);
+ self.pending_pipeline_id.set(None);
}
}
diff --git a/components/script/dom/node.rs b/components/script/dom/node.rs
index 31e48b5b695..81a06850757 100644
--- a/components/script/dom/node.rs
+++ b/components/script/dom/node.rs
@@ -61,7 +61,7 @@ use heapsize::{HeapSizeOf, heap_size_of};
use html5ever::{Prefix, Namespace, QualName};
use js::jsapi::{JSContext, JSObject, JSRuntime};
use libc::{self, c_void, uintptr_t};
-use msg::constellation_msg::PipelineId;
+use msg::constellation_msg::{FrameId, PipelineId};
use ref_slice::ref_slice;
use script_layout_interface::{HTMLCanvasData, OpaqueStyleAndLayoutData, SVGSVGData};
use script_layout_interface::{LayoutElementType, LayoutNodeType, TrustedNodeAddress};
@@ -970,6 +970,7 @@ pub trait LayoutNodeHelpers {
fn image_url(&self) -> Option<ServoUrl>;
fn canvas_data(&self) -> Option<HTMLCanvasData>;
fn svg_data(&self) -> Option<SVGSVGData>;
+ fn iframe_frame_id(&self) -> FrameId;
fn iframe_pipeline_id(&self) -> PipelineId;
fn opaque(&self) -> OpaqueNode;
}
@@ -1120,6 +1121,12 @@ impl LayoutNodeHelpers for LayoutJS<Node> {
.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 {
let iframe_element = self.downcast::<HTMLIFrameElement>()
.expect("not an iframe element!");
diff --git a/components/script/dom/window.rs b/components/script/dom/window.rs
index 6b8857b81b1..137f82cfab8 100644
--- a/components/script/dom/window.rs
+++ b/components/script/dom/window.rs
@@ -1537,10 +1537,10 @@ impl Window {
}
}
+ let pipeline_id = self.upcast::<GlobalScope>().pipeline_id();
self.main_thread_script_chan().send(
- MainThreadScriptMsg::Navigate(self.upcast::<GlobalScope>().pipeline_id(),
- LoadData::new(url, referrer_policy, Some(doc.url())),
- replace)).unwrap();
+ MainThreadScriptMsg::Navigate(pipeline_id,
+ LoadData::new(url, Some(pipeline_id), referrer_policy, Some(doc.url())), replace)).unwrap();
}
pub fn handle_fire_timer(&self, timer_id: TimerEventId) {
diff --git a/components/script/layout_wrapper.rs b/components/script/layout_wrapper.rs
index 7ae6a7e621e..278856c67f3 100644
--- a/components/script/layout_wrapper.rs
+++ b/components/script/layout_wrapper.rs
@@ -44,7 +44,7 @@ use dom::node::{LayoutNodeHelpers, Node};
use dom::text::Text;
use gfx_traits::ByteIndex;
use html5ever::{LocalName, Namespace};
-use msg::constellation_msg::PipelineId;
+use msg::constellation_msg::{FrameId, PipelineId};
use range::Range;
use script_layout_interface::{HTMLCanvasData, LayoutNodeType, SVGSVGData, TrustedNodeAddress};
use script_layout_interface::{OpaqueStyleAndLayoutData, PartialPersistentLayoutData};
@@ -908,6 +908,11 @@ impl<'ln> ThreadSafeLayoutNode for ServoThreadSafeLayoutNode<'ln> {
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 {
let this = unsafe { self.get_jsmanaged() };
this.iframe_pipeline_id()
diff --git a/components/script/script_thread.rs b/components/script/script_thread.rs
index 96167cec236..2f065a90d91 100644
--- a/components/script/script_thread.rs
+++ b/components/script/script_thread.rs
@@ -46,7 +46,7 @@ use dom::element::Element;
use dom::event::{Event, EventBubbles, EventCancelable};
use dom::globalscope::GlobalScope;
use dom::htmlanchorelement::HTMLAnchorElement;
-use dom::htmliframeelement::HTMLIFrameElement;
+use dom::htmliframeelement::{HTMLIFrameElement, NavigationType};
use dom::mutationobserver::MutationObserver;
use dom::node::{Node, NodeDamage, window_from_node};
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::{DocumentActivity, DiscardBrowsingContext, EventResult};
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::{TouchEventType, TouchId, UntrustedNodeAddress, WindowSizeData, WindowSizeType};
use script_traits::CompositorEvent::{KeyEvent, MouseButtonEvent, MouseMoveEvent, ResizeEvent};
@@ -555,8 +555,8 @@ impl ScriptThreadFactory for ScriptThread {
let mut failsafe = ScriptMemoryFailsafe::new(&script_thread);
let origin = MutableOrigin::new(load_data.url.origin());
- let new_load = InProgressLoad::new(id, frame_id, parent_info, layout_chan, window_size,
- load_data.url.clone(), origin);
+ let new_load = InProgressLoad::new(id, frame_id, parent_info,
+ layout_chan, window_size, load_data.url.clone(), origin);
script_thread.start_page_load(new_load, load_data);
let reporter_name = format!("script-reporter-{}", id);
@@ -827,7 +827,22 @@ impl ScriptThread {
FromConstellation(ConstellationControlMsg::AttachLayout(
new_layout_info)) => {
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);
})
}
@@ -1043,10 +1058,12 @@ impl ScriptThread {
event),
ConstellationControlMsg::UpdatePipelineId(parent_pipeline_id,
frame_id,
- new_pipeline_id) =>
+ new_pipeline_id,
+ reason) =>
self.handle_update_pipeline_id(parent_pipeline_id,
frame_id,
- new_pipeline_id),
+ new_pipeline_id,
+ reason),
ConstellationControlMsg::FocusIFrame(parent_pipeline_id, frame_id) =>
self.handle_focus_iframe_msg(parent_pipeline_id, frame_id),
ConstellationControlMsg::WebDriverScriptCommand(pipeline_id, msg) =>
@@ -1062,8 +1079,6 @@ impl ScriptThread {
self.handle_frame_load_event(parent_id, frame_id, child_id),
ConstellationControlMsg::DispatchStorageEvent(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) =>
self.handle_css_error_reporting(pipeline_id, filename, line, column, msg),
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>) {
match { self.documents.borrow().find_window(pipeline_id) } {
None => return warn!("postMessage after pipeline {} closed.", pipeline_id),
@@ -1443,10 +1444,11 @@ impl ScriptThread {
fn handle_update_pipeline_id(&self,
parent_pipeline_id: PipelineId,
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);
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) => {
let iframe = self.documents.borrow().find_iframe(parent_pipeline_id, frame_id);
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 => {
diff --git a/components/script_layout_interface/wrapper_traits.rs b/components/script_layout_interface/wrapper_traits.rs
index e39d27614c5..80b05a285b7 100644
--- a/components/script_layout_interface/wrapper_traits.rs
+++ b/components/script_layout_interface/wrapper_traits.rs
@@ -11,7 +11,7 @@ use SVGSVGData;
use atomic_refcell::AtomicRefCell;
use gfx_traits::{ByteIndex, FragmentType, combine_id_with_fragment_type};
use html5ever::{Namespace, LocalName};
-use msg::constellation_msg::PipelineId;
+use msg::constellation_msg::{FrameId, PipelineId};
use range::Range;
use servo_url::ServoUrl;
use std::fmt::Debug;
@@ -271,6 +271,10 @@ pub trait ThreadSafeLayoutNode: Clone + Copy + Debug + GetLayoutData + NodeInfo
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
/// not an iframe element, fails.
fn iframe_pipeline_id(&self) -> PipelineId;
diff --git a/components/script_traits/lib.rs b/components/script_traits/lib.rs
index 954c1386fa2..29baf8821e6 100644
--- a/components/script_traits/lib.rs
+++ b/components/script_traits/lib.rs
@@ -134,6 +134,8 @@ pub enum LayoutControlMsg {
pub struct LoadData {
/// The URL.
pub url: ServoUrl,
+ /// The creator pipeline id if this is an about:blank load.
+ pub creator_pipeline_id: Option<PipelineId>,
/// The method.
#[serde(deserialize_with = "::hyper_serde::deserialize",
serialize_with = "::hyper_serde::serialize")]
@@ -152,9 +154,14 @@ pub struct LoadData {
impl LoadData {
/// 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 {
url: url,
+ creator_pipeline_id: creator_pipeline_id,
method: Method::Get,
headers: Headers::new(),
data: None,
@@ -211,6 +218,15 @@ pub enum DocumentActivity {
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.
#[derive(Deserialize, Serialize)]
pub enum ConstellationControlMsg {
@@ -249,7 +265,7 @@ pub enum ConstellationControlMsg {
MozBrowserEvent(PipelineId, Option<FrameId>, MozBrowserEvent),
/// Updates the current pipeline ID of a given iframe.
/// 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.
/// PipelineId is for the parent, FrameId is for the actual frame.
FocusIFrame(PipelineId, FrameId),
@@ -274,9 +290,6 @@ pub enum ConstellationControlMsg {
/// Cause a `storage` event to be dispatched at the appropriate window.
/// The strings are key, old value and new value.
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
ReportCSSError(PipelineId, String, usize, usize, String),
/// Reload the given page.
@@ -312,7 +325,6 @@ impl fmt::Debug for ConstellationControlMsg {
WebFontLoaded(..) => "WebFontLoaded",
DispatchFrameLoadEvent { .. } => "DispatchFrameLoadEvent",
DispatchStorageEvent(..) => "DispatchStorageEvent",
- FramedContentChanged(..) => "FramedContentChanged",
ReportCSSError(..) => "ReportCSSError",
Reload(..) => "Reload",
WebVREvents(..) => "WebVREvents",
diff --git a/components/script_traits/script_msg.rs b/components/script_traits/script_msg.rs
index 47a7b103c8c..0402e3ddad6 100644
--- a/components/script_traits/script_msg.rs
+++ b/components/script_traits/script_msg.rs
@@ -34,8 +34,8 @@ use webrender_traits::ClipId;
pub enum LayoutMsg {
/// Indicates whether this pipeline is currently running animations.
ChangeRunningAnimationsState(PipelineId, AnimationState),
- /// Inform the constellation of the size of the pipeline's viewport.
- FrameSizes(Vec<(PipelineId, TypedSize2D<f32, CSSPixel>)>),
+ /// Inform the constellation of the size of the frame's viewport.
+ FrameSizes(Vec<(FrameId, TypedSize2D<f32, CSSPixel>)>),
/// Requests that the constellation inform the compositor of the a cursor change.
SetCursor(Cursor),
/// Notifies the constellation that the viewport has been constrained in some manner
@@ -120,8 +120,8 @@ pub enum ScriptMsg {
VisibilityChangeComplete(PipelineId, bool),
/// A load has been requested in an IFrame.
ScriptLoadedURLInIFrame(IFrameLoadInfoWithData),
- /// A load of `about:blank` has been completed in an IFrame.
- ScriptLoadedAboutBlankInIFrame(IFrameLoadInfo, IpcSender<LayoutControlMsg>),
+ /// A load of the initial `about:blank` has been completed in an IFrame.
+ ScriptNewIFrame(IFrameLoadInfo, IpcSender<LayoutControlMsg>),
/// Requests that the constellation set the contents of the clipboard
SetClipboardContents(String),
/// Mark a new document as active
diff --git a/components/webdriver_server/lib.rs b/components/webdriver_server/lib.rs
index 210c5b0f9c8..250ad21813b 100644
--- a/components/webdriver_server/lib.rs
+++ b/components/webdriver_server/lib.rs
@@ -357,7 +357,7 @@ impl Handler {
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());
self.constellation_chan.send(ConstellationMsg::WebDriverCommand(cmd_msg)).unwrap();
diff --git a/tests/wpt/mozilla/meta/css/matchMedia.html.ini b/tests/wpt/mozilla/meta/css/matchMedia.html.ini
index 8c726be5a03..dded0e3276d 100644
--- a/tests/wpt/mozilla/meta/css/matchMedia.html.ini
+++ b/tests/wpt/mozilla/meta/css/matchMedia.html.ini
@@ -1,4 +1,5 @@
[matchMedia.html]
+ disabled: true
type: testharness
[window.matchMedia exists]
expected: FAIL