diff options
author | David Zbarsky <dzbarsky@gmail.com> | 2015-07-13 03:05:33 -0400 |
---|---|---|
committer | David Zbarsky <dzbarsky@gmail.com> | 2015-11-25 00:02:25 -0800 |
commit | 25b7c9523c535ca6b57d0c9286a51cdf396fac8c (patch) | |
tree | 063e6ab9418965da4ca7553daa7bef93a64e3412 | |
parent | ea690a2dff64d1cb4eb668473d62f1bbcb19f7c8 (diff) | |
download | servo-25b7c9523c535ca6b57d0c9286a51cdf396fac8c.tar.gz servo-25b7c9523c535ca6b57d0c9286a51cdf396fac8c.zip |
Implement Range#deleteContents
-rw-r--r-- | components/script/dom/range.rs | 75 | ||||
-rw-r--r-- | components/script/dom/webidls/Range.webidl | 4 | ||||
-rw-r--r-- | tests/wpt/metadata/dom/interfaces.html.ini | 21 | ||||
-rw-r--r-- | tests/wpt/metadata/dom/ranges/Range-deleteContents.html.ini | 287 | ||||
-rw-r--r-- | tests/wpt/mozilla/meta/MANIFEST.json | 6 | ||||
-rw-r--r-- | tests/wpt/mozilla/tests/mozilla/range_deleteContents.html | 18 |
6 files changed, 114 insertions, 297 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] diff --git a/tests/wpt/metadata/dom/interfaces.html.ini b/tests/wpt/metadata/dom/interfaces.html.ini index 156dc6787dd..5746a9bfdac 100644 --- a/tests/wpt/metadata/dom/interfaces.html.ini +++ b/tests/wpt/metadata/dom/interfaces.html.ini @@ -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 @@ -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 + diff --git a/tests/wpt/metadata/dom/ranges/Range-deleteContents.html.ini b/tests/wpt/metadata/dom/ranges/Range-deleteContents.html.ini index 13ac404dcf0..4bbb956a7fa 100644 --- a/tests/wpt/metadata/dom/ranges/Range-deleteContents.html.ini +++ b/tests/wpt/metadata/dom/ranges/Range-deleteContents.html.ini @@ -1,365 +1,92 @@ [Range-deleteContents.html] type: testharness - [Detached Range] - expected: FAIL - - [Resulting DOM for range 0 [paras[0\].firstChild, 0, paras[0\].firstChild, 0\]] - expected: FAIL - - [Resulting cursor position for range 0 [paras[0\].firstChild, 0, paras[0\].firstChild, 0\]] - expected: FAIL - - [Resulting DOM for range 1 [paras[0\].firstChild, 0, paras[0\].firstChild, 1\]] - expected: FAIL - [Resulting cursor position for range 1 [paras[0\].firstChild, 0, paras[0\].firstChild, 1\]] expected: FAIL - [Resulting DOM for range 2 [paras[0\].firstChild, 2, paras[0\].firstChild, 8\]] - expected: FAIL - [Resulting cursor position for range 2 [paras[0\].firstChild, 2, paras[0\].firstChild, 8\]] expected: FAIL - [Resulting DOM for range 3 [paras[0\].firstChild, 2, paras[0\].firstChild, 9\]] - expected: FAIL - [Resulting cursor position for range 3 [paras[0\].firstChild, 2, paras[0\].firstChild, 9\]] expected: FAIL - [Resulting DOM for range 4 [paras[1\].firstChild, 0, paras[1\].firstChild, 0\]] - expected: FAIL - - [Resulting cursor position for range 4 [paras[1\].firstChild, 0, paras[1\].firstChild, 0\]] - expected: FAIL - - [Resulting DOM for range 5 [paras[1\].firstChild, 2, paras[1\].firstChild, 9\]] - expected: FAIL - [Resulting cursor position for range 5 [paras[1\].firstChild, 2, paras[1\].firstChild, 9\]] expected: FAIL - [Resulting DOM for range 6 [detachedPara1.firstChild, 0, detachedPara1.firstChild, 0\]] - expected: FAIL - - [Resulting cursor position for range 6 [detachedPara1.firstChild, 0, detachedPara1.firstChild, 0\]] - expected: FAIL - - [Resulting DOM for range 7 [detachedPara1.firstChild, 2, detachedPara1.firstChild, 8\]] - expected: FAIL - [Resulting cursor position for range 7 [detachedPara1.firstChild, 2, detachedPara1.firstChild, 8\]] expected: FAIL - [Resulting DOM for range 8 [foreignPara1.firstChild, 0, foreignPara1.firstChild, 0\]] - expected: FAIL - - [Resulting cursor position for range 8 [foreignPara1.firstChild, 0, foreignPara1.firstChild, 0\]] - expected: FAIL - - [Resulting DOM for range 9 [foreignPara1.firstChild, 2, foreignPara1.firstChild, 8\]] - expected: FAIL - [Resulting cursor position for range 9 [foreignPara1.firstChild, 2, foreignPara1.firstChild, 8\]] expected: FAIL - [Resulting DOM for range 10 [document.documentElement, 0, document.documentElement, 1\]] - expected: FAIL - - [Resulting cursor position for range 10 [document.documentElement, 0, document.documentElement, 1\]] - expected: FAIL - - [Resulting DOM for range 11 [document.documentElement, 0, document.documentElement, 2\]] - expected: FAIL - - [Resulting cursor position for range 11 [document.documentElement, 0, document.documentElement, 2\]] - expected: FAIL - - [Resulting DOM for range 12 [document.documentElement, 1, document.documentElement, 2\]] - expected: FAIL - - [Resulting cursor position for range 12 [document.documentElement, 1, document.documentElement, 2\]] - expected: FAIL - - [Resulting DOM for range 13 [document.head, 1, document.head, 1\]] - expected: FAIL - - [Resulting cursor position for range 13 [document.head, 1, document.head, 1\]] - expected: FAIL - - [Resulting DOM for range 14 [document.body, 4, document.body, 5\]] - expected: FAIL - - [Resulting cursor position for range 14 [document.body, 4, document.body, 5\]] - expected: FAIL - - [Resulting DOM for range 15 [foreignDoc.documentElement, 0, foreignDoc.documentElement, 1\]] - expected: FAIL - - [Resulting cursor position for range 15 [foreignDoc.documentElement, 0, foreignDoc.documentElement, 1\]] - expected: FAIL - - [Resulting DOM for range 16 [paras[0\], 0, paras[0\], 1\]] - expected: FAIL - - [Resulting cursor position for range 16 [paras[0\], 0, paras[0\], 1\]] - expected: FAIL - - [Resulting DOM for range 17 [detachedPara1, 0, detachedPara1, 1\]] - expected: FAIL - - [Resulting cursor position for range 17 [detachedPara1, 0, detachedPara1, 1\]] - expected: FAIL - - [Resulting DOM for range 18 [paras[0\].firstChild, 0, paras[1\].firstChild, 0\]] - expected: FAIL - [Resulting cursor position for range 18 [paras[0\].firstChild, 0, paras[1\].firstChild, 0\]] expected: FAIL - [Resulting DOM for range 19 [paras[0\].firstChild, 0, paras[1\].firstChild, 8\]] - expected: FAIL - [Resulting cursor position for range 19 [paras[0\].firstChild, 0, paras[1\].firstChild, 8\]] expected: FAIL - [Resulting DOM for range 20 [paras[0\].firstChild, 3, paras[3\], 1\]] - expected: FAIL - [Resulting cursor position for range 20 [paras[0\].firstChild, 3, paras[3\], 1\]] expected: FAIL - [Resulting DOM for range 21 [paras[0\], 0, paras[0\].firstChild, 7\]] - expected: FAIL - - [Resulting cursor position for range 21 [paras[0\], 0, paras[0\].firstChild, 7\]] - expected: FAIL - - [Resulting DOM for range 22 [testDiv, 2, paras[4\], 1\]] - expected: FAIL - - [Resulting cursor position for range 22 [testDiv, 2, paras[4\], 1\]] - expected: FAIL - - [Resulting DOM for range 23 [document, 0, document, 1\]] - expected: FAIL - - [Resulting cursor position for range 23 [document, 0, document, 1\]] - expected: FAIL - [Resulting DOM for range 24 [document, 0, document, 2\]] expected: FAIL - [Resulting cursor position for range 24 [document, 0, document, 2\]] - expected: FAIL - - [Resulting DOM for range 25 [comment, 2, comment, 3\]] - expected: FAIL - [Resulting cursor position for range 25 [comment, 2, comment, 3\]] expected: FAIL - [Resulting DOM for range 26 [testDiv, 0, comment, 5\]] - expected: FAIL - - [Resulting cursor position for range 26 [testDiv, 0, comment, 5\]] - expected: FAIL - - [Resulting DOM for range 27 [foreignDoc, 1, foreignComment, 2\]] - expected: FAIL - - [Resulting cursor position for range 27 [foreignDoc, 1, foreignComment, 2\]] - expected: FAIL - - [Resulting DOM for range 28 [foreignDoc.body, 0, foreignTextNode, 36\]] - expected: FAIL - - [Resulting cursor position for range 28 [foreignDoc.body, 0, foreignTextNode, 36\]] - expected: FAIL - - [Resulting DOM for range 29 [xmlDoc, 1, xmlComment, 0\]] - expected: FAIL - - [Resulting cursor position for range 29 [xmlDoc, 1, xmlComment, 0\]] - expected: FAIL - - [Resulting DOM for range 30 [detachedTextNode, 0, detachedTextNode, 8\]] - expected: FAIL - [Resulting cursor position for range 30 [detachedTextNode, 0, detachedTextNode, 8\]] expected: FAIL - [Resulting DOM for range 31 [detachedForeignTextNode, 0, detachedForeignTextNode, 8\]] - expected: FAIL - [Resulting cursor position for range 31 [detachedForeignTextNode, 0, detachedForeignTextNode, 8\]] expected: FAIL - [Resulting DOM for range 32 [detachedXmlTextNode, 0, detachedXmlTextNode, 8\]] - expected: FAIL - [Resulting cursor position for range 32 [detachedXmlTextNode, 0, detachedXmlTextNode, 8\]] expected: FAIL - [Resulting DOM for range 33 [detachedComment, 3, detachedComment, 4\]] - expected: FAIL - [Resulting cursor position for range 33 [detachedComment, 3, detachedComment, 4\]] expected: FAIL - [Resulting DOM for range 34 [detachedForeignComment, 0, detachedForeignComment, 1\]] - expected: FAIL - [Resulting cursor position for range 34 [detachedForeignComment, 0, detachedForeignComment, 1\]] expected: FAIL - [Resulting DOM for range 35 [detachedXmlComment, 2, detachedXmlComment, 6\]] - expected: FAIL - [Resulting cursor position for range 35 [detachedXmlComment, 2, detachedXmlComment, 6\]] expected: FAIL - [Resulting DOM for range 36 [docfrag, 0, docfrag, 0\]] + [Resulting DOM for range 10 [document.documentElement, 0, document.documentElement, 1\]] expected: FAIL - [Resulting cursor position for range 36 [docfrag, 0, docfrag, 0\]] + [Resulting DOM for range 11 [document.documentElement, 0, document.documentElement, 2\]] expected: FAIL - [Resulting DOM for range 37 [processingInstruction, 0, processingInstruction, 4\]] + [Resulting DOM for range 12 [document.documentElement, 1, document.documentElement, 2\]] expected: FAIL - [Resulting cursor position for range 37 [processingInstruction, 0, processingInstruction, 4\]] + [Resulting DOM for range 15 [foreignDoc.documentElement, 0, foreignDoc.documentElement, 1\]] expected: FAIL - [Resulting DOM for range 38 [paras[1\].firstChild, 0, paras[1\].firstChild, 1\]] + [Resulting DOM for range 27 [foreignDoc, 1, foreignComment, 2\]] expected: FAIL - [Resulting cursor position for range 38 [paras[1\].firstChild, 0, paras[1\].firstChild, 1\]] + [Resulting cursor position for range 37 [processingInstruction, 0, processingInstruction, 4\]] expected: FAIL - [Resulting DOM for range 39 [paras[1\].firstChild, 2, paras[1\].firstChild, 8\]] + [Resulting cursor position for range 38 [paras[1\].firstChild, 0, paras[1\].firstChild, 1\]] expected: FAIL [Resulting cursor position for range 39 [paras[1\].firstChild, 2, paras[1\].firstChild, 8\]] expected: FAIL - [Resulting DOM for range 40 [detachedPara1.firstChild, 0, detachedPara1.firstChild, 1\]] - expected: FAIL - [Resulting cursor position for range 40 [detachedPara1.firstChild, 0, detachedPara1.firstChild, 1\]] expected: FAIL - [Resulting DOM for range 41 [foreignPara1.firstChild, 0, foreignPara1.firstChild, 1\]] - expected: FAIL - [Resulting cursor position for range 41 [foreignPara1.firstChild, 0, foreignPara1.firstChild, 1\]] expected: FAIL - [Resulting DOM for range 42 [foreignDoc.head, 1, foreignDoc.head, 1\]] - expected: FAIL - - [Resulting cursor position for range 42 [foreignDoc.head, 1, foreignDoc.head, 1\]] - expected: FAIL - - [Resulting DOM for range 43 [foreignDoc.body, 0, foreignDoc.body, 0\]] - expected: FAIL - - [Resulting cursor position for range 43 [foreignDoc.body, 0, foreignDoc.body, 0\]] - expected: FAIL - - [Resulting DOM for range 44 [paras[0\], 0, paras[0\], 0\]] - expected: FAIL - - [Resulting cursor position for range 44 [paras[0\], 0, paras[0\], 0\]] - expected: FAIL - - [Resulting DOM for range 45 [detachedPara1, 0, detachedPara1, 0\]] - expected: FAIL - - [Resulting cursor position for range 45 [detachedPara1, 0, detachedPara1, 0\]] - expected: FAIL - - [Resulting DOM for range 46 [testDiv, 1, paras[2\].firstChild, 5\]] - expected: FAIL - - [Resulting cursor position for range 46 [testDiv, 1, paras[2\].firstChild, 5\]] - expected: FAIL - - [Resulting DOM for range 47 [document.documentElement, 1, document.body, 0\]] - expected: FAIL - - [Resulting cursor position for range 47 [document.documentElement, 1, document.body, 0\]] - expected: FAIL - - [Resulting DOM for range 48 [foreignDoc.documentElement, 1, foreignDoc.body, 0\]] - expected: FAIL - - [Resulting cursor position for range 48 [foreignDoc.documentElement, 1, foreignDoc.body, 0\]] - expected: FAIL - [Resulting DOM for range 49 [document, 1, document, 2\]] expected: FAIL - [Resulting cursor position for range 49 [document, 1, document, 2\]] - expected: FAIL - - [Resulting DOM for range 50 [paras[2\].firstChild, 4, comment, 2\]] - expected: FAIL - [Resulting cursor position for range 50 [paras[2\].firstChild, 4, comment, 2\]] expected: FAIL - [Resulting DOM for range 51 [paras[3\], 1, comment, 8\]] - expected: FAIL - [Resulting cursor position for range 51 [paras[3\], 1, comment, 8\]] expected: FAIL - [Resulting DOM for range 52 [foreignDoc, 0, foreignDoc, 0\]] - expected: FAIL - - [Resulting cursor position for range 52 [foreignDoc, 0, foreignDoc, 0\]] - expected: FAIL - - [Resulting DOM for range 53 [xmlDoc, 0, xmlDoc, 0\]] - expected: FAIL - - [Resulting cursor position for range 53 [xmlDoc, 0, xmlDoc, 0\]] - expected: FAIL - - [Resulting DOM for range 54 [detachedForeignTextNode, 7, detachedForeignTextNode, 7\]] - expected: FAIL - - [Resulting cursor position for range 54 [detachedForeignTextNode, 7, detachedForeignTextNode, 7\]] - expected: FAIL - - [Resulting DOM for range 55 [detachedXmlTextNode, 7, detachedXmlTextNode, 7\]] - expected: FAIL - - [Resulting cursor position for range 55 [detachedXmlTextNode, 7, detachedXmlTextNode, 7\]] - expected: FAIL - - [Resulting DOM for range 56 [detachedComment, 5, detachedComment, 5\]] - expected: FAIL - - [Resulting cursor position for range 56 [detachedComment, 5, detachedComment, 5\]] - expected: FAIL - - [Resulting DOM for range 57 [detachedForeignComment, 4, detachedForeignComment, 4\]] - expected: FAIL - - [Resulting cursor position for range 57 [detachedForeignComment, 4, detachedForeignComment, 4\]] - expected: FAIL - - [Resulting DOM for range 58 [foreignDocfrag, 0, foreignDocfrag, 0\]] - expected: FAIL - - [Resulting cursor position for range 58 [foreignDocfrag, 0, foreignDocfrag, 0\]] - expected: FAIL - - [Resulting DOM for range 59 [xmlDocfrag, 0, xmlDocfrag, 0\]] - expected: FAIL - - [Resulting cursor position for range 59 [xmlDocfrag, 0, xmlDocfrag, 0\]] - expected: FAIL - diff --git a/tests/wpt/mozilla/meta/MANIFEST.json b/tests/wpt/mozilla/meta/MANIFEST.json index 5dadda08d55..8830b8af00c 100644 --- a/tests/wpt/mozilla/meta/MANIFEST.json +++ b/tests/wpt/mozilla/meta/MANIFEST.json @@ -5349,6 +5349,12 @@ "url": "/_mozilla/mozilla/proxy_setter.html" } ], + "mozilla/range_deleteContents.html": [ + { + "path": "mozilla/range_deleteContents.html", + "url": "/_mozilla/mozilla/range_deleteContents.html" + } + ], "mozilla/response-data-brotli.htm": [ { "path": "mozilla/response-data-brotli.htm", diff --git a/tests/wpt/mozilla/tests/mozilla/range_deleteContents.html b/tests/wpt/mozilla/tests/mozilla/range_deleteContents.html new file mode 100644 index 00000000000..8de03455bcb --- /dev/null +++ b/tests/wpt/mozilla/tests/mozilla/range_deleteContents.html @@ -0,0 +1,18 @@ +<!DOCTYPE html> +<html> + <head> + <script src="/resources/testharness.js"></script> + <script src="/resources/testharnessreport.js"></script> + </head> + <body> + <script> + test(function() { + var range = document.createRange(); + range.setStart(document, 0); + range.setEnd(document, 1); + range.deleteContents(); + assert_equals(document.childNodes.length, 1); + }, "Deleting range containing doctype"); + </script> + </body> +</html> |