forked from mirrors/gecko-dev
		
	 689e86231d
			
		
	
	
		689e86231d
		
	
	
	
	
		
			
			NodeTypeId is supposed to reflect the WebIDL inheritance hierarchy. All of Text/ProcessingInstruction/Comment inherit from CharacterData, which inherits from Node. There should be a CharacterDataTypeId value that differentiates between those, instead. r? @jdm cc @yichoi Source-Repo: https://github.com/servo/servo Source-Revision: 5b0c6c9d31973aabdb820f16237e1a7c2a6524ad
		
			
				
	
	
		
			105 lines
		
	
	
	
		
			4 KiB
		
	
	
	
		
			Rust
		
	
	
	
	
	
			
		
		
	
	
			105 lines
		
	
	
	
		
			4 KiB
		
	
	
	
		
			Rust
		
	
	
	
	
	
| /* This Source Code Form is subject to the terms of the Mozilla Public
 | |
|  * License, v. 2.0. If a copy of the MPL was not distributed with this
 | |
|  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 | |
| 
 | |
| use dom::bindings::codegen::Bindings::TextBinding::{self, TextMethods};
 | |
| use dom::bindings::codegen::Bindings::CharacterDataBinding::CharacterDataMethods;
 | |
| use dom::bindings::codegen::Bindings::DocumentBinding::DocumentMethods;
 | |
| use dom::bindings::codegen::Bindings::NodeBinding::NodeMethods;
 | |
| use dom::bindings::codegen::Bindings::WindowBinding::WindowMethods;
 | |
| use dom::bindings::codegen::InheritTypes::{CharacterDataCast, TextDerived};
 | |
| use dom::bindings::codegen::InheritTypes::NodeCast;
 | |
| use dom::bindings::error::{Error, Fallible};
 | |
| use dom::bindings::global::GlobalRef;
 | |
| use dom::bindings::js::{JSRef, OptionalRootable, Rootable, RootedReference};
 | |
| use dom::bindings::js::Temporary;
 | |
| use dom::characterdata::{CharacterData, CharacterDataHelpers, CharacterDataTypeId};
 | |
| use dom::document::Document;
 | |
| use dom::eventtarget::{EventTarget, EventTargetTypeId};
 | |
| use dom::node::{Node, NodeHelpers, NodeTypeId};
 | |
| use util::str::DOMString;
 | |
| 
 | |
| /// An HTML text node.
 | |
| #[dom_struct]
 | |
| pub struct Text {
 | |
|     characterdata: CharacterData,
 | |
| }
 | |
| 
 | |
| impl TextDerived for EventTarget {
 | |
|     fn is_text(&self) -> bool {
 | |
|         *self.type_id() == EventTargetTypeId::Node(NodeTypeId::CharacterData(CharacterDataTypeId::Text))
 | |
|     }
 | |
| }
 | |
| 
 | |
| impl Text {
 | |
|     fn new_inherited(text: DOMString, document: JSRef<Document>) -> Text {
 | |
|         Text {
 | |
|             characterdata: CharacterData::new_inherited(CharacterDataTypeId::Text, text, document)
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     pub fn new(text: DOMString, document: JSRef<Document>) -> Temporary<Text> {
 | |
|         Node::reflect_node(box Text::new_inherited(text, document),
 | |
|                            document, TextBinding::Wrap)
 | |
|     }
 | |
| 
 | |
|     pub fn Constructor(global: GlobalRef, text: DOMString) -> Fallible<Temporary<Text>> {
 | |
|         let document = global.as_window().Document().root();
 | |
|         Ok(Text::new(text, document.r()))
 | |
|     }
 | |
| }
 | |
| 
 | |
| impl<'a> TextMethods for JSRef<'a, Text> {
 | |
|     // https://dom.spec.whatwg.org/#dom-text-splittextoffset
 | |
|     fn SplitText(self, offset: u32) -> Fallible<Temporary<Text>> {
 | |
|         let cdata = CharacterDataCast::from_ref(self);
 | |
|         // Step 1.
 | |
|         let length = cdata.Length();
 | |
|         if offset > length {
 | |
|             // Step 2.
 | |
|             return Err(Error::IndexSize);
 | |
|         }
 | |
|         // Step 3.
 | |
|         let count = length - offset;
 | |
|         // Step 4.
 | |
|         let new_data = cdata.SubstringData(offset, count).unwrap();
 | |
|         // Step 5.
 | |
|         let node = NodeCast::from_ref(self);
 | |
|         let owner_doc = node.owner_doc().root();
 | |
|         let new_node = owner_doc.r().CreateTextNode(new_data).root();
 | |
|         // Step 6.
 | |
|         let parent = node.parent_node().root();
 | |
|         if let Some(ref parent) = parent {
 | |
|             // Step 7.
 | |
|             parent.r().InsertBefore(NodeCast::from_ref(new_node.r()),
 | |
|                                     node.next_sibling().root().r())
 | |
|                   .unwrap();
 | |
|             // TODO: Ranges.
 | |
|         }
 | |
|         // Step 8.
 | |
|         cdata.DeleteData(offset, count).unwrap();
 | |
|         if parent.is_none() {
 | |
|             // Step 9.
 | |
|             // TODO: Ranges
 | |
|         }
 | |
|         // Step 10.
 | |
|         Ok(Temporary::from_rooted(new_node.r()))
 | |
|     }
 | |
| 
 | |
|     // https://dom.spec.whatwg.org/#dom-text-wholetext
 | |
|     fn WholeText(self) -> DOMString {
 | |
|         let first = NodeCast::from_ref(self).inclusively_preceding_siblings()
 | |
|                                             .map(|node| node.root())
 | |
|                                             .take_while(|node| node.r().is_text())
 | |
|                                             .last().unwrap();
 | |
|         let nodes = first.r().inclusively_following_siblings().map(|node| node.root())
 | |
|                              .take_while(|node| node.r().is_text());
 | |
|         let mut text = DOMString::new();
 | |
|         for ref node in nodes {
 | |
|             let cdata = CharacterDataCast::to_ref(node.r()).unwrap();
 | |
|             text.push_str(&cdata.data());
 | |
|         }
 | |
|         text
 | |
|     }
 | |
| }
 | |
| 
 |