aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Robinson <mrobinson@igalia.com>2014-11-11 08:20:37 -0800
committerMartin Robinson <mrobinson@igalia.com>2015-01-09 15:14:01 -0800
commit6a46eef5cd85bacefe0a5dc383833df5076d34fa (patch)
treef6d00112d617a2ba7cd6e5ed30364692a290381e
parentc1d218cf0260da4e0642e2ea5b73823de79aa2c7 (diff)
downloadservo-6a46eef5cd85bacefe0a5dc383833df5076d34fa.tar.gz
servo-6a46eef5cd85bacefe0a5dc383833df5076d34fa.zip
Update FrameTree pipelines when appropriate
Instead of simply creating a new FrameTree when an iframe starts a load, update the existing FrameTree's pipeline. This prevents the FrameTree from accumulating many extra children.
-rw-r--r--components/compositing/constellation.rs152
-rw-r--r--components/layout/wrapper.rs4
-rw-r--r--components/msg/constellation_msg.rs2
-rw-r--r--components/script/dom/htmliframeelement.rs63
4 files changed, 126 insertions, 95 deletions
diff --git a/components/compositing/constellation.rs b/components/compositing/constellation.rs
index 5bc565b7f9a..0024d516f43 100644
--- a/components/compositing/constellation.rs
+++ b/components/compositing/constellation.rs
@@ -98,7 +98,7 @@ struct FrameTree {
/// The ID of this frame.
pub id: FrameId,
/// The pipeline for this frame.
- pub pipeline: Rc<Pipeline>,
+ pub pipeline: RefCell<Rc<Pipeline>>,
/// The parent frame's pipeline.
pub parent: RefCell<Option<Rc<Pipeline>>>,
/// A vector of child frames.
@@ -112,7 +112,7 @@ impl FrameTree {
-> FrameTree {
FrameTree {
id: id,
- pipeline: pipeline,
+ pipeline: RefCell::new(pipeline.clone()),
parent: RefCell::new(parent_pipeline),
children: RefCell::new(vec!()),
has_compositor_layer: Cell::new(false),
@@ -165,7 +165,7 @@ pub struct FrameTreeDiff {
impl FrameTree {
fn to_sendable(&self) -> SendableFrameTree {
SendableFrameTree {
- pipeline: self.pipeline.to_sendable(),
+ pipeline: self.pipeline.borrow().to_sendable(),
children: self.children
.borrow()
.iter()
@@ -178,18 +178,24 @@ impl FrameTree {
trait FrameTreeTraversal {
fn contains(&self, id: PipelineId) -> bool;
fn find(&self, id: PipelineId) -> Option<Self>;
+ fn find_with_subpage_id(&self, id: Option<SubpageId>) -> Option<Rc<FrameTree>>;
fn replace_child(&self, id: PipelineId, new_child: Self) -> ReplaceResult;
fn iter(&self) -> FrameTreeIterator;
}
impl FrameTreeTraversal for Rc<FrameTree> {
fn contains(&self, id: PipelineId) -> bool {
- self.iter().any(|frame_tree| id == frame_tree.pipeline.id)
+ self.iter().any(|frame_tree| id == frame_tree.pipeline.borrow().id)
}
/// Returns the frame tree whose key is id
fn find(&self, id: PipelineId) -> Option<Rc<FrameTree>> {
- self.iter().find(|frame_tree| id == frame_tree.pipeline.id)
+ self.iter().find(|frame_tree| id == frame_tree.pipeline.borrow().id)
+ }
+
+ /// Returns the frame tree whose subpage is id
+ fn find_with_subpage_id(&self, id: Option<SubpageId>) -> Option<Rc<FrameTree>> {
+ self.iter().find(|frame_tree| id == frame_tree.pipeline.borrow().subpage_id)
}
/// Replaces a node of the frame tree in place. Returns the node that was removed or the
@@ -198,7 +204,7 @@ impl FrameTreeTraversal for Rc<FrameTree> {
for frame_tree in self.iter() {
let mut children = frame_tree.children.borrow_mut();
let child = children.iter_mut()
- .find(|child| child.frame_tree.pipeline.id == id);
+ .find(|child| child.frame_tree.pipeline.borrow().id == id);
match child {
Some(child) => {
*new_child.parent.borrow_mut() = child.frame_tree.parent.borrow().clone();
@@ -293,7 +299,7 @@ impl NavigationContext {
/// Loads a new set of page frames, returning all evicted frame trees
fn load(&mut self, frame_tree: Rc<FrameTree>, compositor_proxy: &mut CompositorProxy)
-> Vec<Rc<FrameTree>> {
- debug!("navigating to {}", frame_tree.pipeline.id);
+ debug!("navigating to {}", frame_tree.pipeline.borrow().id);
let evicted = replace(&mut self.next, vec!());
match self.current.take() {
Some(current) => self.previous.push(current),
@@ -334,7 +340,7 @@ impl NavigationContext {
self.current = Some(new_frame.clone());
compositor_proxy.send(CompositorMsg::ChangePageLoadData(
new_frame.id,
- new_frame.pipeline.load_data.clone()));
+ new_frame.pipeline.borrow().load_data.clone()));
}
}
@@ -463,11 +469,12 @@ impl<LTF: LayoutTaskFactory, STF: ScriptTaskFactory> Constellation<LTF, STF> {
debug!("constellation got frame rect message");
self.handle_frame_rect_msg(pipeline_id, subpage_id, Rect::from_untyped(&rect));
}
- ConstellationMsg::ScriptLoadedURLInIFrame(url, source_pipeline_id, subpage_id, sandbox) => {
+ ConstellationMsg::ScriptLoadedURLInIFrame(url, source_pipeline_id, new_subpage_id, old_subpage_id, sandbox) => {
debug!("constellation got iframe URL load message");
self.handle_script_loaded_url_in_iframe_msg(url,
source_pipeline_id,
- subpage_id,
+ new_subpage_id,
+ old_subpage_id,
sandbox);
}
ConstellationMsg::SetCursor(cursor) => self.handle_set_cursor_msg(cursor),
@@ -550,12 +557,12 @@ impl<LTF: LayoutTaskFactory, STF: ScriptTaskFactory> Constellation<LTF, STF> {
loop {
let idx = self.pending_frames.iter().position(|pending| {
- pending.after.pipeline.id == pipeline_id
+ pending.after.pipeline.borrow().id == pipeline_id
});
match idx {
Some(idx) => {
debug!("removing pending frame change for failed pipeline");
- self.pending_frames[idx].after.pipeline.force_exit();
+ self.pending_frames[idx].after.pipeline.borrow().force_exit();
self.compositor_proxy.send(CompositorMsg::PaintTaskExited(old_pipeline.id));
self.pending_frames.remove(idx);
},
@@ -607,7 +614,7 @@ impl<LTF: LayoutTaskFactory, STF: ScriptTaskFactory> Constellation<LTF, STF> {
// Returns true if a child frame tree's subpage id matches the given subpage id
let subpage_eq = |child_frame_tree: & &mut ChildFrameTree| {
- child_frame_tree.frame_tree.pipeline.
+ child_frame_tree.frame_tree.pipeline.borrow().
subpage_id.expect("Constellation:
child frame does not have a subpage id. This should not be possible.")
== subpage_id
@@ -668,7 +675,7 @@ impl<LTF: LayoutTaskFactory, STF: ScriptTaskFactory> Constellation<LTF, STF> {
device_pixel_ratio: ScaleFactor<ViewportPx,DevicePixel,f32>) {
child_frame_tree.rect = Some(rect);
// NOTE: work around borrowchk issues
- let pipeline = &child_frame_tree.frame_tree.pipeline;
+ let pipeline = &*child_frame_tree.frame_tree.pipeline.borrow();
if !already_sent.contains(&pipeline.id) {
if is_active {
let ScriptControlChan(ref script_chan) = pipeline.script_chan;
@@ -688,31 +695,60 @@ impl<LTF: LayoutTaskFactory, STF: ScriptTaskFactory> Constellation<LTF, STF> {
}
}
+ fn update_child_pipeline(frame_tree: Rc<FrameTree>,
+ new_pipeline: Rc<Pipeline>,
+ old_subpage_id: SubpageId) {
+ let existing_tree = match frame_tree.find_with_subpage_id(Some(old_subpage_id)) {
+ Some(existing_tree) => existing_tree.clone(),
+ None => panic!("Tried to update non-existing frame tree with pipeline={} subpage={}",
+ new_pipeline.id,
+ old_subpage_id),
+ };
+
+ *existing_tree.pipeline.borrow_mut() = new_pipeline;
+ }
+
+ fn create_or_update_child_pipeline(&mut self,
+ frame_tree: Rc<FrameTree>,
+ new_pipeline: Rc<Pipeline>,
+ new_rect: Option<TypedRect<PagePx, f32>>,
+ old_subpage_id: Option<SubpageId>) {
+ match old_subpage_id {
+ Some(old_subpage_id) =>
+ Constellation::update_child_pipeline(frame_tree.clone(), new_pipeline, old_subpage_id),
+ None => {
+ let new_frame_tree =
+ Rc::new(FrameTree::new(self.get_next_frame_id(), new_pipeline,
+ Some(frame_tree.pipeline.borrow().clone())));
+ frame_tree.children.borrow_mut().push(ChildFrameTree::new(new_frame_tree,
+ new_rect));
+ }
+ }
+ }
// The script task associated with pipeline_id has loaded a URL in an iframe via script. This
// will result in a new pipeline being spawned and a frame tree being added to
- // source_pipeline_id's frame tree's children. This message is never the result of a page
- // navigation.
+ // containing_page_pipeline_id's frame tree's children. This message is never the result of a
+ // page navigation.
fn handle_script_loaded_url_in_iframe_msg(&mut self,
url: Url,
- source_pipeline_id: PipelineId,
- subpage_id: SubpageId,
+ containing_page_pipeline_id: PipelineId,
+ new_subpage_id: SubpageId,
+ old_subpage_id: Option<SubpageId>,
sandbox: IFrameSandboxState) {
// Start by finding the frame trees matching the pipeline id,
// and add the new pipeline to their sub frames.
- let frame_trees = self.find_all(source_pipeline_id);
+ let frame_trees = self.find_all(containing_page_pipeline_id);
if frame_trees.is_empty() {
panic!("Constellation: source pipeline id of ScriptLoadedURLInIFrame is not in
navigation context, nor is it in a pending frame. This should be
impossible.");
}
- let next_pipeline_id = self.get_next_pipeline_id();
-
// Compare the pipeline's url to the new url. If the origin is the same,
// then reuse the script task in creating the new pipeline
- let source_pipeline = self.pipelines.get(&source_pipeline_id).expect("Constellation:
- source Id of ScriptLoadedURLInIFrame does have an associated pipeline in
+ let source_pipeline = self.pipelines.get(&containing_page_pipeline_id).expect("Constellation:
+ source Id of ScriptLoadedURLInIFrameMsg does have an associated pipeline in
constellation. This should be impossible.").clone();
let source_url = source_pipeline.load_data.url.clone();
@@ -730,21 +766,20 @@ impl<LTF: LayoutTaskFactory, STF: ScriptTaskFactory> Constellation<LTF, STF> {
None
};
+ let new_frame_pipeline_id = self.get_next_pipeline_id();
let pipeline = self.new_pipeline(
- next_pipeline_id,
- Some(subpage_id),
+ new_frame_pipeline_id,
+ Some(new_subpage_id),
script_pipeline,
LoadData::new(url)
);
- let rect = self.pending_sizes.remove(&(source_pipeline_id, subpage_id));
+ let rect = self.pending_sizes.remove(&(containing_page_pipeline_id, new_subpage_id));
for frame_tree in frame_trees.iter() {
- let next_frame_id = self.get_next_frame_id();
- frame_tree.children.borrow_mut().push(ChildFrameTree::new(
- Rc::new(FrameTree::new(next_frame_id,
- pipeline.clone(),
- Some(source_pipeline.clone()))),
- rect));
+ self.create_or_update_child_pipeline(frame_tree.clone(),
+ pipeline.clone(),
+ rect,
+ old_subpage_id);
}
self.pipelines.insert(pipeline.id, pipeline);
}
@@ -778,7 +813,7 @@ impl<LTF: LayoutTaskFactory, STF: ScriptTaskFactory> Constellation<LTF, STF> {
// changes would be overridden by changing the subframe associated with source_id.
let parent = source_frame.parent.clone();
- let subpage_id = source_frame.pipeline.subpage_id;
+ let subpage_id = source_frame.pipeline.borrow().subpage_id;
let next_pipeline_id = self.get_next_pipeline_id();
let next_frame_id = self.get_next_frame_id();
let pipeline = self.new_pipeline(next_pipeline_id, subpage_id, None, load_data);
@@ -805,7 +840,7 @@ impl<LTF: LayoutTaskFactory, STF: ScriptTaskFactory> Constellation<LTF, STF> {
} else {
let old = self.current_frame().as_ref().unwrap();
for frame in old.iter() {
- frame.pipeline.revoke_paint_permission();
+ frame.pipeline.borrow().revoke_paint_permission();
}
}
self.navigation_context.forward(&mut *self.compositor_proxy)
@@ -817,7 +852,7 @@ impl<LTF: LayoutTaskFactory, STF: ScriptTaskFactory> Constellation<LTF, STF> {
} else {
let old = self.current_frame().as_ref().unwrap();
for frame in old.iter() {
- frame.pipeline.revoke_paint_permission();
+ frame.pipeline.borrow().revoke_paint_permission();
}
}
self.navigation_context.back(&mut *self.compositor_proxy)
@@ -825,7 +860,7 @@ impl<LTF: LayoutTaskFactory, STF: ScriptTaskFactory> Constellation<LTF, STF> {
};
for frame in destination_frame.iter() {
- frame.pipeline.load();
+ frame.pipeline.borrow().load();
}
self.grant_paint_permission(destination_frame, NavigationType::Navigate);
@@ -838,9 +873,9 @@ impl<LTF: LayoutTaskFactory, STF: ScriptTaskFactory> Constellation<LTF, STF> {
fn handle_key_msg(&self, key: Key, state: KeyState, mods: KeyModifiers) {
self.current_frame().as_ref().map(|frame| {
- let ScriptControlChan(ref chan) = frame.pipeline.script_chan;
+ let ScriptControlChan(ref chan) = frame.pipeline.borrow().script_chan;
chan.send(ConstellationControlMsg::SendEvent(
- frame.pipeline.id, CompositorEvent::KeyEvent(key, state, mods)));
+ frame.pipeline.borrow().id, CompositorEvent::KeyEvent(key, state, mods)));
});
}
@@ -871,7 +906,7 @@ impl<LTF: LayoutTaskFactory, STF: ScriptTaskFactory> Constellation<LTF, STF> {
// If it is not found, it simply means that this pipeline will not receive
// permission to paint.
let pending_index = self.pending_frames.iter().rposition(|frame_change| {
- frame_change.after.pipeline.id == pipeline_id
+ frame_change.after.pipeline.borrow().id == pipeline_id
});
match pending_index {
Some(pending_index) => {
@@ -897,7 +932,7 @@ impl<LTF: LayoutTaskFactory, STF: ScriptTaskFactory> Constellation<LTF, STF> {
frame not contained in the current frame. This is a bug");
for frame in to_revoke.iter() {
- frame.pipeline.revoke_paint_permission();
+ frame.pipeline.borrow().revoke_paint_permission();
}
// If to_add is not the root frame, then replace revoked_frame with it.
@@ -907,8 +942,8 @@ impl<LTF: LayoutTaskFactory, STF: ScriptTaskFactory> Constellation<LTF, STF> {
{
if to_add.parent.borrow().is_some() {
debug!("Constellation: replacing {} with {} in {}",
- revoke_id, to_add.pipeline.id,
- next_frame_tree.pipeline.id);
+ revoke_id, to_add.pipeline.borrow().id,
+ next_frame_tree.pipeline.borrow().id);
flag = true;
}
}
@@ -921,7 +956,7 @@ impl<LTF: LayoutTaskFactory, STF: ScriptTaskFactory> Constellation<LTF, STF> {
// Add to_add to parent's children, if it is not the root
let parent = &to_add.parent;
for parent in parent.borrow().iter() {
- let subpage_id = to_add.pipeline.subpage_id
+ let subpage_id = to_add.pipeline.borrow().subpage_id
.expect("Constellation:
Child frame's subpage id is None. This should be impossible.");
let rect = self.pending_sizes.remove(&(parent.id, subpage_id));
@@ -945,14 +980,14 @@ impl<LTF: LayoutTaskFactory, STF: ScriptTaskFactory> Constellation<LTF, STF> {
let mut already_seen = HashSet::new();
for frame_tree in self.current_frame().iter() {
debug!("constellation sending resize message to active frame");
- let pipeline = &frame_tree.pipeline;
+ let pipeline = &*frame_tree.pipeline.borrow();;
let ScriptControlChan(ref chan) = pipeline.script_chan;
let _ = chan.send_opt(ConstellationControlMsg::Resize(pipeline.id, new_size));
already_seen.insert(pipeline.id);
}
for frame_tree in self.navigation_context.previous.iter()
.chain(self.navigation_context.next.iter()) {
- let pipeline = &frame_tree.pipeline;
+ let pipeline = &*frame_tree.pipeline.borrow();
if !already_seen.contains(&pipeline.id) {
debug!("constellation sending resize message to inactive frame");
let ScriptControlChan(ref chan) = pipeline.script_chan;
@@ -967,9 +1002,10 @@ impl<LTF: LayoutTaskFactory, STF: ScriptTaskFactory> Constellation<LTF, STF> {
let frame_tree = &change.after;
if frame_tree.parent.borrow().is_none() {
debug!("constellation sending resize message to pending outer frame ({})",
- frame_tree.pipeline.id);
- let ScriptControlChan(ref chan) = frame_tree.pipeline.script_chan;
- let _ = chan.send_opt(ConstellationControlMsg::Resize(frame_tree.pipeline.id, new_size));
+ frame_tree.pipeline.borrow().id);
+ let ScriptControlChan(ref chan) = frame_tree.pipeline.borrow().script_chan;
+ let _ = chan.send_opt(ConstellationControlMsg::Resize(
+ frame_tree.pipeline.borrow().id, new_size));
}
}
@@ -981,15 +1017,15 @@ impl<LTF: LayoutTaskFactory, STF: ScriptTaskFactory> Constellation<LTF, STF> {
// TODO(tkuehn): should only exit once per unique script task,
// and then that script task will handle sub-exits
for frame_tree in frame_tree.iter() {
- frame_tree.pipeline.exit(PipelineExitType::PipelineOnly);
- self.compositor_proxy.send(CompositorMsg::PaintTaskExited(frame_tree.pipeline.id));
- self.pipelines.remove(&frame_tree.pipeline.id);
+ frame_tree.pipeline.borrow().exit(PipelineExitType::PipelineOnly);
+ self.compositor_proxy.send(CompositorMsg::PaintTaskExited(frame_tree.pipeline.borrow().id));
+ self.pipelines.remove(&frame_tree.pipeline.borrow().id);
}
}
fn handle_evicted_frames(&mut self, evicted: Vec<Rc<FrameTree>>) {
for frame_tree in evicted.into_iter() {
- if !self.navigation_context.contains(frame_tree.pipeline.id) {
+ if !self.navigation_context.contains(frame_tree.pipeline.borrow().id) {
self.close_pipelines(frame_tree);
} else {
let frames = frame_tree.children.borrow().iter()
@@ -1030,7 +1066,7 @@ impl<LTF: LayoutTaskFactory, STF: ScriptTaskFactory> Constellation<LTF, STF> {
let mut iter = frame_tree.iter();
for frame in iter {
frame.has_compositor_layer.set(true);
- frame.pipeline.grant_paint_permission();
+ frame.pipeline.borrow().grant_paint_permission();
}
}
Err(()) => {} // message has been discarded, probably shutting down
@@ -1043,7 +1079,7 @@ impl<LTF: LayoutTaskFactory, STF: ScriptTaskFactory> Constellation<LTF, STF> {
-> Option<(ChildFrameTree, Rc<FrameTree>)> {
for child in frame_tree.children.borrow().iter() {
let child_frame_tree = child.frame_tree.clone();
- if child.frame_tree.pipeline.id == child_pipeline_id {
+ if child.frame_tree.pipeline.borrow().id == child_pipeline_id {
return Some((ChildFrameTree::new(child_frame_tree, child.rect),
frame_tree.clone()));
}
@@ -1070,13 +1106,13 @@ impl<LTF: LayoutTaskFactory, STF: ScriptTaskFactory> Constellation<LTF, STF> {
};
if child.frame_tree.has_compositor_layer.get() {
- child.frame_tree.pipeline.grant_paint_permission();
+ child.frame_tree.pipeline.borrow().grant_paint_permission();
return;
}
let sendable_frame_tree_diff = FrameTreeDiff {
- parent_pipeline: parent.pipeline.to_sendable(),
- pipeline: child.frame_tree.pipeline.to_sendable(),
+ parent_pipeline: parent.pipeline.borrow().to_sendable(),
+ pipeline: child.frame_tree.pipeline.borrow().to_sendable(),
rect: child.rect,
};
@@ -1085,7 +1121,7 @@ impl<LTF: LayoutTaskFactory, STF: ScriptTaskFactory> Constellation<LTF, STF> {
match port.recv_opt() {
Ok(()) => {
child.frame_tree.has_compositor_layer.set(true);
- child.frame_tree.pipeline.grant_paint_permission();
+ child.frame_tree.pipeline.borrow().grant_paint_permission();
}
Err(()) => {} // The message has been discarded, we are probably shutting down.
}
diff --git a/components/layout/wrapper.rs b/components/layout/wrapper.rs
index e11587710fa..98567dbcecd 100644
--- a/components/layout/wrapper.rs
+++ b/components/layout/wrapper.rs
@@ -144,8 +144,8 @@ pub trait TLayoutNode {
Some(elem) => elem,
None => panic!("not an iframe element!")
};
- let size = (*iframe_element.unsafe_get()).size().unwrap();
- (*size.pipeline_id(), *size.subpage_id())
+ ((*iframe_element.unsafe_get()).containing_page_pipeline_id().unwrap(),
+ (*iframe_element.unsafe_get()).subpage_id().unwrap())
}
}
diff --git a/components/msg/constellation_msg.rs b/components/msg/constellation_msg.rs
index cbd6062f724..5cd2a0cce39 100644
--- a/components/msg/constellation_msg.rs
+++ b/components/msg/constellation_msg.rs
@@ -203,7 +203,7 @@ pub enum Msg {
LoadComplete,
FrameRect(PipelineId, SubpageId, Rect<f32>),
LoadUrl(PipelineId, LoadData),
- ScriptLoadedURLInIFrame(Url, PipelineId, SubpageId, IFrameSandboxState),
+ ScriptLoadedURLInIFrame(Url, PipelineId, SubpageId, Option<SubpageId>, IFrameSandboxState),
Navigate(NavigationDirection),
PainterReady(PipelineId),
ResizedWindow(WindowSizeData),
diff --git a/components/script/dom/htmliframeelement.rs b/components/script/dom/htmliframeelement.rs
index 683c18c678a..66d0f824fa2 100644
--- a/components/script/dom/htmliframeelement.rs
+++ b/components/script/dom/htmliframeelement.rs
@@ -20,7 +20,7 @@ use dom::node::{Node, NodeHelpers, NodeTypeId, window_from_node};
use dom::urlhelper::UrlHelper;
use dom::virtualmethods::VirtualMethods;
use dom::window::Window;
-use page::IterablePage;
+use page::{IterablePage, Page};
use servo_msg::constellation_msg::{PipelineId, SubpageId, ConstellationChan};
use servo_msg::constellation_msg::IFrameSandboxState::{IFrameSandboxed, IFrameUnsandboxed};
@@ -44,7 +44,8 @@ enum SandboxAllowance {
#[dom_struct]
pub struct HTMLIFrameElement {
htmlelement: HTMLElement,
- size: Cell<Option<IFrameSize>>,
+ subpage_id: Cell<Option<SubpageId>>,
+ containing_page_pipeline_id: Cell<Option<PipelineId>>,
sandbox: Cell<Option<u8>>,
}
@@ -54,31 +55,12 @@ impl HTMLIFrameElementDerived for EventTarget {
}
}
-#[jstraceable]
-#[privatize]
-#[deriving(Copy)]
-pub struct IFrameSize {
- pipeline_id: PipelineId,
- subpage_id: SubpageId,
-}
-
-impl IFrameSize {
- #[inline]
- pub fn pipeline_id<'a>(&'a self) -> &'a PipelineId {
- &self.pipeline_id
- }
-
- #[inline]
- pub fn subpage_id<'a>(&'a self) -> &'a SubpageId {
- &self.subpage_id
- }
-}
-
pub trait HTMLIFrameElementHelpers {
fn is_sandboxed(self) -> bool;
fn get_url(self) -> Option<Url>;
/// http://www.whatwg.org/html/#process-the-iframe-attributes
fn process_the_iframe_attributes(self);
+ fn generate_new_subpage_id(self, page: &Page) -> (SubpageId, Option<SubpageId>);
}
impl<'a> HTMLIFrameElementHelpers for JSRef<'a, HTMLIFrameElement> {
@@ -100,6 +82,13 @@ impl<'a> HTMLIFrameElementHelpers for JSRef<'a, HTMLIFrameElement> {
})
}
+ fn generate_new_subpage_id(self, page: &Page) -> (SubpageId, Option<SubpageId>) {
+ let old_subpage_id = self.subpage_id.get();
+ let subpage_id = page.get_next_subpage_id();
+ self.subpage_id.set(Some(subpage_id));
+ (subpage_id, old_subpage_id)
+ }
+
fn process_the_iframe_attributes(self) {
let url = match self.get_url() {
Some(url) => url.clone(),
@@ -112,19 +101,19 @@ impl<'a> HTMLIFrameElementHelpers for JSRef<'a, HTMLIFrameElement> {
IFrameUnsandboxed
};
- // Subpage Id
let window = window_from_node(self).root();
let window = window.r();
let page = window.page();
- let subpage_id = page.get_next_subpage_id();
+ let (new_subpage_id, old_subpage_id) = self.generate_new_subpage_id(page);
- self.size.set(Some(IFrameSize {
- pipeline_id: page.id,
- subpage_id: subpage_id,
- }));
+ self.containing_page_pipeline_id.set(Some(page.id));
let ConstellationChan(ref chan) = page.constellation_chan;
- chan.send(ConstellationMsg::ScriptLoadedURLInIFrame(url, page.id, subpage_id, sandboxed));
+ chan.send(ConstellationMsg::ScriptLoadedURLInIFrame(url,
+ page.id,
+ new_subpage_id,
+ old_subpage_id,
+ sandboxed));
}
}
@@ -132,7 +121,8 @@ impl HTMLIFrameElement {
fn new_inherited(localName: DOMString, prefix: Option<DOMString>, document: JSRef<Document>) -> HTMLIFrameElement {
HTMLIFrameElement {
htmlelement: HTMLElement::new_inherited(HTMLElementTypeId::HTMLIFrameElement, localName, prefix, document),
- size: Cell::new(None),
+ subpage_id: Cell::new(None),
+ containing_page_pipeline_id: Cell::new(None),
sandbox: Cell::new(None),
}
}
@@ -144,8 +134,13 @@ impl HTMLIFrameElement {
}
#[inline]
- pub fn size(&self) -> Option<IFrameSize> {
- self.size.get()
+ pub fn containing_page_pipeline_id(&self) -> Option<PipelineId> {
+ self.containing_page_pipeline_id.get()
+ }
+
+ #[inline]
+ pub fn subpage_id(&self) -> Option<SubpageId> {
+ self.subpage_id.get()
}
}
@@ -171,11 +166,11 @@ impl<'a> HTMLIFrameElementMethods for JSRef<'a, HTMLIFrameElement> {
}
fn GetContentWindow(self) -> Option<Temporary<Window>> {
- self.size.get().and_then(|size| {
+ self.subpage_id.get().and_then(|subpage_id| {
let window = window_from_node(self).root();
let children = window.page().children.borrow();
let child = children.iter().find(|child| {
- child.subpage_id.unwrap() == size.subpage_id
+ child.subpage_id.unwrap() == subpage_id
});
child.and_then(|page| {
page.frame.borrow().as_ref().map(|frame| {