aboutsummaryrefslogtreecommitdiffstats
path: root/components/script
diff options
context:
space:
mode:
Diffstat (limited to 'components/script')
-rw-r--r--components/script/dom/element.rs14
-rw-r--r--components/script/dom/htmlinputelement.rs31
-rw-r--r--components/script/textinput.rs5
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| {