-
Notifications
You must be signed in to change notification settings - Fork 47.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Correctly render placeholder for textarea in IE11 #8020
Conversation
07998a5
to
cb79db5
Compare
// TODO: Validate that text is allowed as a child of this node | ||
if (__DEV__) { | ||
setAndValidateContentChildDev.call(this, contentToUse); | ||
if (shouldSetNodeTextContent(lazyTree, props, contentToUse)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's just do contentToUse !== ''
here (and move the comment you have above down here to explain). No need to check for textarea/placeholder.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sounds good, I wasn't totally sure if there were situations where setting textContent
to an empty string was valid.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't know of any. :)
// initial value. In IE10/IE11 there is a bug where the placeholder attribute | ||
// will populate textContent as well. | ||
// https://developer.microsoft.com/microsoft-edge/platform/issues/101525/ | ||
if (textContent === inst._wrapperState.initialValue) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, when is this not true?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is false in IE11 when placeholder
has been set on a text area. There's a bug (linked in the comment above) where setting placeholder
also sets textContent
.
The bug report specifically mentions innerHTML
and innerText
, but it also effects textContent
331aa88
to
1e3331d
Compare
@spicyj removed |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My understanding is:
If you render <textarea defaultValue="A" />
then <textarea defaultValue="B" />
then .value should be A and you should see A in the textarea.
If you start with the empty string instead of A then .value should stay as ''
(and you should see the placeholder).
Can you confirm that these still work? I'm concerned that in the second case, .value will change to B when you change defaultValue=""
to defaultValue="B"
.
Accepting contingent on this working properly. If it doesn't, let's do another round.
if (__DEV__) { | ||
setAndValidateContentChildDev.call(this, contentToUse); | ||
// Avoid setting textContent when the text is empty. In IE11 setting | ||
// textContent on a text area will cause the placeholder to not |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
textarea
@spicyj It looks like it retains the initial empty value and the placeholder remains visible. Here's a JSFiddle with a build that includes this change, demonstrating the behavior: https://jsfiddle.net/e2Lqbc8r/ |
Cool. I don't have an IE handy but if you tested that case, feel free to ship this. |
shouldSetNodeTextContent returns whether a node.textContent should be updated. Currently it only covers one case, which is to avoid setting the textContent if the text is empty and a placeholder exists.
In IE11 textContent is populated when the placeholder attribute is set. Without this check, we end up setting node.value equal to the placeholder text, causing the textarea to actually render with the text inside. This check makes sure that textContent is equal to our expected initialValue, which should be the case when using defaultValue.
1e3331d
to
561b8f2
Compare
Tested in IE11 and IE10 👍 |
* Check if textContent should be set for textarea shouldSetNodeTextContent returns whether a node.textContent should be updated. Currently it only covers one case, which is to avoid setting the textContent if the text is empty and a placeholder exists. * Only set node.value if it's equal to initialValue In IE11 textContent is populated when the placeholder attribute is set. Without this check, we end up setting node.value equal to the placeholder text, causing the textarea to actually render with the text inside. This check makes sure that textContent is equal to our expected initialValue, which should be the case when using defaultValue. * Remove placeholder/textarea check, use contentToUse instead (cherry picked from commit e644faa)
This should be out in 15.4.2. |
* Check if textContent should be set for textarea shouldSetNodeTextContent returns whether a node.textContent should be updated. Currently it only covers one case, which is to avoid setting the textContent if the text is empty and a placeholder exists. * Only set node.value if it's equal to initialValue In IE11 textContent is populated when the placeholder attribute is set. Without this check, we end up setting node.value equal to the placeholder text, causing the textarea to actually render with the text inside. This check makes sure that textContent is equal to our expected initialValue, which should be the case when using defaultValue. * Remove placeholder/textarea check, use contentToUse instead
Resolves #6731
In IE11, setting the
node.placeholder
will also setnode.textContent
, so when we ended up settingtextContent
to""
viaDOMLazyTree.queueText
in in_createInitialChildren
, it caused the placeholder to never show up.18d418a resolves this by checking if the
<textarea/>
has aplaceholder
andtext
is empty. If it is, it skipsqueueText
.We were also unconditionally setting
node.value = node.textContent
, which before 18d418a just meant we'd set it to an empty string, but now we're settingnode.value
equal to the placeholder in IE11.07998a5 resolves this by only setting
node.value
iftextContent
is our expectedinitialValue
.Test plan
Tested with this component, which contains uncontrolled/controlled
<textarea/>
s with and withoutdefaultValue
/placeholder
Tested in the following browsers:
cc @spicyj @sebmarkbage