diff options
Diffstat (limited to 'components/script')
-rw-r--r-- | components/script/dom/range.rs | 75 | ||||
-rw-r--r-- | components/script/dom/webidls/Range.webidl | 4 |
2 files changed, 77 insertions, 2 deletions
diff --git a/components/script/dom/range.rs b/components/script/dom/range.rs index 6175ba4383e..efb27e3cfcd 100644 --- a/components/script/dom/range.rs +++ b/components/script/dom/range.rs @@ -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. diff --git a/components/script/dom/webidls/Range.webidl b/components/script/dom/webidls/Range.webidl index 0cf978115fa..1d91c89b505 100644 --- a/components/script/dom/webidls/Range.webidl +++ b/components/script/dom/webidls/Range.webidl @@ -48,8 +48,8 @@ interface Range { const unsigned short END_TO_START = 3; [Pure, Throws] short compareBoundaryPoints(unsigned short how, Range sourceRange); - // [Throws] - // void deleteContents(); + [Throws] + void deleteContents(); [NewObject, Throws] DocumentFragment extractContents(); [NewObject, Throws] |