diff options
Diffstat (limited to 'components/script/dom/range.rs')
-rw-r--r-- | components/script/dom/range.rs | 386 |
1 files changed, 214 insertions, 172 deletions
diff --git a/components/script/dom/range.rs b/components/script/dom/range.rs index f43c9e1922c..9123a2c67e3 100644 --- a/components/script/dom/range.rs +++ b/components/script/dom/range.rs @@ -40,8 +40,12 @@ pub struct Range { } impl Range { - fn new_inherited(start_container: &Node, start_offset: u32, - end_container: &Node, end_offset: u32) -> Range { + fn new_inherited( + start_container: &Node, + start_offset: u32, + end_container: &Node, + end_offset: u32, + ) -> Range { Range { reflector_: Reflector::new(), start: BoundaryPoint::new(start_container, start_offset), @@ -54,16 +58,22 @@ impl Range { Range::new(document, root, 0, root, 0) } - pub fn new(document: &Document, - start_container: &Node, start_offset: u32, - end_container: &Node, end_offset: u32) - -> DomRoot<Range> { + pub fn new( + document: &Document, + start_container: &Node, + start_offset: u32, + end_container: &Node, + end_offset: u32, + ) -> DomRoot<Range> { let range = reflect_dom_object( Box::new(Range::new_inherited( - start_container, start_offset, end_container, end_offset + start_container, + start_offset, + end_container, + end_offset, )), document.window(), - RangeBinding::Wrap + RangeBinding::Wrap, ); start_container.ranges().push(WeakRef::new(&range)); if start_container != end_container { @@ -80,58 +90,74 @@ impl Range { // https://dom.spec.whatwg.org/#contained fn contains(&self, node: &Node) -> bool { - match (bp_position(node, 0, &self.StartContainer(), self.StartOffset()), - bp_position(node, node.len(), &self.EndContainer(), self.EndOffset())) { + match ( + bp_position(node, 0, &self.StartContainer(), self.StartOffset()), + bp_position(node, node.len(), &self.EndContainer(), self.EndOffset()), + ) { (Some(Ordering::Greater), Some(Ordering::Less)) => true, - _ => false + _ => false, } } // https://dom.spec.whatwg.org/#partially-contained fn partially_contains(&self, node: &Node) -> bool { - self.StartContainer().inclusive_ancestors().any(|n| &*n == node) != - self.EndContainer().inclusive_ancestors().any(|n| &*n == node) + self.StartContainer() + .inclusive_ancestors() + .any(|n| &*n == node) != + self.EndContainer() + .inclusive_ancestors() + .any(|n| &*n == node) } // https://dom.spec.whatwg.org/#concept-range-clone - fn contained_children(&self) -> Fallible<(Option<DomRoot<Node>>, - Option<DomRoot<Node>>, - Vec<DomRoot<Node>>)> { + fn contained_children( + &self, + ) -> Fallible<( + Option<DomRoot<Node>>, + Option<DomRoot<Node>>, + Vec<DomRoot<Node>>, + )> { let start_node = self.StartContainer(); let end_node = self.EndContainer(); // Steps 5-6. let common_ancestor = self.CommonAncestorContainer(); - let first_contained_child = - if start_node.is_inclusive_ancestor_of(&end_node) { - // Step 7. - None - } else { - // Step 8. - common_ancestor.children() - .find(|node| Range::partially_contains(self, node)) - }; + let first_contained_child = if start_node.is_inclusive_ancestor_of(&end_node) { + // Step 7. + None + } else { + // Step 8. + common_ancestor + .children() + .find(|node| Range::partially_contains(self, node)) + }; - let last_contained_child = - if end_node.is_inclusive_ancestor_of(&start_node) { - // Step 9. - None - } else { - // Step 10. - common_ancestor.rev_children() - .find(|node| Range::partially_contains(self, node)) - }; + let last_contained_child = if end_node.is_inclusive_ancestor_of(&start_node) { + // Step 9. + None + } else { + // Step 10. + common_ancestor + .rev_children() + .find(|node| Range::partially_contains(self, node)) + }; // Step 11. - let contained_children: Vec<DomRoot<Node>> = - common_ancestor.children().filter(|n| self.contains(n)).collect(); + let contained_children: Vec<DomRoot<Node>> = common_ancestor + .children() + .filter(|n| self.contains(n)) + .collect(); // Step 12. if contained_children.iter().any(|n| n.is_doctype()) { return Err(Error::HierarchyRequest); } - Ok((first_contained_child, last_contained_child, contained_children)) + Ok(( + first_contained_child, + last_contained_child, + contained_children, + )) } // https://dom.spec.whatwg.org/#concept-range-bp-set @@ -142,7 +168,8 @@ impl Range { } else if &self.end.node == node { self.StartContainer().ranges().remove(self); } else { - node.ranges().push(self.StartContainer().ranges().remove(self)); + node.ranges() + .push(self.StartContainer().ranges().remove(self)); } } self.start.set(node, offset); @@ -156,7 +183,8 @@ impl Range { } else if &self.start.node == node { self.EndContainer().ranges().remove(self); } else { - node.ranges().push(self.EndContainer().ranges().remove(self)); + node.ranges() + .push(self.EndContainer().ranges().remove(self)); } } self.end.set(node, offset); @@ -179,11 +207,14 @@ impl Range { // Step 3. return Err(Error::IndexSize); } - if let Ordering::Less = bp_position(node, offset, &start_node, self.StartOffset()).unwrap() { + if let Ordering::Less = bp_position(node, offset, &start_node, self.StartOffset()).unwrap() + { // Step 4. return Ok(Ordering::Less); } - if let Ordering::Greater = bp_position(node, offset, &self.EndContainer(), self.EndOffset()).unwrap() { + if let Ordering::Greater = + bp_position(node, offset, &self.EndContainer(), self.EndOffset()).unwrap() + { // Step 5. return Ok(Ordering::Greater); } @@ -332,8 +363,7 @@ impl RangeMethods for Range { } // https://dom.spec.whatwg.org/#dom-range-compareboundarypoints - fn CompareBoundaryPoints(&self, how: u16, other: &Range) - -> Fallible<i16> { + fn CompareBoundaryPoints(&self, how: u16, other: &Range) -> Fallible<i16> { if how > RangeConstants::END_TO_START { // Step 1. return Err(Error::NotSupported); @@ -346,18 +376,10 @@ impl RangeMethods for Range { } // Step 3. let (this_point, other_point) = match how { - RangeConstants::START_TO_START => { - (&self.start, &other.start) - }, - RangeConstants::START_TO_END => { - (&self.end, &other.start) - }, - RangeConstants::END_TO_END => { - (&self.end, &other.end) - }, - RangeConstants::END_TO_START => { - (&self.start, &other.end) - }, + RangeConstants::START_TO_START => (&self.start, &other.start), + RangeConstants::START_TO_END => (&self.end, &other.start), + RangeConstants::END_TO_END => (&self.end, &other.end), + RangeConstants::END_TO_START => (&self.start, &other.end), _ => unreachable!(), }; // step 4. @@ -372,8 +394,13 @@ impl RangeMethods for Range { fn CloneRange(&self) -> DomRoot<Range> { let start_node = self.StartContainer(); let owner_doc = start_node.owner_doc(); - Range::new(&owner_doc, &start_node, self.StartOffset(), - &self.EndContainer(), self.EndOffset()) + Range::new( + &owner_doc, + &start_node, + self.StartOffset(), + &self.EndContainer(), + self.EndOffset(), + ) } // https://dom.spec.whatwg.org/#dom-range-ispointinrange @@ -385,19 +412,17 @@ impl RangeMethods for Range { Err(Error::WrongDocument) => { // Step 2. Ok(false) - } + }, Err(error) => Err(error), } } // https://dom.spec.whatwg.org/#dom-range-comparepoint fn ComparePoint(&self, node: &Node, offset: u32) -> Fallible<i16> { - self.compare_point(node, offset).map(|order| { - match order { - Ordering::Less => -1, - Ordering::Equal => 0, - Ordering::Greater => 1, - } + self.compare_point(node, offset).map(|order| match order { + Ordering::Less => -1, + Ordering::Equal => 0, + Ordering::Greater => 1, }) } @@ -420,10 +445,10 @@ impl RangeMethods for Range { // Step 4. let offset = node.index(); // Step 5. - Ordering::Greater == bp_position(&parent, offset + 1, - &start_node, self.StartOffset()).unwrap() && - Ordering::Less == bp_position(&parent, offset, - &self.EndContainer(), self.EndOffset()).unwrap() + Ordering::Greater == + bp_position(&parent, offset + 1, &start_node, self.StartOffset()).unwrap() && + Ordering::Less == + bp_position(&parent, offset, &self.EndContainer(), self.EndOffset()).unwrap() } // https://dom.spec.whatwg.org/#dom-range-clonecontents @@ -446,7 +471,9 @@ impl RangeMethods for Range { if end_node == start_node { if let Some(cdata) = start_node.downcast::<CharacterData>() { // Steps 4.1-2. - let data = cdata.SubstringData(start_offset, end_offset - start_offset).unwrap(); + let data = cdata + .SubstringData(start_offset, end_offset - start_offset) + .unwrap(); let clone = cdata.clone_with_data(data, &start_node.owner_doc()); // Step 4.3. fragment.upcast::<Node>().AppendChild(&clone)?; @@ -464,7 +491,9 @@ impl RangeMethods for Range { if let Some(cdata) = child.downcast::<CharacterData>() { assert!(child == start_node); // Steps 13.1-2. - let data = cdata.SubstringData(start_offset, start_node.len() - start_offset).unwrap(); + let data = cdata + .SubstringData(start_offset, start_node.len() - start_offset) + .unwrap(); let clone = cdata.clone_with_data(data, &start_node.owner_doc()); // Step 13.3. fragment.upcast::<Node>().AppendChild(&clone)?; @@ -474,11 +503,13 @@ impl RangeMethods for Range { // Step 14.2. fragment.upcast::<Node>().AppendChild(&clone)?; // Step 14.3. - let subrange = Range::new(&clone.owner_doc(), - &start_node, - start_offset, - &child, - child.len()); + let subrange = Range::new( + &clone.owner_doc(), + &start_node, + start_offset, + &child, + child.len(), + ); // Step 14.4. let subfragment = subrange.CloneContents()?; // Step 14.5. @@ -509,11 +540,7 @@ impl RangeMethods for Range { // Step 17.2. fragment.upcast::<Node>().AppendChild(&clone)?; // Step 17.3. - let subrange = Range::new(&clone.owner_doc(), - &child, - 0, - &end_node, - end_offset); + let subrange = Range::new(&clone.owner_doc(), &child, 0, &end_node, end_offset); // Step 17.4. let subfragment = subrange.CloneContents()?; // Step 17.5. @@ -548,13 +575,14 @@ impl RangeMethods for Range { let clone = end_node.CloneNode(true); // Step 4.2. let text = end_data.SubstringData(start_offset, end_offset - start_offset); - clone.downcast::<CharacterData>().unwrap().SetData(text.unwrap()); + clone + .downcast::<CharacterData>() + .unwrap() + .SetData(text.unwrap()); // Step 4.3. fragment.upcast::<Node>().AppendChild(&clone)?; // Step 4.4. - end_data.ReplaceData(start_offset, - end_offset - start_offset, - DOMString::new())?; + end_data.ReplaceData(start_offset, end_offset - start_offset, DOMString::new())?; // Step 4.5. return Ok(fragment); } @@ -569,12 +597,16 @@ impl RangeMethods for Range { (DomRoot::from_ref(&*start_node), start_offset) } else { // Step 14.1-2. - let reference_node = start_node.ancestors() - .take_while(|n| !n.is_inclusive_ancestor_of(&end_node)) - .last() - .unwrap_or(DomRoot::from_ref(&start_node)); + let reference_node = start_node + .ancestors() + .take_while(|n| !n.is_inclusive_ancestor_of(&end_node)) + .last() + .unwrap_or(DomRoot::from_ref(&start_node)); // Step 14.3. - (reference_node.GetParentNode().unwrap(), reference_node.index() + 1) + ( + reference_node.GetParentNode().unwrap(), + reference_node.index() + 1, + ) }; if let Some(child) = first_contained_child { @@ -583,26 +615,32 @@ impl RangeMethods for Range { // Step 15.1. let clone = start_node.CloneNode(true); // Step 15.2. - let text = start_data.SubstringData(start_offset, - start_node.len() - start_offset); - clone.downcast::<CharacterData>().unwrap().SetData(text.unwrap()); + let text = start_data.SubstringData(start_offset, start_node.len() - start_offset); + clone + .downcast::<CharacterData>() + .unwrap() + .SetData(text.unwrap()); // Step 15.3. fragment.upcast::<Node>().AppendChild(&clone)?; // Step 15.4. - start_data.ReplaceData(start_offset, - start_node.len() - start_offset, - DOMString::new())?; + start_data.ReplaceData( + start_offset, + start_node.len() - start_offset, + DOMString::new(), + )?; } else { // Step 16.1. let clone = child.CloneNode(false); // Step 16.2. fragment.upcast::<Node>().AppendChild(&clone)?; // Step 16.3. - let subrange = Range::new(&clone.owner_doc(), - &start_node, - start_offset, - &child, - child.len()); + let subrange = Range::new( + &clone.owner_doc(), + &start_node, + start_offset, + &child, + child.len(), + ); // Step 16.4. let subfragment = subrange.ExtractContents()?; // Step 16.5. @@ -622,7 +660,10 @@ impl RangeMethods for Range { let clone = end_node.CloneNode(true); // Step 18.2. let text = end_data.SubstringData(0, end_offset); - clone.downcast::<CharacterData>().unwrap().SetData(text.unwrap()); + clone + .downcast::<CharacterData>() + .unwrap() + .SetData(text.unwrap()); // Step 18.3. fragment.upcast::<Node>().AppendChild(&clone)?; // Step 18.4. @@ -633,11 +674,7 @@ impl RangeMethods for Range { // Step 19.2. fragment.upcast::<Node>().AppendChild(&clone)?; // Step 19.3. - let subrange = Range::new(&clone.owner_doc(), - &child, - 0, - &end_node, - end_offset); + let subrange = Range::new(&clone.owner_doc(), &child, 0, &end_node, end_offset); // Step 19.4. let subfragment = subrange.ExtractContents()?; // Step 19.5. @@ -672,7 +709,7 @@ impl RangeMethods for Range { // Handled under step 2. NodeTypeId::CharacterData(CharacterDataTypeId::Text) => (), NodeTypeId::CharacterData(_) => return Err(Error::HierarchyRequest), - _ => () + _ => (), } // Step 2. @@ -682,7 +719,7 @@ impl RangeMethods for Range { let parent = match start_node.GetParentNode() { Some(parent) => parent, // Step 1. - None => return Err(Error::HierarchyRequest) + None => return Err(Error::HierarchyRequest), }; // Step 5. (Some(DomRoot::from_ref(&*start_node)), parent) @@ -693,22 +730,19 @@ impl RangeMethods for Range { }; // Step 6. - Node::ensure_pre_insertion_validity(node, - &parent, - reference_node.r())?; + Node::ensure_pre_insertion_validity(node, &parent, reference_node.r())?; // Step 7. let split_text; - let reference_node = - match start_node.downcast::<Text>() { - Some(text) => { - split_text = text.SplitText(start_offset)?; - let new_reference = DomRoot::upcast::<Node>(split_text); - assert!(new_reference.GetParentNode().r() == Some(&parent)); - Some(new_reference) - }, - _ => reference_node - }; + let reference_node = match start_node.downcast::<Text>() { + Some(text) => { + split_text = text.SplitText(start_offset)?; + let new_reference = DomRoot::upcast::<Node>(split_text); + assert!(new_reference.GetParentNode().r() == Some(&parent)); + Some(new_reference) + }, + _ => reference_node, + }; // Step 8. let reference_node = if Some(node) == reference_node.r() { @@ -721,8 +755,7 @@ impl RangeMethods for Range { node.remove_self(); // Step 10. - let new_offset = - reference_node.r().map_or(parent.len(), |node| node.index()); + let new_offset = reference_node.r().map_or(parent.len(), |node| node.index()); // Step 11 let new_offset = new_offset + if node.type_id() == NodeTypeId::DocumentFragment { @@ -758,9 +791,7 @@ impl RangeMethods for Range { // 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::new()); + return text.ReplaceData(start_offset, end_offset - start_offset, DOMString::new()); } } @@ -789,7 +820,7 @@ impl RangeMethods for Range { let mut reference_node = DomRoot::from_ref(start_node); while let Some(parent) = reference_node.GetParentNode() { if parent.is_inclusive_ancestor_of(end_node) { - return (parent, reference_node.index() + 1) + return (parent, reference_node.index() + 1); } reference_node = parent; } @@ -801,9 +832,11 @@ impl RangeMethods for Range { // Step 7. if let Some(text) = start_node.downcast::<CharacterData>() { - text.ReplaceData(start_offset, - start_node.len() - start_offset, - DOMString::new()).unwrap(); + text.ReplaceData( + start_offset, + start_node.len() - start_offset, + DOMString::new(), + ).unwrap(); } // Step 8. @@ -828,17 +861,21 @@ impl RangeMethods for Range { let start = self.StartContainer(); let end = self.EndContainer(); - if start.inclusive_ancestors().any(|n| !n.is_inclusive_ancestor_of(&end) && !n.is::<Text>()) || - end.inclusive_ancestors().any(|n| !n.is_inclusive_ancestor_of(&start) && !n.is::<Text>()) { - return Err(Error::InvalidState); + if start + .inclusive_ancestors() + .any(|n| !n.is_inclusive_ancestor_of(&end) && !n.is::<Text>()) || + end.inclusive_ancestors() + .any(|n| !n.is_inclusive_ancestor_of(&start) && !n.is::<Text>()) + { + return Err(Error::InvalidState); } // Step 2. match new_parent.type_id() { - NodeTypeId::Document(_) | - NodeTypeId::DocumentType | - NodeTypeId::DocumentFragment => return Err(Error::InvalidNodeType), - _ => () + NodeTypeId::Document(_) | NodeTypeId::DocumentType | NodeTypeId::DocumentFragment => { + return Err(Error::InvalidNodeType) + }, + _ => (), } // Step 3. @@ -870,19 +907,24 @@ impl RangeMethods for Range { // Step 2. if start_node == end_node { - return char_data.SubstringData(self.StartOffset(), - self.EndOffset() - self.StartOffset()).unwrap(); + return char_data + .SubstringData(self.StartOffset(), self.EndOffset() - self.StartOffset()) + .unwrap(); } // Step 3. - s.push_str(&*char_data.SubstringData(self.StartOffset(), - char_data.Length() - self.StartOffset()).unwrap()); + s.push_str( + &*char_data + .SubstringData(self.StartOffset(), char_data.Length() - self.StartOffset()) + .unwrap(), + ); } // Step 4. let ancestor = self.CommonAncestorContainer(); - let mut iter = start_node.following_nodes(&ancestor) - .filter_map(DomRoot::downcast::<Text>); + let mut iter = start_node + .following_nodes(&ancestor) + .filter_map(DomRoot::downcast::<Text>); while let Some(child) = iter.next() { if self.contains(child.upcast()) { @@ -963,23 +1005,24 @@ impl BoundaryPoint { #[allow(unrooted_must_root)] impl PartialOrd for BoundaryPoint { fn partial_cmp(&self, other: &Self) -> Option<Ordering> { - bp_position(&self.node.get(), self.offset.get(), - &other.node.get(), other.offset.get()) + bp_position( + &self.node.get(), + self.offset.get(), + &other.node.get(), + other.offset.get(), + ) } } #[allow(unrooted_must_root)] impl PartialEq for BoundaryPoint { fn eq(&self, other: &Self) -> bool { - self.node.get() == other.node.get() && - self.offset.get() == other.offset.get() + self.node.get() == other.node.get() && self.offset.get() == other.offset.get() } } // https://dom.spec.whatwg.org/#concept-range-bp-position -fn bp_position(a_node: &Node, a_offset: u32, - b_node: &Node, b_offset: u32) - -> Option<Ordering> { +fn bp_position(a_node: &Node, a_offset: u32, b_node: &Node, b_offset: u32) -> Option<Ordering> { if a_node as *const Node == b_node as *const Node { // Step 1. return Some(a_offset.cmp(&b_offset)); @@ -998,9 +1041,9 @@ fn bp_position(a_node: &Node, a_offset: u32, } else if position & NodeConstants::DOCUMENT_POSITION_CONTAINS != 0 { // Step 3-1, 3-2. let mut b_ancestors = b_node.inclusive_ancestors(); - let child = b_ancestors.find(|child| { - &*child.GetParentNode().unwrap() == a_node - }).unwrap(); + let child = b_ancestors + .find(|child| &*child.GetParentNode().unwrap() == a_node) + .unwrap(); // Step 3-3. if child.index() < a_offset { Some(Ordering::Greater) @@ -1022,7 +1065,9 @@ pub struct WeakRangeVec { impl WeakRangeVec { /// Create a new vector of weak references. pub fn new() -> Self { - WeakRangeVec { cell: UnsafeCell::new(WeakRefVec::new()) } + WeakRangeVec { + cell: UnsafeCell::new(WeakRefVec::new()), + } } /// Whether that vector of ranges is empty. @@ -1100,9 +1145,7 @@ impl WeakRangeVec { /// Used for steps 7.3-4. when normalizing a node. /// <https://dom.spec.whatwg.org/#dom-node-normalize> - pub fn move_to_text_child_at(&self, - node: &Node, offset: u32, - child: &Node, new_offset: u32) { + pub fn move_to_text_child_at(&self, node: &Node, offset: u32, child: &Node, new_offset: u32) { unsafe { let child_ranges = &mut *child.ranges().cell.get(); @@ -1116,8 +1159,8 @@ impl WeakRangeVec { let move_end = node_is_end && range.EndOffset() == offset; let remove_from_node = move_start && move_end || - move_start && !node_is_end || - move_end && !node_is_start; + move_start && !node_is_end || + move_end && !node_is_start; let already_in_child = &range.start.node == child || &range.end.node == child; let push_to_child = !already_in_child && (move_start || move_end); @@ -1143,9 +1186,13 @@ impl WeakRangeVec { /// Used for steps 8-11. when replacing character data. /// <https://dom.spec.whatwg.org/#concept-cd-replace> - pub fn replace_code_units(&self, - node: &Node, offset: u32, - removed_code_units: u32, added_code_units: u32) { + pub fn replace_code_units( + &self, + node: &Node, + offset: u32, + removed_code_units: u32, + added_code_units: u32, + ) { self.map_offset_above(node, offset, |range_offset| { if range_offset <= offset + removed_code_units { offset @@ -1157,9 +1204,7 @@ impl WeakRangeVec { /// Used for steps 7.2-3. when splitting a text node. /// <https://dom.spec.whatwg.org/#concept-text-split> - pub fn move_to_following_text_sibling_above(&self, - node: &Node, offset: u32, - sibling: &Node) { + pub fn move_to_following_text_sibling_above(&self, node: &Node, offset: u32, sibling: &Node) { unsafe { let sibling_ranges = &mut *sibling.ranges().cell.get(); @@ -1175,11 +1220,10 @@ impl WeakRangeVec { let move_end = node_is_end && end_offset > offset; let remove_from_node = move_start && move_end || - move_start && !node_is_end || - move_end && !node_is_start; + move_start && !node_is_end || + move_end && !node_is_start; - let already_in_sibling = - &range.start.node == sibling || &range.end.node == sibling; + let already_in_sibling = &range.start.node == sibling || &range.end.node == sibling; let push_to_sibling = !already_in_sibling && (move_start || move_end); if remove_from_node { @@ -1242,9 +1286,7 @@ impl WeakRangeVec { fn remove(&self, range: &Range) -> WeakRef<Range> { unsafe { let ranges = &mut *self.cell.get(); - let position = ranges.iter().position(|ref_| { - ref_ == range - }).unwrap(); + let position = ranges.iter().position(|ref_| ref_ == range).unwrap(); ranges.swap_remove(position) } } |