auto merge of #606 : metajack/servo/broken-inline-css, r=jdm

This add a new children iterator to abstract node and fixes a bug where inline stylesheets got parsed piecewise due to \r style line endings.
This commit is contained in:
bors-servo 2013-07-19 14:45:19 -07:00
commit cca33c2027
3 changed files with 43 additions and 22 deletions

View file

@ -46,6 +46,10 @@ pub struct AbstractNode<View> {
priv obj: *mut Node<View>, priv obj: *mut Node<View>,
} }
pub struct AbstractNodeChildrenIterator<View> {
priv current_node: Option<AbstractNode<View>>,
}
/// An HTML node. /// An HTML node.
/// ///
/// `View` describes extra data associated with this node that this task has access to. For /// `View` describes extra data associated with this node that this task has access to. For
@ -200,7 +204,7 @@ impl<View> TreeNodeRef<Node<View>> for AbstractNode<View> {
} }
} }
impl<View> AbstractNode<View> { impl<'self, View> AbstractNode<View> {
// Unsafe accessors // Unsafe accessors
/// Returns the layout data, unsafely cast to whatever type layout wishes. Only layout is /// Returns the layout data, unsafely cast to whatever type layout wishes. Only layout is
@ -396,6 +400,22 @@ impl<View> AbstractNode<View> {
pub fn debug_str(&self) -> ~str { pub fn debug_str(&self) -> ~str {
fmt!("%?", self.type_id()) fmt!("%?", self.type_id())
} }
pub fn children(&self) -> AbstractNodeChildrenIterator<View> {
AbstractNodeChildrenIterator {
current_node: self.first_child(),
}
}
}
impl<View> Iterator<AbstractNode<View>> for AbstractNodeChildrenIterator<View> {
pub fn next(&mut self) -> Option<AbstractNode<View>> {
self.current_node = match self.current_node {
None => None,
Some(node) => node.next_sibling(),
};
self.current_node
}
} }
impl Node<ScriptView> { impl Node<ScriptView> {

View file

@ -275,24 +275,7 @@ pub fn parse_html(url: Url,
parser.set_document_node(unsafe { root.to_hubbub_node() }); parser.set_document_node(unsafe { root.to_hubbub_node() });
parser.enable_scripting(true); parser.enable_scripting(true);
// Performs various actions necessary after appending has taken place. Currently, this let (css_chan2, css_chan3, js_chan2) = (css_chan.clone(), css_chan.clone(), js_chan.clone());
// consists of processing inline stylesheets, but in the future it might perform
// prefetching, etc.
let css_chan2 = css_chan.clone();
let append_hook: ~fn(AbstractNode<ScriptView>, AbstractNode<ScriptView>) = |parent_node, child_node| {
if parent_node.is_style_element() && child_node.is_text() {
debug!("found inline CSS stylesheet");
let url = url::from_str("http://example.com/"); // FIXME
let url_cell = Cell::new(url);
do child_node.with_imm_text |text_node| {
let data = text_node.parent.data.to_str(); // FIXME: Bad copy.
let provenance = InlineProvenance(result::unwrap(url_cell.take()), data);
css_chan2.send(CSSTaskNewFile(provenance));
}
}
};
let (css_chan2, js_chan2) = (css_chan.clone(), js_chan.clone());
parser.set_tree_handler(~hubbub::TreeHandler { parser.set_tree_handler(~hubbub::TreeHandler {
create_comment: |data: ~str| { create_comment: |data: ~str| {
debug!("create comment"); debug!("create comment");
@ -393,15 +376,32 @@ pub fn parse_html(url: Url,
Node::as_abstract_node(~Text::new(data)).to_hubbub_node() Node::as_abstract_node(~Text::new(data)).to_hubbub_node()
} }
}, },
ref_node: |_| {}, ref_node: |_| { debug!("ref node"); },
unref_node: |_| {}, unref_node: |node| {
// check for the end of a <style> so we can submit all the text to the parser.
unsafe {
let node: AbstractNode<ScriptView> = NodeWrapping::from_hubbub_node(node);
if node.is_style_element() {
let url = url::from_str("http://example.com/"); // FIXME
let url_cell = Cell::new(url);
let mut data = ~[];
for node.children().advance |child| {
do child.with_imm_text() |text| {
data.push(text.parent.data.to_str()); // FIXME: Bad copy.
}
}
let provenance = InlineProvenance(result::unwrap(url_cell.take()), data.concat());
css_chan3.send(CSSTaskNewFile(provenance));
}
}
},
append_child: |parent: hubbub::NodeDataPtr, child: hubbub::NodeDataPtr| { append_child: |parent: hubbub::NodeDataPtr, child: hubbub::NodeDataPtr| {
unsafe { unsafe {
debug!("append child %x %x", cast::transmute(parent), cast::transmute(child)); debug!("append child %x %x", cast::transmute(parent), cast::transmute(child));
let parent: AbstractNode<ScriptView> = NodeWrapping::from_hubbub_node(parent); let parent: AbstractNode<ScriptView> = NodeWrapping::from_hubbub_node(parent);
let child: AbstractNode<ScriptView> = NodeWrapping::from_hubbub_node(child); let child: AbstractNode<ScriptView> = NodeWrapping::from_hubbub_node(child);
parent.add_child(child); parent.add_child(child);
append_hook(parent, child);
} }
child child
}, },

View file

@ -0,0 +1 @@
<html> <head> <style> p { color: white; } p.blue { background-color: blue; } p.red { background-color: red; } </style> </head> <body> <p class="blue"> I am a paragraph. My background color is blue. </p> <p class="red"> I am a paragraph. My background color is red. </p> </body> </html>