Auto merge of #14539 - frewsxcv:textarea-placeholder, r=mbrubeck

Show the placeholder text for textarea elements.

Fixes https://github.com/servo/servo/issues/10552.

All this logic was taken from htmlinputelement.rs.

<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/14539)
<!-- Reviewable:end -->
This commit is contained in:
bors-servo 2016-12-14 12:13:06 -08:00 committed by GitHub
commit 816b2969c3
5 changed files with 80 additions and 2 deletions

View file

@ -39,6 +39,7 @@ pub struct HTMLTextAreaElement {
htmlelement: HTMLElement, htmlelement: HTMLElement,
#[ignore_heap_size_of = "#7193"] #[ignore_heap_size_of = "#7193"]
textinput: DOMRefCell<TextInput<IpcSender<ConstellationMsg>>>, textinput: DOMRefCell<TextInput<IpcSender<ConstellationMsg>>>,
placeholder: DOMRefCell<DOMString>,
// https://html.spec.whatwg.org/multipage/#concept-textarea-dirty // https://html.spec.whatwg.org/multipage/#concept-textarea-dirty
value_changed: Cell<bool>, value_changed: Cell<bool>,
} }
@ -58,7 +59,12 @@ impl LayoutHTMLTextAreaElementHelpers for LayoutJS<HTMLTextAreaElement> {
#[allow(unrooted_must_root)] #[allow(unrooted_must_root)]
#[allow(unsafe_code)] #[allow(unsafe_code)]
unsafe fn get_value_for_layout(self) -> String { 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)] #[allow(unrooted_must_root)]
@ -105,6 +111,7 @@ impl HTMLTextAreaElement {
htmlelement: htmlelement:
HTMLElement::new_inherited_with_state(IN_ENABLED_STATE | IN_READ_WRITE_STATE, HTMLElement::new_inherited_with_state(IN_ENABLED_STATE | IN_READ_WRITE_STATE,
local_name, prefix, document), local_name, prefix, document),
placeholder: DOMRefCell::new(DOMString::new()),
textinput: DOMRefCell::new(TextInput::new( textinput: DOMRefCell::new(TextInput::new(
Lines::Multiple, DOMString::new(), chan, None, None, SelectionDirection::None)), Lines::Multiple, DOMString::new(), chan, None, None, SelectionDirection::None)),
value_changed: Cell::new(false), value_changed: Cell::new(false),
@ -119,6 +126,14 @@ impl HTMLTextAreaElement {
document, document,
HTMLTextAreaElementBinding::Wrap) 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 { 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") => { local_name!("readonly") => {
let el = self.upcast::<Element>(); let el = self.upcast::<Element>();
match mutation { match mutation {
@ -375,10 +400,14 @@ impl VirtualMethods for HTMLTextAreaElement {
document_from_node(self).request_focus(self.upcast()); document_from_node(self).request_focus(self.upcast());
} else if event.type_() == atom!("keydown") && !event.DefaultPrevented() { } else if event.type_() == atom!("keydown") && !event.DefaultPrevented() {
if let Some(kevent) = event.downcast::<KeyboardEvent>() { 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::TriggerDefaultAction => (),
KeyReaction::DispatchInput => { KeyReaction::DispatchInput => {
self.value_changed.set(true); self.value_changed.set(true);
self.update_placeholder_shown_state();
if event.IsTrusted() { if event.IsTrusted() {
let window = window_from_node(self); let window = window_from_node(self);

View file

@ -29,6 +29,7 @@ files = [
"./tests/unit/net/parsable_mime/text", "./tests/unit/net/parsable_mime/text",
"./tests/wpt/mozilla/tests/css/fonts", "./tests/wpt/mozilla/tests/css/fonts",
"./tests/wpt/mozilla/tests/css/pre_with_tab.html", "./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 # FIXME(pcwalton, #11679): This is a workaround for a tidy error on the quoted string
# `"__TEXT,_info_plist"` inside an attribute. # `"__TEXT,_info_plist"` inside an attribute.
"./components/servo/platform/macos/mod.rs", "./components/servo/platform/macos/mod.rs",

View file

@ -6498,6 +6498,18 @@
"url": "/_mozilla/mozilla/table_valign_uneven_height.html" "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": [ "mozilla/webgl/clearcolor.html": [
{ {
"path": "mozilla/webgl/clearcolor.html", "path": "mozilla/webgl/clearcolor.html",
@ -21546,6 +21558,18 @@
"url": "/_mozilla/mozilla/table_valign_uneven_height.html" "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": [ "mozilla/webgl/clearcolor.html": [
{ {
"path": "mozilla/webgl/clearcolor.html", "path": "mozilla/webgl/clearcolor.html",

View file

@ -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>

View file

@ -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>