aboutsummaryrefslogtreecommitdiffstats
path: root/components/script/dom/htmlinputelement.rs
diff options
context:
space:
mode:
Diffstat (limited to 'components/script/dom/htmlinputelement.rs')
-rw-r--r--components/script/dom/htmlinputelement.rs77
1 files changed, 53 insertions, 24 deletions
diff --git a/components/script/dom/htmlinputelement.rs b/components/script/dom/htmlinputelement.rs
index 44e8b21ab18..547c0f57aa2 100644
--- a/components/script/dom/htmlinputelement.rs
+++ b/components/script/dom/htmlinputelement.rs
@@ -13,16 +13,20 @@ use dom::bindings::codegen::Bindings::HTMLInputElementBinding::HTMLInputElementM
use dom::bindings::codegen::Bindings::NodeListBinding::NodeListMethods;
use dom::bindings::codegen::InheritTypes::{ElementCast, HTMLElementCast, HTMLFormElementCast, HTMLInputElementCast, NodeCast};
use dom::bindings::codegen::InheritTypes::{HTMLInputElementDerived, HTMLFieldSetElementDerived};
+use dom::bindings::codegen::InheritTypes::KeyboardEventCast;
use dom::bindings::js::{JS, JSRef, Temporary, OptionalRootable, ResultRootable};
use dom::bindings::utils::{Reflectable, Reflector};
use dom::document::{Document, DocumentHelpers};
-use dom::element::{AttributeHandlers, Element, HTMLInputElementTypeId};
+use dom::element::{AttributeHandlers, Element, HTMLInputElementTypeId, LayoutElementHelpers};
+use dom::element::RawLayoutElementHelpers;
use dom::event::Event;
use dom::eventtarget::{EventTarget, NodeTargetTypeId};
use dom::htmlelement::HTMLElement;
+use dom::keyboardevent::KeyboardEvent;
use dom::htmlformelement::{InputElement, FormOwner, HTMLFormElement, HTMLFormElementHelpers, NotFromFormSubmitMethod};
use dom::node::{DisabledStateHelpers, Node, NodeHelpers, ElementNodeTypeId, document_from_node, window_from_node};
use dom::virtualmethods::VirtualMethods;
+use textinput::{TextInput, TriggerDefaultAction, DispatchInput, Nothing};
use servo_util::str::DOMString;
use string_cache::Atom;
@@ -51,9 +55,8 @@ pub struct HTMLInputElement {
htmlelement: HTMLElement,
input_type: Cell<InputType>,
checked: Cell<bool>,
- uncommitted_value: DOMRefCell<Option<String>>,
- value: DOMRefCell<Option<String>>,
size: Cell<u32>,
+ textinput: DOMRefCell<TextInput>,
}
impl HTMLInputElementDerived for EventTarget {
@@ -70,9 +73,8 @@ impl HTMLInputElement {
htmlelement: HTMLElement::new_inherited(HTMLInputElementTypeId, localName, prefix, document),
input_type: Cell::new(InputText),
checked: Cell::new(false),
- uncommitted_value: DOMRefCell::new(None),
- value: DOMRefCell::new(None),
size: Cell::new(DEFAULT_INPUT_SIZE),
+ textinput: DOMRefCell::new(TextInput::new(false, "".to_string())),
}
}
@@ -84,40 +86,55 @@ impl HTMLInputElement {
}
pub trait LayoutHTMLInputElementHelpers {
- unsafe fn get_value_for_layout(&self) -> String;
+ unsafe fn get_value_for_layout(self) -> String;
+ unsafe fn get_size_for_layout(self) -> u32;
+}
+
+pub trait RawLayoutHTMLInputElementHelpers {
unsafe fn get_size_for_layout(&self) -> u32;
}
-impl LayoutHTMLInputElementHelpers for HTMLInputElement {
+impl LayoutHTMLInputElementHelpers for JS<HTMLInputElement> {
#[allow(unrooted_must_root)]
- unsafe fn get_value_for_layout(&self) -> String {
- match self.input_type.get() {
+ unsafe fn get_value_for_layout(self) -> String {
+ unsafe fn get_raw_textinput_value(input: JS<HTMLInputElement>) -> Option<String> {
+ let elem: JS<Element> = input.transmute_copy();
+ if !elem.has_attr_for_layout(&ns!(""), &atom!("value")) {
+ return None;
+ }
+ Some((*input.unsafe_get()).textinput.borrow_for_layout().get_content())
+ }
+
+ unsafe fn get_raw_attr_value(input: JS<HTMLInputElement>) -> Option<String> {
+ let elem: JS<Element> = input.transmute_copy();
+ (*elem.unsafe_get()).get_attr_val_for_layout(&ns!(""), &atom!("value"))
+ .map(|s| s.to_string())
+ }
+
+ match (*self.unsafe_get()).input_type.get() {
InputCheckbox | InputRadio => "".to_string(),
InputFile | InputImage => "".to_string(),
- InputButton(ref default) => self.value.borrow_for_layout().clone()
+ InputButton(ref default) => get_raw_attr_value(self)
.or_else(|| default.map(|v| v.to_string()))
.unwrap_or_else(|| "".to_string()),
InputPassword => {
- let raw = self.value.borrow_for_layout().clone().unwrap_or_else(|| "".to_string());
- String::from_char(raw.len(), '*')
+ let raw = get_raw_textinput_value(self).unwrap_or_else(|| "".to_string());
+ String::from_char(raw.len(), '●')
}
- _ => self.value.borrow_for_layout().clone().unwrap_or_else(|| "".to_string()),
+ _ => get_raw_textinput_value(self).unwrap_or_else(|| "".to_string()),
}
}
#[allow(unrooted_must_root)]
- unsafe fn get_size_for_layout(&self) -> u32 {
- self.size.get()
+ unsafe fn get_size_for_layout(self) -> u32 {
+ (*self.unsafe_get()).get_size_for_layout()
}
}
-impl LayoutHTMLInputElementHelpers for JS<HTMLInputElement> {
- unsafe fn get_value_for_layout(&self) -> String {
- (*self.unsafe_get()).get_value_for_layout()
- }
-
+impl RawLayoutHTMLInputElementHelpers for HTMLInputElement {
+ #[allow(unrooted_must_root)]
unsafe fn get_size_for_layout(&self) -> u32 {
- (*self.unsafe_get()).get_size_for_layout()
+ self.size.get()
}
}
@@ -156,7 +173,7 @@ impl<'a> HTMLInputElementMethods for JSRef<'a, HTMLInputElement> {
// https://html.spec.whatwg.org/multipage/forms.html#dom-input-value
fn Value(self) -> DOMString {
- self.value.borrow().clone().unwrap_or("".to_string())
+ self.textinput.borrow().get_content()
}
// https://html.spec.whatwg.org/multipage/forms.html#dom-input-value
@@ -309,7 +326,7 @@ impl<'a> VirtualMethods for JSRef<'a, HTMLInputElement> {
self.force_relayout();
}
&atom!("value") => {
- *self.value.borrow_mut() = Some(attr.value().as_slice().to_string());
+ self.textinput.borrow_mut().set_content(attr.value().as_slice().to_string());
self.force_relayout();
}
&atom!("name") => {
@@ -353,7 +370,7 @@ impl<'a> VirtualMethods for JSRef<'a, HTMLInputElement> {
self.force_relayout();
}
&atom!("value") => {
- *self.value.borrow_mut() = None;
+ self.textinput.borrow_mut().set_content("".to_string());
self.force_relayout();
}
&atom!("name") => {
@@ -418,6 +435,18 @@ impl<'a> VirtualMethods for JSRef<'a, HTMLInputElement> {
let doc = document_from_node(*self).root();
doc.request_focus(ElementCast::from_ref(*self));
+ } else if "keydown" == event.Type().as_slice() && !event.DefaultPrevented() &&
+ (self.input_type.get() == InputText|| self.input_type.get() == InputPassword) {
+ 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 => (),
+ }
+ });
}
}
}