Skip to content

Commit

Permalink
Implement Range#deleteContents
Browse files Browse the repository at this point in the history
  • Loading branch information
dzbarsky committed Nov 25, 2015
1 parent ea690a2 commit 25b7c95
Show file tree
Hide file tree
Showing 6 changed files with 114 additions and 297 deletions.
75 changes: 75 additions & 0 deletions components/script/dom/range.rs
Expand Up @@ -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;
Expand Down Expand Up @@ -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.
Expand Down
4 changes: 2 additions & 2 deletions components/script/dom/webidls/Range.webidl
Expand Up @@ -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]
Expand Down
21 changes: 6 additions & 15 deletions tests/wpt/metadata/dom/interfaces.html.ini
Expand Up @@ -216,27 +216,12 @@
[Comment interface: existence and properties of interface object]
expected: FAIL
[Range interface: operation deleteContents()]
expected: FAIL
[Range interface: stringifier]
expected: FAIL
[Range interface: document.createRange() must inherit property "deleteContents" with the proper type (20)]
expected: FAIL
[Range interface: detachedRange must inherit property "deleteContents" with the proper type (20)]
expected: FAIL
[NodeFilter interface: existence and properties of interface object]
expected: FAIL
[DOMSettableTokenList interface: existence and properties of interface object]
expected: FAIL
[DOMSettableTokenList interface object length]
expected: FAIL
[DOMSettableTokenList interface: existence and properties of interface prototype object]
expected: FAIL
Expand All @@ -258,3 +243,9 @@
[Document interface: xmlDoc must inherit property "queryAll" with the proper type (36)]
expected: FAIL

[DOMSettableTokenList interface: existence and properties of interface object]
expected: FAIL

[DOMSettableTokenList interface object length]
expected: FAIL

0 comments on commit 25b7c95

Please sign in to comment.