opened
fastfasterfastest
username_0
There is a bug with the `textInput` binding when used with a textarea element under the following conditions:
- html5 mode
- value contains `U+000D CARRIAGE RETURN` characters

Then, the `textInput` binding will update the (model) value even though the user did not change the text in the textarea element.

In this fiddle http://jsfiddle.net/username_0/938r0k13/, just tabbing through the textarea causes the model value to be updated (alternatively, click in the textarea and then click outside the textarea).

The `textInput` binding implementation currently assumes that setting the textarea element's value will return that same value when later getting the textarea element's value.  However, that is not the case in html5 if the value contains `CR` characters.  In html5, the value returned by `element.value` is normalized and `CR` characters are transformed, see http://www.w3.org/TR/html5/forms.html#the-textarea-element, and thus one can not assume that one gets the same value that was set.
```
element.value = someValue;
someValue === element.value;	//not neccessarily true in html5
```

To trigger the bug you have to trigger some event that causes `textInput`'s internal `updateModel` function to be called.  That may not be easy in 3.4.2 but in the "latest"/pre-3.5.0 build it is easily done by triggering a `blur` event (the fiddle referenced above uses a pre-3.5.0 build that @username_1 made available a while ago).
`textInput` binding's handling of the `blur` event was added by https://github.com/knockout/knockout/commit/11e3cb93671b69b0fb26239ad4f2d2f75d6c6cc3

Note, the same issue may apply for the value binding as well, although it is not as easily exposed or triggered.

Looking at the sources, textInput.js, I think a fix could look something like:
```
var isHtml5 = true;  //[some test]
var transformModelValueForComparisonWithElementValue = isHtml5 && (ko.utils.tagNameLower(element) === "textarea") ?
    function (modelValue) { return (modelValue.indexOf("\r") !== -1) ? modelValue.replace(/(?:\r\n|\r)/g, "\n") : modelValue; } :
    function (modelValue) { return modelValue; };

var updateView = function () {
    var modelValue = ko.utils.unwrapObservable(valueAccessor()),
        modelValueTransformed;

    if (modelValue === null || modelValue === undefined) {
        modelValue = '';
    }

    //transform modelValue so it can be compared to element.value
    modelValueTransformed = transformModelValueForComparisonWithElementValue(modelValue);

    if (elementValueBeforeEvent !== undefined && modelValueTransformed === elementValueBeforeEvent) {
        ko.utils.setTimeout(updateView, 4);
        return;
    }

    // Update the element only if the element and model are different. On some browsers, updating the value
    // will move the cursor to the end of the input, which would be bad while the user is typing.
    if (element.value !== modelValueTransformed) {
        previousElementValue = modelValueTransformed;  // Make sure we ignore events (propertychange) that result from updating the value
        element.value = modelValue;
    }
};
textInput binding bug with textarea
issue
created
mbest
username_1
Would this fix it? Change

```
            if (element.value !== modelValue) {
                previousElementValue = modelValue;  // Make sure we ignore events (propertychange) that result from updating the value
                element.value = modelValue;
            }
```

to

```
            if (element.value !== modelValue) {
                previousElementValue = modelValue;  // Make sure we ignore events (propertychange) that result from updating the value
                element.value = modelValue;
                previousElementValue = element.value; // In case the browser changes the value (see #2281)
            }
```
comment
created
brianmhunt
username_2
comment
created
fastfasterfastest
username_0
@username_1 I don't think so.
First, the model value is compared to `elementValueBeforeEvent` before that as well.
Second, `previousElementValue` is compared to `element.value` in `updateModel` so it (`previousElementValue`) needs to be "comparable" to `element.value`, i.e. it needs to be the transformed value.  If `previousElementValue` is set to the untransformed model value as you suggest, then the comparison in `updateModel` will fail when it should succeed.
comment
closed
mbest
username_1
issue
created
mbest
username_1
My method appears to work fine. Let me know if you notice otherwise.
comment
created
fastfasterfastest
username_0
It's been a while... but if all stars are aligned then your method may work.

Regarding my first point: in the code of your method there is a comparison between an untransformed value and a transformed value (`modelValue === elementValueBeforeEvent`).  If that comparison does happen it will fail when it should succeed, but it is unclear if that comparison will/can actually take place or not without changing the text in the element.

The second point I made, it's been a while but, appears to be invalid.  `previousElementValue` is set to a transformed value and can thus be compared with `element.value`.
comment
created
mbest
username_1
I don't think the `elementValueBeforeEvent` check will be affected. For more info on why that exists, see #1334.
comment