(parent.first_child.get().unwrap(), self));
parent.first_child.set(Some(new_sibling));
}
self.previous_sibling.set(Some(new_sibling));
}
}
impl<'arena> Sink<'arena> {
fn new_node(&self, data: NodeData<'arena>) -> Ref<'arena> {
self.arena.alloc(Node::new(data))
}
fn append_common(&self, child: NodeOrText[>, previous: P, append: A)
where P: FnOnce() -> Option][>,
A: FnOnce(Ref<'arena>),
{
let new_node = match child {
NodeOrText::AppendText(text) => {
// Append to an existing Text node if we have one.
if let Some(&Node { data: NodeData::Text { ref contents }, .. }) = previous() {
contents.borrow_mut().push_tendril(&text);
return
}
self.new_node(NodeData::Text { contents: RefCell::new(text) })
}
NodeOrText::AppendNode(node) => node
};
append(new_node)
}
}
impl<'arena> TreeSink for Sink<'arena> {
type Handle = Ref<'arena>;
type Output = Ref<'arena>;
fn finish(self) -> Ref<'arena> {
self.document
}
fn parse_error(&mut self, _: Cow<'static, str>) {}
fn get_document(&mut self) -> Ref<'arena> {
self.document
}
fn set_quirks_mode(&mut self, mode: QuirksMode) {
self.quirks_mode = mode;
}
fn same_node(&self, x: &Ref<'arena>, y: &Ref<'arena>) -> bool {
ptr::eq::(*x, *y)
}
fn elem_name<'a>(&self, target: &'a Ref<'arena>) -> ExpandedName<'a> {
match target.data {
NodeData::Element { ref name, .. } => name.expanded(),
_ => panic!("not an element!"),
}
}
fn get_template_contents(&mut self, target: &Ref<'arena>) -> Ref<'arena> {
if let NodeData::Element { template_contents: Some(ref contents), .. } = target.data {
contents
} else {
panic!("not a template element!")
}
}
fn is_mathml_annotation_xml_integration_point(&self, target: &Ref<'arena>) -> bool {
if let NodeData::Element { mathml_annotation_xml_integration_point, .. } = target.data {
mathml_annotation_xml_integration_point
} else {
panic!("not an element!")
}
}
fn create_element(&mut self, name: QualName, attrs: Vec, flags: ElementFlags) -> Ref<'arena> {
self.new_node(NodeData::Element {
name: name,
attrs: RefCell::new(attrs),
template_contents: if flags.template {
Some(self.new_node(NodeData::Document))
} else {
None
},
mathml_annotation_xml_integration_point: flags.mathml_annotation_xml_integration_point,
})
}
fn create_comment(&mut self, text: StrTendril) -> Ref<'arena> {
self.new_node(NodeData::Comment { contents: text })
}
fn create_pi(&mut self, target: StrTendril, data: StrTendril) -> Ref<'arena> {
self.new_node(NodeData::ProcessingInstruction { target: target, contents: data })
}
fn append(&mut self, parent: &Ref<'arena>, child: NodeOrText][>) {
self.append_common(
child,
|| parent.last_child.get(),
|new_node| parent.append(new_node)
)
}
fn append_before_sibling(&mut self, sibling: &Ref<'arena>, child: NodeOrText][>) {
self.append_common(
child,
|| sibling.previous_sibling.get(),
|new_node| sibling.insert_before(new_node)
)
}
fn append_based_on_parent_node(&mut self, element: &Ref<'arena>,
prev_element: &Ref<'arena>, child: NodeOrText][>) {
if element.parent.get().is_some() {
self.append_before_sibling(element, child)
} else {
self.append(prev_element, child)
}
}
fn append_doctype_to_document(&mut self,
name: StrTendril,
public_id: StrTendril,
system_id: StrTendril) {
self.document.append(self.new_node(NodeData::Doctype {
name: name,
public_id: public_id,
system_id: system_id
}))
}
fn add_attrs_if_missing(&mut self, target: &Ref<'arena>, attrs: Vec) {
let mut existing = if let NodeData::Element { ref attrs, .. } = target.data {
attrs.borrow_mut()
} else {
panic!("not an element")
};
let existing_names = existing.iter().map(|e| e.name.clone()).collect::>();
existing.extend(attrs.into_iter().filter(|attr| {
!existing_names.contains(&attr.name)
}));
}
fn remove_from_parent(&mut self, target: &Ref<'arena>) {
target.detach()
}
fn reparent_children(&mut self, node: &Ref<'arena>, new_parent: &Ref<'arena>) {
let mut next_child = node.first_child.get();
while let Some(child) = next_child {
debug_assert!(ptr::eq::(child.parent.get().unwrap(), *node));
next_child = child.next_sibling.get();
new_parent.append(child)
}
}
}
]