diff options
-rwxr-xr-x | components/script/dom/htmltextareaelement.rs | 33 | ||||
-rw-r--r-- | servo-tidy.toml | 1 | ||||
-rw-r--r-- | tests/wpt/mozilla/meta/MANIFEST.json | 24 | ||||
-rw-r--r-- | tests/wpt/mozilla/tests/mozilla/textarea_placeholder.html | 11 | ||||
-rw-r--r-- | tests/wpt/mozilla/tests/mozilla/textarea_placeholder_ref.html | 13 |
5 files changed, 80 insertions, 2 deletions
diff --git a/components/script/dom/htmltextareaelement.rs b/components/script/dom/htmltextareaelement.rs index 47b9bb6ee0b..87e9fb532d3 100755 --- a/components/script/dom/htmltextareaelement.rs +++ b/components/script/dom/htmltextareaelement.rs @@ -39,6 +39,7 @@ pub struct HTMLTextAreaElement { htmlelement: HTMLElement, #[ignore_heap_size_of = "#7193"] textinput: DOMRefCell<TextInput<IpcSender<ConstellationMsg>>>, + placeholder: DOMRefCell<DOMString>, // https://html.spec.whatwg.org/multipage/#concept-textarea-dirty value_changed: Cell<bool>, } @@ -58,7 +59,12 @@ impl LayoutHTMLTextAreaElementHelpers for LayoutJS<HTMLTextAreaElement> { #[allow(unrooted_must_root)] #[allow(unsafe_code)] unsafe fn get_value_for_layout(self) -> String { - String::from((*self.unsafe_get()).textinput.borrow_for_layout().get_content()) + let text = (*self.unsafe_get()).textinput.borrow_for_layout().get_content(); + String::from(if text.is_empty() { + (*self.unsafe_get()).placeholder.borrow_for_layout().clone() + } else { + text + }) } #[allow(unrooted_must_root)] @@ -105,6 +111,7 @@ impl HTMLTextAreaElement { htmlelement: HTMLElement::new_inherited_with_state(IN_ENABLED_STATE | IN_READ_WRITE_STATE, local_name, prefix, document), + placeholder: DOMRefCell::new(DOMString::new()), textinput: DOMRefCell::new(TextInput::new( Lines::Multiple, DOMString::new(), chan, None, None, SelectionDirection::None)), value_changed: Cell::new(false), @@ -119,6 +126,14 @@ impl HTMLTextAreaElement { document, HTMLTextAreaElementBinding::Wrap) } + + fn update_placeholder_shown_state(&self) { + 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); + el.set_placeholder_shown_state(has_placeholder); + } } impl HTMLTextAreaElementMethods for HTMLTextAreaElement { @@ -311,6 +326,16 @@ impl VirtualMethods for HTMLTextAreaElement { } } }, + local_name!("placeholder") => { + { + let mut placeholder = self.placeholder.borrow_mut(); + placeholder.clear(); + if let AttributeMutation::Set(_) = mutation { + placeholder.push_str(&attr.value()); + } + } + self.update_placeholder_shown_state(); + }, local_name!("readonly") => { let el = self.upcast::<Element>(); match mutation { @@ -375,10 +400,14 @@ impl VirtualMethods for HTMLTextAreaElement { document_from_node(self).request_focus(self.upcast()); } else if event.type_() == atom!("keydown") && !event.DefaultPrevented() { if let Some(kevent) = event.downcast::<KeyboardEvent>() { - match self.textinput.borrow_mut().handle_keydown(kevent) { + // This can't be inlined, as holding on to textinput.borrow_mut() + // during self.implicit_submission will cause a panic. + let action = self.textinput.borrow_mut().handle_keydown(kevent); + match action { KeyReaction::TriggerDefaultAction => (), KeyReaction::DispatchInput => { self.value_changed.set(true); + self.update_placeholder_shown_state(); if event.IsTrusted() { let window = window_from_node(self); diff --git a/servo-tidy.toml b/servo-tidy.toml index 194a1658a3c..755d0282b32 100644 --- a/servo-tidy.toml +++ b/servo-tidy.toml @@ -29,6 +29,7 @@ files = [ "./tests/unit/net/parsable_mime/text", "./tests/wpt/mozilla/tests/css/fonts", "./tests/wpt/mozilla/tests/css/pre_with_tab.html", + "./tests/wpt/mozilla/tests/mozilla/textarea_placeholder.html", # FIXME(pcwalton, #11679): This is a workaround for a tidy error on the quoted string # `"__TEXT,_info_plist"` inside an attribute. "./components/servo/platform/macos/mod.rs", diff --git a/tests/wpt/mozilla/meta/MANIFEST.json b/tests/wpt/mozilla/meta/MANIFEST.json index 23b77f9ed85..bfd49e221e8 100644 --- a/tests/wpt/mozilla/meta/MANIFEST.json +++ b/tests/wpt/mozilla/meta/MANIFEST.json @@ -6498,6 +6498,18 @@ "url": "/_mozilla/mozilla/table_valign_uneven_height.html" } ], + "mozilla/textarea_placeholder.html": [ + { + "path": "mozilla/textarea_placeholder.html", + "references": [ + [ + "/_mozilla/mozilla/textarea_placeholder_ref.html", + "==" + ] + ], + "url": "/_mozilla/mozilla/textarea_placeholder.html" + } + ], "mozilla/webgl/clearcolor.html": [ { "path": "mozilla/webgl/clearcolor.html", @@ -21546,6 +21558,18 @@ "url": "/_mozilla/mozilla/table_valign_uneven_height.html" } ], + "mozilla/textarea_placeholder.html": [ + { + "path": "mozilla/textarea_placeholder.html", + "references": [ + [ + "/_mozilla/mozilla/textarea_placeholder_ref.html", + "==" + ] + ], + "url": "/_mozilla/mozilla/textarea_placeholder.html" + } + ], "mozilla/webgl/clearcolor.html": [ { "path": "mozilla/webgl/clearcolor.html", diff --git a/tests/wpt/mozilla/tests/mozilla/textarea_placeholder.html b/tests/wpt/mozilla/tests/mozilla/textarea_placeholder.html new file mode 100644 index 00000000000..6dd1f1e1e0c --- /dev/null +++ b/tests/wpt/mozilla/tests/mozilla/textarea_placeholder.html @@ -0,0 +1,11 @@ +<!doctype html> +<meta charset="utf-8"> +<link rel="match" href="textarea_placeholder_ref.html"> + +<textarea placeholder=""></textarea> +<textarea placeholder=" "></textarea> +<textarea placeholder="foobar"></textarea> +<textarea placeholder=" foo bar "></textarea> +<textarea rows=5 placeholder="
foo + bar
"></textarea> +<textarea placeholder="foo bar">lorem ipsum</textarea> diff --git a/tests/wpt/mozilla/tests/mozilla/textarea_placeholder_ref.html b/tests/wpt/mozilla/tests/mozilla/textarea_placeholder_ref.html new file mode 100644 index 00000000000..46d2686144f --- /dev/null +++ b/tests/wpt/mozilla/tests/mozilla/textarea_placeholder_ref.html @@ -0,0 +1,13 @@ +<!doctype html> +<meta charset="utf-8"> + +<textarea></textarea> +<textarea></textarea> +<textarea>foobar</textarea> +<textarea> foo bar </textarea> +<textarea rows=5> + + foo + bar +</textarea> +<textarea>lorem ipsum</textarea> |