diff options
Diffstat (limited to 'components/script')
-rw-r--r-- | components/script/dom/element.rs | 14 | ||||
-rw-r--r-- | components/script/dom/htmlinputelement.rs | 31 | ||||
-rw-r--r-- | components/script/textinput.rs | 5 |
3 files changed, 42 insertions, 8 deletions
diff --git a/components/script/dom/element.rs b/components/script/dom/element.rs index fc4160f1843..0432be3987c 100644 --- a/components/script/dom/element.rs +++ b/components/script/dom/element.rs @@ -2222,7 +2222,8 @@ impl<'a> ::selectors::Element for Root<Element> { NonTSPseudoClass::Disabled | NonTSPseudoClass::Checked | NonTSPseudoClass::Indeterminate | - NonTSPseudoClass::ReadWrite => + NonTSPseudoClass::ReadWrite | + NonTSPseudoClass::PlaceholderShown => Element::state(self).contains(pseudo_class.state_flag()), } } @@ -2493,6 +2494,17 @@ impl Element { pub fn set_read_write_state(&self, value: bool) { self.set_state(IN_READ_WRITE_STATE, value) } + + pub fn placeholder_shown_state(&self) -> bool { + self.state.get().contains(IN_PLACEHOLDER_SHOWN_STATE) + } + + pub fn set_placeholder_shown_state(&self, value: bool) { + if self.placeholder_shown_state() != value { + self.set_state(IN_PLACEHOLDER_SHOWN_STATE, value); + self.upcast::<Node>().dirty(NodeDamage::OtherNodeDamage); + } + } } impl Element { diff --git a/components/script/dom/htmlinputelement.rs b/components/script/dom/htmlinputelement.rs index 04fc98a3982..a7bb9846bb9 100644 --- a/components/script/dom/htmlinputelement.rs +++ b/components/script/dom/htmlinputelement.rs @@ -709,6 +709,17 @@ impl HTMLInputElement { self.value_changed.set(false); self.upcast::<Node>().dirty(NodeDamage::OtherNodeDamage); } + + fn update_placeholder_shown_state(&self) { + match self.input_type.get() { + InputType::InputText | InputType::InputPassword => {}, + _ => return, + } + let has_placeholder = !self.placeholder.borrow().is_empty(); + let has_value = !self.textinput.borrow().is_empty(); + let el = self.upcast::<Element>(); + el.set_placeholder_shown_state(has_placeholder && !has_value); + } } impl VirtualMethods for HTMLInputElement { @@ -757,6 +768,7 @@ impl VirtualMethods for HTMLInputElement { self.size.set(size.unwrap_or(DEFAULT_INPUT_SIZE)); } &atom!("type") => { + let el = self.upcast::<Element>(); match mutation { AttributeMutation::Set(_) => { let new_type = match attr.value().as_atom() { @@ -774,7 +786,6 @@ impl VirtualMethods for HTMLInputElement { let (old_value_mode, old_idl_value) = (self.value_mode(), self.Value()); self.input_type.set(new_type); - let el = self.upcast::<Element>(); if new_type == InputType::InputText { let read_write = !(self.ReadOnly() || el.disabled_state()); el.set_read_write_state(read_write); @@ -831,11 +842,14 @@ impl VirtualMethods for HTMLInputElement { el.set_read_write_state(read_write); } } + + self.update_placeholder_shown_state(); }, &atom!("value") if !self.value_changed.get() => { let value = mutation.new_value(attr).map(|value| (**value).to_owned()); self.textinput.borrow_mut().set_content( value.map_or(DOMString::new(), DOMString::from)); + self.update_placeholder_shown_state(); }, &atom!("name") if self.input_type.get() == InputType::InputRadio => { self.radio_group_updated( @@ -854,13 +868,15 @@ impl VirtualMethods for HTMLInputElement { } } &atom!("placeholder") => { - // FIXME(ajeffrey): Should we do in-place mutation of the placeholder? - let mut placeholder = self.placeholder.borrow_mut(); - placeholder.clear(); - if let AttributeMutation::Set(_) = mutation { - placeholder.extend( - attr.value().chars().filter(|&c| c != '\n' && c != '\r')); + { + let mut placeholder = self.placeholder.borrow_mut(); + placeholder.clear(); + if let AttributeMutation::Set(_) = mutation { + placeholder.extend( + attr.value().chars().filter(|&c| c != '\n' && c != '\r')); + } } + self.update_placeholder_shown_state(); }, &atom!("readonly") if self.input_type.get() == InputType::InputText => { let el = self.upcast::<Element>(); @@ -936,6 +952,7 @@ impl VirtualMethods for HTMLInputElement { }, DispatchInput => { self.value_changed.set(true); + self.update_placeholder_shown_state(); if event.IsTrusted() { let window = window_from_node(self); diff --git a/components/script/textinput.rs b/components/script/textinput.rs index 5666fa617b4..c724c2691c4 100644 --- a/components/script/textinput.rs +++ b/components/script/textinput.rs @@ -549,6 +549,11 @@ impl<T: ClipboardProvider> TextInput<T> { } } + /// Whether the content is empty. + pub fn is_empty(&self) -> bool { + self.lines.len() <= 1 && self.lines.get(0).map_or(true, |line| line.is_empty()) + } + /// The length of the content in bytes. pub fn len(&self) -> usize { self.lines.iter().fold(0, |m, l| { |