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>,
}
pub struct AbstractNodeChildrenIterator<View> {
priv current_node: Option<AbstractNode<View>>,
}
/// An HTML node.
///
/// `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
/// 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 {
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> {

View file

@ -275,24 +275,7 @@ pub fn parse_html(url: Url,
parser.set_document_node(unsafe { root.to_hubbub_node() });
parser.enable_scripting(true);
// Performs various actions necessary after appending has taken place. Currently, this
// 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());
let (css_chan2, css_chan3, js_chan2) = (css_chan.clone(), css_chan.clone(), js_chan.clone());
parser.set_tree_handler(~hubbub::TreeHandler {
create_comment: |data: ~str| {
debug!("create comment");
@ -393,15 +376,32 @@ pub fn parse_html(url: Url,
Node::as_abstract_node(~Text::new(data)).to_hubbub_node()
}
},
ref_node: |_| {},
unref_node: |_| {},
ref_node: |_| { debug!("ref 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| {
unsafe {
debug!("append child %x %x", cast::transmute(parent), cast::transmute(child));
let parent: AbstractNode<ScriptView> = NodeWrapping::from_hubbub_node(parent);
let child: AbstractNode<ScriptView> = NodeWrapping::from_hubbub_node(child);
parent.add_child(child);
append_hook(parent, 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>