aboutsummaryrefslogtreecommitdiffstats
path: root/components/script
diff options
context:
space:
mode:
authorDavid Zbarsky <dzbarsky@gmail.com>2015-07-13 03:05:33 -0400
committerDavid Zbarsky <dzbarsky@gmail.com>2015-11-25 00:02:25 -0800
commit25b7c9523c535ca6b57d0c9286a51cdf396fac8c (patch)
tree063e6ab9418965da4ca7553daa7bef93a64e3412 /components/script
parentea690a2dff64d1cb4eb668473d62f1bbcb19f7c8 (diff)
downloadservo-25b7c9523c535ca6b57d0c9286a51cdf396fac8c.tar.gz
servo-25b7c9523c535ca6b57d0c9286a51cdf396fac8c.zip
Implement Range#deleteContents
Diffstat (limited to 'components/script')
-rw-r--r--components/script/dom/range.rs75
-rw-r--r--components/script/dom/webidls/Range.webidl4
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]