aboutsummaryrefslogtreecommitdiffstats
path: root/components/script/dom/htmltextareaelement.rs
diff options
context:
space:
mode:
authorMatthew Rasmus <mattr@zzntd.com>2014-11-29 13:48:55 -0800
committerMatthew Rasmus <mattr@zzntd.com>2014-12-05 12:21:31 -0800
commit29241699fdbdfe9308dde4f0586472919049f153 (patch)
treeb1eb7e834c86b659619e3b0158dbe5195162bd3e /components/script/dom/htmltextareaelement.rs
parentfd65b5f43826e526eb1dced4c93b0a63b8f49121 (diff)
downloadservo-29241699fdbdfe9308dde4f0586472919049f153.tar.gz
servo-29241699fdbdfe9308dde4f0586472919049f153.zip
Implements multi line text input for TextArea
Diffstat (limited to 'components/script/dom/htmltextareaelement.rs')
-rw-r--r--components/script/dom/htmltextareaelement.rs92
1 files changed, 87 insertions, 5 deletions
diff --git a/components/script/dom/htmltextareaelement.rs b/components/script/dom/htmltextareaelement.rs
index 8888178df5f..e34ec36aeca 100644
--- a/components/script/dom/htmltextareaelement.rs
+++ b/components/script/dom/htmltextareaelement.rs
@@ -4,18 +4,24 @@
use dom::attr::Attr;
use dom::attr::AttrHelpers;
+use dom::bindings::cell::DOMRefCell;
+use dom::bindings::codegen::Bindings::EventBinding::EventMethods;
use dom::bindings::codegen::Bindings::HTMLTextAreaElementBinding;
use dom::bindings::codegen::Bindings::HTMLTextAreaElementBinding::HTMLTextAreaElementMethods;
-use dom::bindings::codegen::InheritTypes::{HTMLElementCast, NodeCast};
use dom::bindings::codegen::Bindings::NodeBinding::NodeMethods;
+use dom::bindings::codegen::InheritTypes::{ElementCast, HTMLElementCast, NodeCast};
use dom::bindings::codegen::InheritTypes::{HTMLTextAreaElementDerived, HTMLFieldSetElementDerived};
-use dom::bindings::js::{JSRef, Temporary};
+use dom::bindings::codegen::InheritTypes::{KeyboardEventCast, TextDerived};
+use dom::bindings::js::{JS, JSRef, Temporary};
use dom::bindings::utils::{Reflectable, Reflector};
-use dom::document::Document;
+use dom::document::{Document, DocumentHelpers};
use dom::element::{AttributeHandlers, HTMLTextAreaElementTypeId};
+use dom::event::Event;
use dom::eventtarget::{EventTarget, NodeTargetTypeId};
use dom::htmlelement::HTMLElement;
-use dom::node::{DisabledStateHelpers, Node, NodeHelpers, ElementNodeTypeId};
+use dom::keyboardevent::KeyboardEvent;
+use dom::node::{DisabledStateHelpers, Node, NodeHelpers, ElementNodeTypeId, document_from_node};
+use textinput::{Multiple, TextInput, TriggerDefaultAction, DispatchInput, Nothing};
use dom::virtualmethods::VirtualMethods;
use servo_util::str::DOMString;
@@ -24,6 +30,7 @@ use string_cache::Atom;
#[dom_struct]
pub struct HTMLTextAreaElement {
htmlelement: HTMLElement,
+ textinput: DOMRefCell<TextInput>,
}
impl HTMLTextAreaElementDerived for EventTarget {
@@ -32,10 +39,22 @@ impl HTMLTextAreaElementDerived for EventTarget {
}
}
+pub trait LayoutHTMLTextAreaElementHelpers {
+ unsafe fn get_value_for_layout(self) -> String;
+}
+
+impl LayoutHTMLTextAreaElementHelpers for JS<HTMLTextAreaElement> {
+ #[allow(unrooted_must_root)]
+ unsafe fn get_value_for_layout(self) -> String {
+ (*self.unsafe_get()).textinput.borrow_for_layout().get_content()
+ }
+}
+
impl HTMLTextAreaElement {
fn new_inherited(localName: DOMString, prefix: Option<DOMString>, document: JSRef<Document>) -> HTMLTextAreaElement {
HTMLTextAreaElement {
- htmlelement: HTMLElement::new_inherited(HTMLTextAreaElementTypeId, localName, prefix, document)
+ htmlelement: HTMLElement::new_inherited(HTMLTextAreaElementTypeId, localName, prefix, document),
+ textinput: DOMRefCell::new(TextInput::new(Multiple, "".to_string())),
}
}
@@ -108,6 +127,28 @@ impl<'a> HTMLTextAreaElementMethods for JSRef<'a, HTMLTextAreaElement> {
let node: JSRef<Node> = NodeCast::from_ref(self);
node.SetTextContent(Some(value))
}
+
+ // https://html.spec.whatwg.org/multipage/forms.html#dom-textarea-value
+ fn Value(self) -> DOMString {
+ self.textinput.borrow().get_content()
+ }
+
+ // https://html.spec.whatwg.org/multipage/forms.html#dom-textarea-value
+ fn SetValue(self, value: DOMString) {
+ self.textinput.borrow_mut().set_content(value);
+ }
+}
+
+pub trait HTMLTextAreaElementHelpers {
+ fn force_relayout(self);
+}
+
+impl<'a> HTMLTextAreaElementHelpers for JSRef<'a, HTMLTextAreaElement> {
+ fn force_relayout(self) {
+ let doc = document_from_node(self).root();
+ let node: JSRef<Node> = NodeCast::from_ref(self);
+ doc.content_changed(node)
+ }
}
impl<'a> VirtualMethods for JSRef<'a, HTMLTextAreaElement> {
@@ -172,6 +213,47 @@ impl<'a> VirtualMethods for JSRef<'a, HTMLTextAreaElement> {
node.check_disabled_attribute();
}
}
+
+ fn child_inserted(&self, child: JSRef<Node>) {
+ match self.super_type() {
+ Some(s) => {
+ s.child_inserted(child);
+ }
+ _ => (),
+ }
+
+ if child.is_text() {
+ self.SetValue(child.GetTextContent().unwrap());
+ }
+ }
+
+ // copied and modified from htmlinputelement.rs
+ fn handle_event(&self, event: JSRef<Event>) {
+ match self.super_type() {
+ Some(s) => {
+ s.handle_event(event);
+ }
+ _ => (),
+ }
+
+ if "click" == event.Type().as_slice() && !event.DefaultPrevented() {
+ //TODO: set the editing position for text inputs
+
+ let doc = document_from_node(*self).root();
+ doc.request_focus(ElementCast::from_ref(*self));
+ } else if "keydown" == event.Type().as_slice() && !event.DefaultPrevented() {
+ let keyevent: Option<JSRef<KeyboardEvent>> = KeyboardEventCast::to_ref(event);
+ keyevent.map(|event| {
+ match self.textinput.borrow_mut().handle_keydown(event) {
+ TriggerDefaultAction => (),
+ DispatchInput => {
+ self.force_relayout();
+ }
+ Nothing => (),
+ }
+ });
+ }
+ }
}
impl Reflectable for HTMLTextAreaElement {