diff options
author | bors-servo <release+servo@mozilla.com> | 2014-02-20 04:28:55 -0500 |
---|---|---|
committer | bors-servo <release+servo@mozilla.com> | 2014-02-20 04:28:55 -0500 |
commit | 1f90716bc10d9134a13ac41a97d217104247010f (patch) | |
tree | 9ab55b7f70fc44c0fccdfd882b12575dee313516 /src/components/main/layout/construct.rs | |
parent | ec4c31c214724b60a41a700c4eb0cb8333e26d60 (diff) | |
parent | ed0c15a93aa9598b3f2f0bc49b8560f640960c44 (diff) | |
download | servo-1f90716bc10d9134a13ac41a97d217104247010f.tar.gz servo-1f90716bc10d9134a13ac41a97d217104247010f.zip |
auto merge of #1664 : recrack/servo/object-element, r=jdm
Support for #1636
Now, we can see eyes in acid2.html :)
Diffstat (limited to 'src/components/main/layout/construct.rs')
-rw-r--r-- | src/components/main/layout/construct.rs | 66 |
1 files changed, 53 insertions, 13 deletions
diff --git a/src/components/main/layout/construct.rs b/src/components/main/layout/construct.rs index 293ba995da3..98d33db8d26 100644 --- a/src/components/main/layout/construct.rs +++ b/src/components/main/layout/construct.rs @@ -34,14 +34,19 @@ use layout::util::{LayoutDataAccess, OpaqueNode}; use layout::wrapper::{PostorderNodeMutTraversal, TLayoutNode, ThreadSafeLayoutNode}; use gfx::font_context::FontContext; -use script::dom::element::{HTMLIframeElementTypeId, HTMLImageElementTypeId}; +use script::dom::element::{HTMLIframeElementTypeId, HTMLImageElementTypeId, HTMLObjectElementTypeId}; use script::dom::node::{CommentNodeTypeId, DoctypeNodeTypeId, DocumentFragmentNodeTypeId}; use script::dom::node::{DocumentNodeTypeId, ElementNodeTypeId, ProcessingInstructionNodeTypeId}; use script::dom::node::{TextNodeTypeId}; use style::computed_values::{display, position, float, white_space}; use style::ComputedValues; +use servo_util::namespace; +use servo_util::url::parse_url; +use servo_util::url::is_image_data; +use extra::url::Url; use extra::arc::Arc; + use std::cell::RefCell; use std::util; use std::num::Zero; @@ -220,16 +225,20 @@ pub struct FlowConstructor<'a> { /// The font context. font_context: ~FontContext, + + /// The URL of the page. + url: &'a Url, } impl<'fc> FlowConstructor<'fc> { /// Creates a new flow constructor. - pub fn init<'a>(layout_context: &'a mut LayoutContext) -> FlowConstructor<'a> { + pub fn init<'a>(layout_context: &'a mut LayoutContext, url: &'a Url) -> FlowConstructor<'a> { let font_context = ~FontContext::new(layout_context.font_context_info.clone()); FlowConstructor { layout_context: layout_context, next_flow_id: RefCell::new(0), font_context: font_context, + url: url, } } @@ -241,14 +250,13 @@ impl<'fc> FlowConstructor<'fc> { } /// Builds the `ImageBoxInfo` for the given image. This is out of line to guide inlining. - fn build_box_info_for_image(&mut self, node: ThreadSafeLayoutNode) -> Option<ImageBoxInfo> { - // FIXME(pcwalton): Don't copy URLs. - match node.image_url() { - None => None, + fn build_box_info_for_image(&mut self, node: ThreadSafeLayoutNode, url: Option<Url>) -> SpecificBoxInfo { + match url { + None => GenericBox, Some(url) => { // FIXME(pcwalton): The fact that image boxes store the cache within them makes // little sense to me. - Some(ImageBoxInfo::new(&node, url, self.layout_context.image_cache.clone())) + ImageBox(ImageBoxInfo::new(&node, url, self.layout_context.image_cache.clone())) } } } @@ -257,13 +265,11 @@ impl<'fc> FlowConstructor<'fc> { pub fn build_specific_box_info_for_node(&mut self, node: ThreadSafeLayoutNode) -> SpecificBoxInfo { match node.type_id() { - ElementNodeTypeId(HTMLImageElementTypeId) => { - match self.build_box_info_for_image(node) { - None => GenericBox, - Some(image_box_info) => ImageBox(image_box_info), - } - } + ElementNodeTypeId(HTMLImageElementTypeId) => self.build_box_info_for_image(node, node.image_url()), ElementNodeTypeId(HTMLIframeElementTypeId) => IframeBox(IframeBoxInfo::new(&node)), + ElementNodeTypeId(HTMLObjectElementTypeId) => { + self.build_box_info_for_image(node, node.get_object_data(self.url)) + } TextNodeTypeId => UnscannedTextBox(UnscannedTextBoxInfo::new(&node)), _ => GenericBox, } @@ -709,6 +715,7 @@ impl<'ln> NodeUtils for ThreadSafeLayoutNode<'ln> { DocumentFragmentNodeTypeId | DocumentNodeTypeId(_) | ElementNodeTypeId(HTMLImageElementTypeId) => true, + ElementNodeTypeId(HTMLObjectElementTypeId) => self.has_object_data(), ElementNodeTypeId(_) => false, } } @@ -761,6 +768,39 @@ impl<'ln> NodeUtils for ThreadSafeLayoutNode<'ln> { } } +/// Methods for interacting with HTMLObjectElement nodes +trait ObjectElement { + /// Returns None if this node is not matching attributes. + fn get_type_and_data(self) -> (Option<&'static str>, Option<&'static str>); + + /// Returns true if this node has object data that is correct uri. + fn has_object_data(self) -> bool; + + /// Returns the "data" attribute value parsed as a URL + fn get_object_data(self, base_url: &Url) -> Option<Url>; +} + +impl<'ln> ObjectElement for ThreadSafeLayoutNode<'ln> { + fn get_type_and_data(self) -> (Option<&'static str>, Option<&'static str>) { + (self.with_element(|e| { e.get_attr(&namespace::Null, "type") } ), + self.with_element(|e| { e.get_attr(&namespace::Null, "data") } )) + } + + fn has_object_data(self) -> bool { + match self.get_type_and_data() { + (None, Some(uri)) => is_image_data(uri), + _ => false + } + } + + fn get_object_data(self, base_url: &Url) -> Option<Url> { + match self.get_type_and_data() { + (None, Some(uri)) if is_image_data(uri) => Some(parse_url(uri, Some(base_url.clone()))), + _ => None + } + } +} + /// Strips ignorable whitespace from the start of a list of boxes. fn strip_ignorable_whitespace_from_start(opt_boxes: &mut Option<~[Box]>) { match util::replace(opt_boxes, None) { |