From bd5526de940c4cdd2413666be56ca86860f493d9 Mon Sep 17 00:00:00 2001 From: Tim Kuehn Date: Thu, 8 Aug 2013 12:43:11 -0700 Subject: [PATCH] add iframe support --- .../main/compositing/compositor_layer.rs | 37 +++++++++---------- src/components/main/constellation.rs | 37 ++++++++++--------- src/components/main/layout/block.rs | 8 ++-- src/components/main/layout/float.rs | 3 ++ src/components/main/layout/inline.rs | 4 ++ src/components/script/dom/element.rs | 1 - .../script/dom/htmliframeelement.rs | 10 +++-- .../script/html/hubbub_html_parser.rs | 6 +-- 8 files changed, 59 insertions(+), 47 deletions(-) diff --git a/src/components/main/compositing/compositor_layer.rs b/src/components/main/compositing/compositor_layer.rs index b4e79cf6ac2..881a781eb26 100644 --- a/src/components/main/compositing/compositor_layer.rs +++ b/src/components/main/compositing/compositor_layer.rs @@ -82,25 +82,23 @@ impl CompositorLayer { } } - pub fn from_frame_tree(frame_tree: SendableFrameTree, tile_size: uint, max_mem: Option) -> CompositorLayer { + pub fn from_frame_tree(frame_tree: SendableFrameTree, + tile_size: uint, + max_mem: Option) -> CompositorLayer { let SendableFrameTree { pipeline, children } = frame_tree; - CompositorLayer { - pipeline: pipeline, - page_size: None, - scroll_offset: Point2D(0f32, 0f32), - children: (do children.consume_iter().transform |child| { - let SendableChildFrameTree { frame_tree, rect } = child; - let container = @mut ContainerLayer(); - container.scissor = rect; - CompositorLayerChild { - child: ~CompositorLayer::from_frame_tree(frame_tree, tile_size, max_mem), - container: container, - } - }).collect(), - quadtree: NoTree(tile_size, max_mem), - root_layer: @mut ContainerLayer(), - hidden: true, - } + let mut layer = CompositorLayer::new(pipeline, None, tile_size, max_mem); + layer.children = (do children.consume_iter().transform |child| { + let SendableChildFrameTree { frame_tree, rect } = child; + let container = @mut ContainerLayer(); + container.scissor = rect; + CompositorLayerChild { + child: ~CompositorLayer::from_frame_tree(frame_tree, + tile_size, + max_mem), + container: container, + } + }).collect(); + layer } // Move the layer by as relative specified amount in page coordinates. Does not change @@ -188,7 +186,8 @@ impl CompositorLayer { let mut redisplay: bool; { // block here to prevent double mutable borrow of self let quadtree = match self.quadtree { - NoTree(_, _) => fail!("CompositorLayer: cannot get buffer request, no quadtree initialized"), + NoTree(_, _) => fail!("CompositorLayer: cannot get buffer request for %?, + no quadtree initialized", self.pipeline.id), Tree(ref mut quadtree) => quadtree, }; let (request, r) = quadtree.get_tile_rects_page(rect, scale); diff --git a/src/components/main/constellation.rs b/src/components/main/constellation.rs index 80bc29dad04..b16e3fb76d6 100644 --- a/src/components/main/constellation.rs +++ b/src/components/main/constellation.rs @@ -402,24 +402,27 @@ impl Constellation { let mut already_sent = HashSet::new(); // If the subframe is in the current frame tree, the compositor needs the new size - let source_frame = self.current_frame().unwrap().find_mut(pipeline_id); - for source_frame in source_frame.iter() { - for child_frame_tree in source_frame.children.mut_iter() { - let pipeline = &child_frame_tree.frame_tree.pipeline; - if pipeline.subpage_id.expect("Constellation: child frame does not have a - subpage id. This should not be possible.") == subpage_id { - child_frame_tree.rect = Some(rect.clone()); - let Rect { size: Size2D { width, height }, _ } = rect; - pipeline.script_chan.send(SendEventMsg(pipeline.id.clone(), - ResizeEvent(width as uint, - height as uint))); - self.compositor_chan.send(ResizeLayer(pipeline.id, rect.size)); - already_sent.insert(pipeline.id.clone()); - break; - } - } + for current_frame in self.current_frame().iter() { + debug!("Constellation: Sending size for frame in current frame tree."); + let source_frame = current_frame.find_mut(pipeline_id); + for source_frame.iter().advance |source_frame| { + for child_frame_tree in source_frame.children.mut_iter() { + let pipeline = &child_frame_tree.frame_tree.pipeline; + if pipeline.subpage_id.expect("Constellation: child frame does not have a + subpage id. This should not be possible.") == subpage_id { + child_frame_tree.rect = Some(rect.clone()); + let Rect { size: Size2D { width, height }, _ } = rect; + pipeline.script_chan.send(SendEventMsg(pipeline.id.clone(), + ResizeEvent(width as uint, + height as uint))); + self.compositor_chan.send(ResizeLayer(pipeline.id, rect.size)); + already_sent.insert(pipeline.id.clone()); + break; + } + } + } } - // Go through the navigation context and tell each associated pipeline to resize. + // Traverse the navigation context and pending frames and tell each associated pipeline to resize. let frame_trees: ~[@mut FrameTree] = { let matching_navi_frames = self.navigation_context.find_all(pipeline_id); let matching_pending_frames = do self.pending_frames.iter().filter_map |frame_change| { diff --git a/src/components/main/layout/block.rs b/src/components/main/layout/block.rs index bd20995348e..0379689d5fb 100644 --- a/src/components/main/layout/block.rs +++ b/src/components/main/layout/block.rs @@ -17,7 +17,7 @@ use geom::point::Point2D; use geom::size::Size2D; use geom::rect::Rect; use gfx::display_list::DisplayList; -use gfx::geometry::Au; +use gfx::geometry::{Au, to_frac_px}; use gfx::geometry; use servo_util::tree::TreeNodeRef; @@ -379,8 +379,10 @@ impl BlockFlowData { box.with_model(|model| model.noncontent_height()) }; do self.common.node.with_mut_iframe_element |iframe_element| { - iframe_element.size.get_mut_ref().set_rect(Rect(Point2D(x.to_f32(), y.to_f32()), - Size2D(w.to_f32(), h.to_f32()))); + iframe_element.size.get_mut_ref().set_rect(Rect(Point2D(to_frac_px(x) as f32, + to_frac_px(y) as f32), + Size2D(to_frac_px(w) as f32, + to_frac_px(h) as f32))); } } diff --git a/src/components/main/layout/float.rs b/src/components/main/layout/float.rs index bfabef57526..efd46b80e60 100644 --- a/src/components/main/layout/float.rs +++ b/src/components/main/layout/float.rs @@ -295,6 +295,9 @@ impl FloatFlowData { list: &Cell>) -> bool { + if self.common.node.is_iframe_element() { + println("float iframe"); + } let abs_rect = Rect(self.common.abs_position, self.common.position.size); if !abs_rect.intersects(dirty) { return false; diff --git a/src/components/main/layout/inline.rs b/src/components/main/layout/inline.rs index d1a9c5e9708..42f0a69b625 100644 --- a/src/components/main/layout/inline.rs +++ b/src/components/main/layout/inline.rs @@ -755,6 +755,10 @@ impl InlineFlowData { list: &Cell>) -> bool { + if self.common.node.is_iframe_element() { + println("inline iframe"); + } + let abs_rect = Rect(self.common.abs_position, self.common.position.size); if !abs_rect.intersects(dirty) { return false; diff --git a/src/components/script/dom/element.rs b/src/components/script/dom/element.rs index e71e7b87e9d..3aa30ea7dee 100644 --- a/src/components/script/dom/element.rs +++ b/src/components/script/dom/element.rs @@ -44,7 +44,6 @@ use newcss::stylesheet::Stylesheet; use js::jsapi::{JSContext, JSObject}; -use std::util::replace; use std::cell::Cell; use std::comm; use std::str::eq_slice; diff --git a/src/components/script/dom/htmliframeelement.rs b/src/components/script/dom/htmliframeelement.rs index 8fa028baff2..4b8199e0bdd 100644 --- a/src/components/script/dom/htmliframeelement.rs +++ b/src/components/script/dom/htmliframeelement.rs @@ -7,26 +7,28 @@ use dom::document::AbstractDocument; use dom::htmlelement::HTMLElement; use dom::windowproxy::WindowProxy; use geom::size::Size2D; +use geom::rect::Rect; -use servo_msg::constellation_msg::SubpageId; +use servo_msg::constellation_msg::{ConstellationChan, FrameRectMsg, PipelineId, SubpageId}; use std::comm::ChanOne; use extra::url::Url; +use std::util::replace; pub struct HTMLIFrameElement { parent: HTMLElement, frame: Option, - size: Option, + size: Option, } -struct IframeSize { +struct IFrameSize { pipeline_id: PipelineId, subpage_id: SubpageId, future_chan: Option>>, constellation_chan: ConstellationChan, } -impl IframeSize { +impl IFrameSize { pub fn set_rect(&mut self, rect: Rect) { let future_chan = replace(&mut self.future_chan, None); do future_chan.map_consume |future_chan| { diff --git a/src/components/script/html/hubbub_html_parser.rs b/src/components/script/html/hubbub_html_parser.rs index dce79fe58ae..f78807a8a35 100644 --- a/src/components/script/html/hubbub_html_parser.rs +++ b/src/components/script/html/hubbub_html_parser.rs @@ -30,7 +30,7 @@ use dom::htmlanchorelement::HTMLAnchorElement; use dom::htmlbodyelement::HTMLBodyElement; use dom::htmlcanvaselement::HTMLCanvasElement; use dom::htmlhrelement::HTMLHRElement; -use dom::htmliframeelement::HTMLIFrameElement; +use dom::htmliframeelement::{IFrameSize, HTMLIFrameElement}; use dom::htmlimageelement::HTMLImageElement; use dom::htmlmetaelement::HTMLMetaElement; use dom::htmlolistelement::HTMLOListElement; @@ -253,7 +253,7 @@ fn build_element_from_tag(cx: *JSContext, tag: &str) -> AbstractNode handle_element!(cx, tag, "ul", HTMLUListElementTypeId, HTMLUListElement, []); handle_element!(cx, tag, "img", HTMLImageElementTypeId, HTMLImageElement, [(image: None)]); - handle_element!(cx, tag, "iframe", HTMLIframeElementTypeId, HTMLIframeElement, [(frame: None), (size: None)]); + handle_element!(cx, tag, "iframe", HTMLIframeElementTypeId, HTMLIFrameElement, [(frame: None), (size: None)]); handle_element!(cx, tag, "h1", HTMLHeadingElementTypeId, HTMLHeadingElement, [(level: Heading1)]); handle_element!(cx, tag, "h2", HTMLHeadingElementTypeId, HTMLHeadingElement, [(level: Heading2)]); @@ -395,7 +395,7 @@ pub fn parse_html(cx: *JSContext, unsafe { (*page).id } }; - iframe_element.size = Some(IframeSize { + iframe_element.size = Some(IFrameSize { pipeline_id: pipeline_id, subpage_id: subpage_id, future_chan: Some(chan),