Implement Range#deleteContents

This commit is contained in:
David Zbarsky 2015-07-13 03:05:33 -04:00
parent ea690a2dff
commit 25b7c9523c
6 changed files with 116 additions and 299 deletions

View file

@ -16,6 +16,7 @@ use dom::bindings::inheritance::Castable;
use dom::bindings::inheritance::{CharacterDataTypeId, NodeTypeId};
use dom::bindings::js::{JS, MutHeap, Root, RootedReference};
use dom::bindings::reflector::{Reflector, reflect_dom_object};
use dom::bindings::trace::RootedVec;
use dom::characterdata::CharacterData;
use dom::document::Document;
use dom::documentfragment::DocumentFragment;
@ -709,6 +710,80 @@ impl RangeMethods for Range {
Ok(())
}
// https://dom.spec.whatwg.org/#dom-range-deletecontents
fn DeleteContents(&self) -> ErrorResult {
// Step 1.
if self.Collapsed() {
return Ok(());
}
// Step 2.
let start_node = self.StartContainer();
let end_node = self.EndContainer();
let start_offset = self.StartOffset();
let end_offset = self.EndOffset();
// Step 3.
if start_node == end_node {
if let Some(text) = start_node.downcast::<CharacterData>() {
return text.ReplaceData(start_offset,
end_offset - start_offset,
DOMString::from(""));
}
}
// Step 4.
let mut contained_children: RootedVec<JS<Node>> = RootedVec::new();
let ancestor = self.CommonAncestorContainer();
for child in start_node.following_nodes(ancestor.r()) {
if self.contains(child.r()) &&
!contained_children.contains(&JS::from_ref(child.GetParentNode().unwrap().r())) {
contained_children.push(JS::from_ref(child.r()));
}
}
let (new_node, new_offset) = if start_node.is_inclusive_ancestor_of(end_node.r()) {
// Step 5.
(Root::from_ref(start_node.r()), start_offset)
} else {
// Step 6.
fn compute_reference(start_node: &Node, end_node: &Node) -> (Root<Node>, u32) {
let mut reference_node = Root::from_ref(start_node);
while let Some(parent) = reference_node.GetParentNode() {
if parent.is_inclusive_ancestor_of(end_node) {
return (parent, reference_node.index())
}
reference_node = parent;
}
panic!()
}
compute_reference(start_node.r(), end_node.r())
};
// Step 7.
if let Some(text) = start_node.downcast::<CharacterData>() {
try!(text.ReplaceData(start_offset,
start_node.len() - start_offset,
DOMString::from("")));
}
// Step 8.
for child in contained_children.r() {
child.remove_self();
}
// Step 9.
if let Some(text) = end_node.downcast::<CharacterData>() {
try!(text.ReplaceData(0, end_offset, DOMString::from("")));
}
// Step 10.
try!(self.SetStart(new_node.r(), new_offset));
self.SetEnd(new_node.r(), new_offset)
}
// https://dom.spec.whatwg.org/#dom-range-surroundcontents
fn SurroundContents(&self, new_parent: &Node) -> ErrorResult {
// Step 1.