author | Fernando Jiménez Moreno <ferjmoreno@gmail.com> |
Fri, 16 Feb 2018 05:38:38 -0500 | |
changeset 404209 | f084649dce30aba28687d8259905c684de66c685 |
parent 404208 | 799ef07581c3c78e140e96e1084a76094420c25b |
child 404210 | 841865bb1ee82a560dd4ca0163a37f87908d3df1 |
push id | 99968 |
push user | rgurzau@mozilla.com |
push date | Fri, 16 Feb 2018 22:14:56 +0000 |
treeherder | mozilla-inbound@2e16779c96cc [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | emilio |
milestone | 60.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/servo/components/script/dom/htmlelement.rs +++ b/servo/components/script/dom/htmlelement.rs @@ -12,27 +12,30 @@ use dom::bindings::codegen::Bindings::No use dom::bindings::codegen::Bindings::WindowBinding::WindowMethods; use dom::bindings::error::{Error, ErrorResult}; use dom::bindings::inheritance::{ElementTypeId, HTMLElementTypeId, NodeTypeId}; use dom::bindings::inheritance::Castable; use dom::bindings::root::{Dom, DomRoot, MutNullableDom, RootedReference}; use dom::bindings::str::DOMString; use dom::cssstyledeclaration::{CSSModificationAccess, CSSStyleDeclaration, CSSStyleOwner}; use dom::document::{Document, FocusType}; +use dom::documentfragment::DocumentFragment; use dom::domstringmap::DOMStringMap; use dom::element::{AttributeMutation, Element}; use dom::eventtarget::EventTarget; use dom::htmlbodyelement::HTMLBodyElement; +use dom::htmlbrelement::HTMLBRElement; use dom::htmlframesetelement::HTMLFrameSetElement; use dom::htmlhtmlelement::HTMLHtmlElement; use dom::htmlinputelement::{HTMLInputElement, InputType}; use dom::htmllabelelement::HTMLLabelElement; use dom::node::{Node, NodeFlags}; use dom::node::{document_from_node, window_from_node}; use dom::nodelist::NodeList; +use dom::text::Text; use dom::virtualmethods::VirtualMethods; use dom::window::ReflowReason; use dom_struct::dom_struct; use html5ever::{LocalName, Prefix}; use script_layout_interface::message::ReflowGoal; use std::collections::HashSet; use std::default::Default; use std::rc::Rc; @@ -416,21 +419,74 @@ impl HTMLElementMethods for HTMLElement return node.GetTextContent().unwrap(); } window.reflow(ReflowGoal::ElementInnerTextQuery(node.to_trusted_node_address()), ReflowReason::Query); DOMString::from(window.layout().element_inner_text()) } // https://html.spec.whatwg.org/multipage/#the-innertext-idl-attribute - fn SetInnerText(&self, _: DOMString) { - // XXX (ferjm) implement this. + fn SetInnerText(&self, input: DOMString) { + // Step 1. + let document = document_from_node(self); + + // Step 2. + let fragment = DocumentFragment::new(&document); + + // Step 3. The given value is already named 'input'. + + // Step 4. + let mut position = input.chars().peekable(); + + // Step 5. + let mut text = String::new(); + + // Step 6. + while let Some(ch) = position.next() { + match ch { + '\u{000A}' | '\u{000D}' => { + if ch == '\u{000D}' && position.peek() == Some(&'\u{000A}') { + // a \r\n pair should only generate one <br>, + // so just skip the \r. + position.next(); + } + + if !text.is_empty() { + append_text_node_to_fragment(&document, &fragment, text); + text = String::new(); + } + + let br = HTMLBRElement::new(local_name!("br"), None, &document); + fragment.upcast::<Node>().AppendChild(&br.upcast()).unwrap(); + }, + _ => { + text.push(ch); + } + } + } + + if !text.is_empty() { + append_text_node_to_fragment(&document, &fragment, text); + } + + // Step 7. + Node::replace_all(Some(fragment.upcast()), self.upcast::<Node>()); } } +fn append_text_node_to_fragment( + document: &Document, + fragment: &DocumentFragment, + text: String +) { + let text = Text::new(DOMString::from(text), document); + let node = DomRoot::upcast::<Node>(text); + fragment.upcast::<Node>().AppendChild(&node).unwrap(); +} + // https://html.spec.whatwg.org/multipage/#attr-data-* static DATA_PREFIX: &str = "data-"; static DATA_HYPHEN_SEPARATOR: char = '\x2d'; fn is_ascii_uppercase(c: char) -> bool { 'A' <= c && c <= 'Z' }