auto merge of #5205 : glennw/servo/iframe-nav, r=jdm

The history is now recorded per frame, but needs to be exposed in a followup PR.
This commit is contained in:
bors-servo 2015-03-16 17:54:50 -06:00
commit 1092ca1019
11 changed files with 587 additions and 921 deletions

View file

@ -291,18 +291,6 @@ impl<Window: WindowMethods> IOCompositor<Window> {
self.get_title_for_main_frame();
}
(Msg::ChangeLayerPipelineAndRemoveChildren(old_pipeline, new_pipeline, response_channel),
ShutdownState::NotShuttingDown) => {
self.handle_change_layer_pipeline_and_remove_children(old_pipeline, new_pipeline);
response_channel.send(()).unwrap();
}
(Msg::CreateRootLayerForPipeline(parent_pipeline, pipeline, rect, response_channel),
ShutdownState::NotShuttingDown) => {
self.handle_create_root_layer_for_pipeline(parent_pipeline, pipeline, rect);
response_channel.send(()).unwrap();
}
(Msg::CreateOrUpdateBaseLayer(layer_properties), ShutdownState::NotShuttingDown) => {
self.create_or_update_base_layer(layer_properties);
}
@ -554,62 +542,11 @@ impl<Window: WindowMethods> IOCompositor<Window> {
let root_layer = self.create_root_layer_for_pipeline_and_rect(&frame_tree.pipeline,
frame_rect);
for kid in frame_tree.children.iter() {
root_layer.add_child(self.create_frame_tree_root_layers(&kid.frame_tree, kid.rect));
root_layer.add_child(self.create_frame_tree_root_layers(kid, kid.rect));
}
return root_layer;
}
fn handle_change_layer_pipeline_and_remove_children(&mut self,
old_pipeline: CompositionPipeline,
new_pipeline: CompositionPipeline) {
let root_layer = match self.find_pipeline_root_layer(old_pipeline.id) {
Some(root_layer) => root_layer,
None => {
debug!("Ignoring ChangeLayerPipelineAndRemoveChildren message \
for pipeline ({:?}) shutting down.",
old_pipeline.id);
return;
}
};
root_layer.clear_all_tiles(self);
root_layer.children().clear();
debug_assert!(root_layer.extra_data.borrow().pipeline_id == old_pipeline.id);
root_layer.extra_data.borrow_mut().pipeline_id = new_pipeline.id;
let new_pipeline_id = new_pipeline.id;
self.get_or_create_pipeline_details(new_pipeline_id).pipeline = Some(new_pipeline);
}
fn handle_create_root_layer_for_pipeline(&mut self,
parent_pipeline: CompositionPipeline,
new_pipeline: CompositionPipeline,
frame_rect: Option<TypedRect<PagePx, f32>>) {
let root_layer = self.create_root_layer_for_pipeline_and_rect(&new_pipeline, frame_rect);
match frame_rect {
Some(ref frame_rect) => {
*root_layer.masks_to_bounds.borrow_mut() = true;
let frame_rect = frame_rect.to_untyped();
*root_layer.bounds.borrow_mut() = Rect::from_untyped(&frame_rect);
}
None => {}
}
let pipeline_id = parent_pipeline.id;
let parent_layer = match self.find_pipeline_root_layer(pipeline_id) {
Some(root_layer) => root_layer,
None => {
debug!("Ignoring FrameTreeUpdate message for pipeline ({:?}) \
shutting down.",
pipeline_id);
return;
}
};
parent_layer.add_child(root_layer);
}
fn find_pipeline_root_layer(&self, pipeline_id: PipelineId) -> Option<Rc<Layer<CompositorData>>> {
if !self.pipeline_details.contains_key(&pipeline_id) {
panic!("Tried to create or update layer for unknown pipeline")

View file

@ -13,18 +13,16 @@ use windowing::{WindowEvent, WindowMethods};
use azure::azure_hl::{SourceSurfaceMethods, Color};
use geom::point::Point2D;
use geom::rect::{Rect, TypedRect};
use geom::rect::Rect;
use geom::size::Size2D;
use layers::platform::surface::{NativeCompositingGraphicsContext, NativeGraphicsMetadata};
use layers::layers::LayerBufferSet;
use pipeline::CompositionPipeline;
use msg::compositor_msg::{Epoch, LayerId, LayerMetadata, ReadyState};
use msg::compositor_msg::{PaintListener, PaintState, ScriptListener, ScrollPolicy};
use msg::constellation_msg::{ConstellationChan, PipelineId};
use msg::constellation_msg::{Key, KeyState, KeyModifiers};
use url::Url;
use util::cursor::Cursor;
use util::geometry::PagePx;
use util::memory::MemoryProfilerChan;
use util::time::TimeProfilerChan;
use std::sync::mpsc::{channel, Sender, Receiver};
@ -207,10 +205,6 @@ pub enum Msg {
PaintMsgDiscarded,
/// Replaces the current frame tree, typically called during main frame navigation.
SetFrameTree(SendableFrameTree, Sender<()>, ConstellationChan),
/// Requests the compositor to create a root layer for a new frame.
CreateRootLayerForPipeline(CompositionPipeline, CompositionPipeline, Option<TypedRect<PagePx, f32>>, Sender<()>),
/// Requests the compositor to change a root layer's pipeline and remove all child layers.
ChangeLayerPipelineAndRemoveChildren(CompositionPipeline, CompositionPipeline, Sender<()>),
/// The load of a page has completed.
LoadComplete,
/// Indicates that the scrolling timeout with the given starting timestamp has happened and a
@ -241,8 +235,6 @@ impl Debug for Msg {
Msg::ChangePageUrl(..) => write!(f, "ChangePageUrl"),
Msg::PaintMsgDiscarded(..) => write!(f, "PaintMsgDiscarded"),
Msg::SetFrameTree(..) => write!(f, "SetFrameTree"),
Msg::CreateRootLayerForPipeline(..) => write!(f, "CreateRootLayerForPipeline"),
Msg::ChangeLayerPipelineAndRemoveChildren(..) => write!(f, "ChangeLayerPipelineAndRemoveChildren"),
Msg::LoadComplete => write!(f, "LoadComplete"),
Msg::ScrollTimeout(..) => write!(f, "ScrollTimeout"),
Msg::KeyEvent(..) => write!(f, "KeyEvent"),

File diff suppressed because it is too large Load diff

View file

@ -90,14 +90,6 @@ impl CompositorEventListener for NullCompositor {
response_chan.send(()).unwrap();
}
Msg::ChangeLayerPipelineAndRemoveChildren(_, _, response_channel) => {
response_channel.send(()).unwrap();
}
Msg::CreateRootLayerForPipeline(_, _, _, response_channel) => {
response_channel.send(()).unwrap();
}
// Explicitly list ignored messages so that when we add a new one,
// we'll notice and think about whether it needs a response, like
// SetFrameTree.

View file

@ -8,23 +8,24 @@ use script_traits::{ScriptControlChan, ScriptTaskFactory};
use script_traits::{NewLayoutInfo, ConstellationControlMsg};
use devtools_traits::DevtoolsControlChan;
use geom::rect::{TypedRect};
use gfx::paint_task::Msg as PaintMsg;
use gfx::paint_task::{PaintChan, PaintTask};
use gfx::font_cache_task::FontCacheTask;
use msg::constellation_msg::{ConstellationChan, Failure, PipelineId, SubpageId};
use msg::constellation_msg::{ConstellationChan, Failure, FrameId, PipelineId, SubpageId};
use msg::constellation_msg::{LoadData, WindowSizeData, PipelineExitType};
use net::image_cache_task::ImageCacheTask;
use net::resource_task::ResourceTask;
use net::storage_task::StorageTask;
use url::Url;
use util::geometry::{PagePx};
use util::time::TimeProfilerChan;
use std::rc::Rc;
use std::sync::mpsc::{Receiver, channel};
/// A uniquely-identifiable pipeline of script task, layout task, and paint task.
pub struct Pipeline {
pub id: PipelineId,
pub parent: Option<(PipelineId, SubpageId)>,
pub parent_info: Option<(PipelineId, SubpageId)>,
pub script_chan: ScriptControlChan,
pub layout_chan: LayoutControlChan,
pub paint_chan: PaintChan,
@ -34,6 +35,8 @@ pub struct Pipeline {
pub url: Url,
/// The title of the most recently-loaded page.
pub title: Option<String>,
pub rect: Option<TypedRect<PagePx, f32>>,
pub children: Vec<FrameId>,
}
/// The subset of the pipeline that is needed for layer composition.
@ -49,7 +52,7 @@ impl Pipeline {
/// Returns the channels wrapped in a struct.
/// If script_pipeline is not None, then subpage_id must also be not None.
pub fn create<LTF,STF>(id: PipelineId,
parent: Option<(PipelineId, SubpageId)>,
parent_info: Option<(PipelineId, SubpageId)>,
constellation_chan: ConstellationChan,
compositor_proxy: Box<CompositorProxy+'static+Send>,
devtools_chan: Option<DevtoolsControlChan>,
@ -58,8 +61,8 @@ impl Pipeline {
resource_task: ResourceTask,
storage_task: StorageTask,
time_profiler_chan: TimeProfilerChan,
window_size: WindowSizeData,
script_pipeline: Option<Rc<Pipeline>>,
window_size: Option<WindowSizeData>,
script_chan: Option<ScriptControlChan>,
load_data: LoadData)
-> Pipeline
where LTF: LayoutTaskFactory, STF:ScriptTaskFactory {
@ -71,10 +74,10 @@ impl Pipeline {
let failure = Failure {
pipeline_id: id,
parent: parent,
parent_info: parent_info,
};
let script_chan = match script_pipeline {
let script_chan = match script_chan {
None => {
let (script_chan, script_port) = channel();
ScriptTaskFactory::create(None::<&mut STF>,
@ -93,18 +96,19 @@ impl Pipeline {
load_data.clone());
ScriptControlChan(script_chan)
}
Some(spipe) => {
Some(script_chan) => {
let (containing_pipeline_id, subpage_id) = parent_info.expect("script_pipeline != None but subpage_id == None");
let new_layout_info = NewLayoutInfo {
old_pipeline_id: spipe.id.clone(),
containing_pipeline_id: containing_pipeline_id,
new_pipeline_id: id,
subpage_id: parent.expect("script_pipeline != None but subpage_id == None").1,
subpage_id: subpage_id,
layout_chan: ScriptTaskFactory::clone_layout_channel(None::<&mut STF>, &layout_pair),
load_data: load_data.clone(),
};
let ScriptControlChan(ref chan) = spipe.script_chan;
let ScriptControlChan(ref chan) = script_chan;
chan.send(ConstellationControlMsg::AttachLayout(new_layout_info)).unwrap();
spipe.script_chan.clone()
script_chan.clone()
}
};
@ -132,7 +136,7 @@ impl Pipeline {
layout_shutdown_chan);
Pipeline::new(id,
parent,
parent_info,
script_chan,
LayoutControlChan(pipeline_chan),
paint_chan,
@ -142,7 +146,7 @@ impl Pipeline {
}
pub fn new(id: PipelineId,
parent: Option<(PipelineId, SubpageId)>,
parent_info: Option<(PipelineId, SubpageId)>,
script_chan: ScriptControlChan,
layout_chan: LayoutControlChan,
paint_chan: PaintChan,
@ -152,7 +156,7 @@ impl Pipeline {
-> Pipeline {
Pipeline {
id: id,
parent: parent,
parent_info: parent_info,
script_chan: script_chan,
layout_chan: layout_chan,
paint_chan: paint_chan,
@ -160,14 +164,11 @@ impl Pipeline {
paint_shutdown_port: paint_shutdown_port,
url: url,
title: None,
children: vec!(),
rect: None,
}
}
pub fn activate(&self) {
let ScriptControlChan(ref chan) = self.script_chan;
chan.send(ConstellationControlMsg::Activate(self.id)).unwrap();
}
pub fn grant_paint_permission(&self) {
let _ = self.paint_chan.send(PaintMsg::PaintPermissionGranted);
}
@ -221,7 +222,7 @@ impl Pipeline {
}
}
pub fn subpage_id(&self) -> Option<SubpageId> {
self.parent.map(|parent| parent.1)
pub fn add_child(&mut self, frame_id: FrameId) {
self.children.push(frame_id);
}
}

View file

@ -26,7 +26,7 @@ impl ConstellationChan {
}
}
#[derive(PartialEq, Eq, Copy)]
#[derive(PartialEq, Eq, Copy, Debug)]
pub enum IFrameSandboxState {
IFrameSandboxed,
IFrameUnsandboxed
@ -36,7 +36,7 @@ pub enum IFrameSandboxState {
#[derive(Clone, Copy)]
pub struct Failure {
pub pipeline_id: PipelineId,
pub parent: Option<(PipelineId, SubpageId)>,
pub parent_info: Option<(PipelineId, SubpageId)>,
}
#[derive(Copy)]
@ -236,19 +236,15 @@ impl LoadData {
}
}
/// Represents the two different ways to which a page can be navigated
#[derive(Clone, PartialEq, Eq, Copy, Hash, Debug)]
pub enum NavigationType {
Load, // entered or clicked on a url
Navigate, // browser forward/back buttons
}
#[derive(Clone, PartialEq, Eq, Copy, Hash, Debug)]
pub enum NavigationDirection {
Forward,
Back,
}
#[derive(Clone, PartialEq, Eq, Copy, Hash, Debug)]
pub struct FrameId(pub uint);
#[derive(Clone, PartialEq, Eq, Copy, Hash, Debug)]
pub struct PipelineId(pub uint);

View file

@ -215,7 +215,7 @@ impl<'a> HTMLFormElementHelpers for JSRef<'a, HTMLFormElement> {
}
// This is wrong. https://html.spec.whatwg.org/multipage/forms.html#planned-navigation
win.r().script_chan().send(ScriptMsg::TriggerLoad(win.r().pipeline(), load_data)).unwrap();
win.r().script_chan().send(ScriptMsg::Navigate(win.r().pipeline(), load_data)).unwrap();
}
fn get_form_dataset<'b>(self, submitter: Option<FormSubmitter<'b>>) -> Vec<FormDatum> {

View file

@ -63,6 +63,7 @@ pub trait HTMLIFrameElementHelpers {
/// http://www.whatwg.org/html/#process-the-iframe-attributes
fn process_the_iframe_attributes(self);
fn generate_new_subpage_id(self) -> (SubpageId, Option<SubpageId>);
fn navigate_child_browsing_context(self, url: Url);
}
impl<'a> HTMLIFrameElementHelpers for JSRef<'a, HTMLIFrameElement> {
@ -92,12 +93,7 @@ impl<'a> HTMLIFrameElementHelpers for JSRef<'a, HTMLIFrameElement> {
(subpage_id, old_subpage_id)
}
fn process_the_iframe_attributes(self) {
let url = match self.get_url() {
Some(url) => url.clone(),
None => Url::parse("about:blank").unwrap(),
};
fn navigate_child_browsing_context(self, url: Url) {
let sandboxed = if self.is_sandboxed() {
IFrameSandboxed
} else {
@ -111,11 +107,20 @@ impl<'a> HTMLIFrameElementHelpers for JSRef<'a, HTMLIFrameElement> {
self.containing_page_pipeline_id.set(Some(window.pipeline()));
let ConstellationChan(ref chan) = window.constellation_chan();
chan.send(ConstellationMsg::ScriptLoadedURLInIFrame(url,
window.pipeline(),
new_subpage_id,
old_subpage_id,
sandboxed)).unwrap();
chan.send(ConstellationMsg::ScriptLoadedURLInIFrame(url,
window.pipeline(),
new_subpage_id,
old_subpage_id,
sandboxed)).unwrap();
}
fn process_the_iframe_attributes(self) {
let url = match self.get_url() {
Some(url) => url.clone(),
None => Url::parse("about:blank").unwrap(),
};
self.navigate_child_browsing_context(url);
}
}

View file

@ -135,7 +135,7 @@ pub struct Window {
layout_join_port: DOMRefCell<Option<Receiver<()>>>,
/// The current size of the window, in pixels.
window_size: Cell<WindowSizeData>,
window_size: Cell<Option<WindowSizeData>>,
/// Associated resource task for use by DOM objects like XMLHttpRequest
resource_task: ResourceTask,
@ -428,7 +428,7 @@ pub trait WindowHelpers {
fn set_fragment_name(self, fragment: Option<String>);
fn steal_fragment_name(self) -> Option<String>;
fn set_window_size(self, size: WindowSizeData);
fn window_size(self) -> WindowSizeData;
fn window_size(self) -> Option<WindowSizeData>;
fn get_url(self) -> Url;
fn resource_task(self) -> ResourceTask;
fn devtools_chan(self) -> Option<DevtoolsControlChan>;
@ -517,6 +517,11 @@ impl<'a> WindowHelpers for JSRef<'a, Window> {
return
}
let window_size = match self.window_size.get() {
Some(window_size) => window_size,
None => return,
};
// Layout will let us know when it's done.
let (join_chan, join_port) = channel();
@ -528,8 +533,6 @@ impl<'a> WindowHelpers for JSRef<'a, Window> {
let last_reflow_id = &self.last_reflow_id;
last_reflow_id.set(last_reflow_id.get() + 1);
let window_size = self.window_size.get();
// On debug mode, print the reflow event information.
if opts::get().relayout_event {
debug_reflow_events(&goal, &query_type, &reason);
@ -607,7 +610,7 @@ impl<'a> WindowHelpers for JSRef<'a, Window> {
}
fn handle_resize_inactive_msg(self, new_size: WindowSizeData) {
self.window_size.set(new_size);
self.window_size.set(Some(new_size));
}
fn init_browser_context(self, doc: JSRef<Document>, frame_element: Option<JSRef<Element>>) {
@ -626,7 +629,7 @@ impl<'a> WindowHelpers for JSRef<'a, Window> {
self.script_chan.send(ScriptMsg::TriggerFragment(self.id, fragment)).unwrap();
},
None => {
self.script_chan.send(ScriptMsg::TriggerLoad(self.id, LoadData::new(url))).unwrap();
self.script_chan.send(ScriptMsg::Navigate(self.id, LoadData::new(url))).unwrap();
}
}
}
@ -645,10 +648,10 @@ impl<'a> WindowHelpers for JSRef<'a, Window> {
}
fn set_window_size(self, size: WindowSizeData) {
self.window_size.set(size);
self.window_size.set(Some(size));
}
fn window_size(self) -> WindowSizeData {
fn window_size(self) -> Option<WindowSizeData> {
self.window_size.get()
}
@ -755,7 +758,7 @@ impl Window {
layout_chan: LayoutChan,
id: PipelineId,
subpage_id: Option<SubpageId>,
window_size: WindowSizeData)
window_size: Option<WindowSizeData>)
-> Temporary<Window> {
let layout_rpc: Box<LayoutRPC> = {
let (rpc_send, rpc_recv) = channel();

View file

@ -33,6 +33,7 @@ use dom::bindings::utils::{wrap_for_same_compartment, pre_wrap};
use dom::document::{Document, IsHTMLDocument, DocumentHelpers, DocumentProgressHandler, DocumentProgressTask, DocumentSource};
use dom::element::{Element, AttributeHandlers};
use dom::event::{Event, EventHelpers, EventBubbles, EventCancelable};
use dom::htmliframeelement::HTMLIFrameElementHelpers;
use dom::uievent::UIEvent;
use dom::eventtarget::EventTarget;
use dom::node::{self, Node, NodeHelpers, NodeDamage, window_from_node};
@ -116,7 +117,7 @@ struct InProgressLoad {
/// The parent pipeline and child subpage associated with this load, if any.
subpage_id: Option<(PipelineId, SubpageId)>,
/// The current window size associated with this pipeline.
window_size: WindowSizeData,
window_size: Option<WindowSizeData>,
/// Channel to the layout task associated with this pipeline.
layout_chan: LayoutChan,
/// The current viewport clipping rectangle applying to this pipelie, if any.
@ -130,7 +131,7 @@ impl InProgressLoad {
fn new(id: PipelineId,
subpage_id: Option<(PipelineId, SubpageId)>,
layout_chan: LayoutChan,
window_size: WindowSizeData,
window_size: Option<WindowSizeData>,
url: Url) -> InProgressLoad {
InProgressLoad {
pipeline_id: id,
@ -161,7 +162,7 @@ pub enum ScriptMsg {
TriggerFragment(PipelineId, String),
/// Begins a content-initiated load on the specified pipeline (only
/// dispatched to ScriptTask).
TriggerLoad(PipelineId, LoadData),
Navigate(PipelineId, LoadData),
/// Fires a JavaScript timeout
/// TimerSource must be FromWindow when dispatched to ScriptTask and
/// must be FromWorker when dispatched to a DedicatedGlobalWorkerScope
@ -340,7 +341,7 @@ impl ScriptTaskFactory for ScriptTask {
storage_task: StorageTask,
image_cache_task: ImageCacheTask,
devtools_chan: Option<DevtoolsControlChan>,
window_size: WindowSizeData,
window_size: Option<WindowSizeData>,
load_data: LoadData)
where C: ScriptListener + Send + 'static {
let ConstellationChan(const_chan) = constellation_chan.clone();
@ -620,8 +621,8 @@ impl ScriptTask {
match msg {
ConstellationControlMsg::AttachLayout(_) =>
panic!("should have handled AttachLayout already"),
ConstellationControlMsg::Activate(id) =>
self.handle_activate(id),
ConstellationControlMsg::Navigate(pipeline_id, subpage_id, load_data) =>
self.handle_navigate(pipeline_id, Some(subpage_id), load_data),
ConstellationControlMsg::SendEvent(id, event) =>
self.handle_event(id, event),
ConstellationControlMsg::ReflowComplete(id, reflow_id) =>
@ -645,8 +646,8 @@ impl ScriptTask {
fn handle_msg_from_script(&self, msg: ScriptMsg) {
match msg {
ScriptMsg::TriggerLoad(id, load_data) =>
self.trigger_load(id, load_data),
ScriptMsg::Navigate(id, load_data) =>
self.handle_navigate(id, None, load_data),
ScriptMsg::TriggerFragment(id, fragment) =>
self.trigger_fragment(id, fragment),
ScriptMsg::FireTimer(TimerSource::FromWindow(id), timer_id) =>
@ -697,7 +698,7 @@ impl ScriptTask {
}
let mut loads = self.incomplete_loads.borrow_mut();
if let Some(ref mut load) = loads.iter_mut().find(|load| load.pipeline_id == id) {
load.window_size = size;
load.window_size = Some(size);
return;
}
panic!("resize sent to nonexistent pipeline");
@ -726,7 +727,7 @@ impl ScriptTask {
/// Handle a request to load a page in a new child frame of an existing page.
fn handle_new_layout(&self, new_layout_info: NewLayoutInfo) {
let NewLayoutInfo {
old_pipeline_id,
containing_pipeline_id,
new_pipeline_id,
subpage_id,
layout_chan,
@ -734,7 +735,7 @@ impl ScriptTask {
} = new_layout_info;
let page = self.root_page();
let parent_page = page.find(old_pipeline_id).expect("ScriptTask: received a layout
let parent_page = page.find(containing_pipeline_id).expect("ScriptTask: received a layout
whose parent has a PipelineId which does not correspond to a pipeline in the script
task's page tree. This is a bug.");
@ -742,7 +743,7 @@ impl ScriptTask {
let chan = layout_chan.downcast_ref::<Sender<layout_interface::Msg>>().unwrap();
let layout_chan = LayoutChan(chan.clone());
// Kick off the fetch for the new resource.
let new_load = InProgressLoad::new(new_pipeline_id, Some((old_pipeline_id, subpage_id)),
let new_load = InProgressLoad::new(new_pipeline_id, Some((containing_pipeline_id, subpage_id)),
layout_chan, parent_window.r().window_size(),
load_data.url.clone());
self.start_page_load(new_load, load_data);
@ -768,24 +769,17 @@ impl ScriptTask {
/// Handles thaw message
fn handle_thaw_msg(&self, id: PipelineId) {
let page = self.root_page();
let page = page.find(id).expect("ScriptTask: received thaw msg for a
pipeline ID not associated with this script task. This is a bug.");
let window = page.window().root();
window.r().thaw();
}
/// Handle a request to make a previously-created pipeline active.
//TODO: unsuspend JS and timers, etc. when we support such things.
fn handle_activate(&self, pipeline_id: PipelineId) {
// We should only get this message when moving in history, so all pages requested
// should exist.
let page = self.root_page().find(pipeline_id).unwrap();
let page = self.root_page().find(id).unwrap();
let needed_reflow = page.set_reflow_status(false);
if needed_reflow {
self.force_reflow(&*page, ReflowReason::CachedPageNeededReflow);
}
let window = page.window().root();
window.r().thaw();
}
/// Handles a notification that reflow completed.
@ -1138,11 +1132,29 @@ impl ScriptTask {
}
}
/// https://html.spec.whatwg.org/multipage/browsers.html#navigating-across-documents
/// The entry point for content to notify that a new load has been requested
/// for the given pipeline.
fn trigger_load(&self, pipeline_id: PipelineId, load_data: LoadData) {
let ConstellationChan(ref const_chan) = self.constellation_chan;
const_chan.send(ConstellationMsg::LoadUrl(pipeline_id, load_data)).unwrap();
/// for the given pipeline (specifically the "navigate" algorithm).
fn handle_navigate(&self, pipeline_id: PipelineId, subpage_id: Option<SubpageId>, load_data: LoadData) {
match subpage_id {
Some(subpage_id) => {
let borrowed_page = self.root_page();
let iframe = borrowed_page.find(pipeline_id).and_then(|page| {
let doc = page.document().root();
let doc: JSRef<Node> = NodeCast::from_ref(doc.r());
doc.traverse_preorder()
.filter_map(HTMLIFrameElementCast::to_ref)
.find(|node| node.subpage_id() == Some(subpage_id))
.map(Temporary::from_rooted)
}).root();
iframe.r().unwrap().navigate_child_browsing_context(load_data.url);
}
None => {
let ConstellationChan(ref const_chan) = self.constellation_chan;
const_chan.send(ConstellationMsg::LoadUrl(pipeline_id, load_data)).unwrap();
}
}
}
/// The entry point for content to notify that a fragment url has been requested

View file

@ -44,7 +44,7 @@ pub struct UntrustedNodeAddress(pub *const c_void);
unsafe impl Send for UntrustedNodeAddress {}
pub struct NewLayoutInfo {
pub old_pipeline_id: PipelineId,
pub containing_pipeline_id: PipelineId,
pub new_pipeline_id: PipelineId,
pub subpage_id: SubpageId,
pub layout_chan: Box<Any+Send>, // opaque reference to a LayoutChannel
@ -53,8 +53,6 @@ pub struct NewLayoutInfo {
/// Messages sent from the constellation to the script task
pub enum ConstellationControlMsg {
/// Reactivate an existing pipeline.
Activate(PipelineId),
/// Gives a channel and ID to a layout task, as well as the ID of that layout's parent
AttachLayout(NewLayoutInfo),
/// Window resized. Sends a DOM event eventually, but first we combine events.
@ -74,7 +72,9 @@ pub enum ConstellationControlMsg {
/// Notifies script task to suspend all its timers
Freeze(PipelineId),
/// Notifies script task to resume all its timers
Thaw(PipelineId)
Thaw(PipelineId),
/// Notifies script task that a url should be loaded in this iframe.
Navigate(PipelineId, SubpageId, LoadData),
}
unsafe impl Send for ConstellationControlMsg {
@ -112,7 +112,7 @@ pub trait ScriptTaskFactory {
storage_task: StorageTask,
image_cache_task: ImageCacheTask,
devtools_chan: Option<DevtoolsControlChan>,
window_size: WindowSizeData,
window_size: Option<WindowSizeData>,
load_data: LoadData)
where C: ScriptListener + Send;
fn create_layout_channel(_phantom: Option<&mut Self>) -> OpaqueScriptLayoutChannel;