diff --git a/packages/morph-attr/lib/main.js b/packages/morph-attr/lib/main.js index 48f39332..c6a1003d 100644 --- a/packages/morph-attr/lib/main.js +++ b/packages/morph-attr/lib/main.js @@ -9,8 +9,16 @@ function getProperty() { function updateProperty(value) { if (this._renderedInitially === true || !isAttrRemovalValue(value)) { - // do not render if initial value is undefined or null - this.domHelper.setPropertyStrict(this.element, this.attrName, value); + let element = this.element; + let attrName = this.attrName; + + if (attrName === 'value' && element.tagName === 'INPUT' && element.value === value) { + // Do nothing. Attempts to avoid accidently changing the input cursor location. + // See https://github.com/tildeio/htmlbars/pull/447 for more details. + } else { + // do not render if initial value is undefined or null + this.domHelper.setPropertyStrict(element, attrName, value); + } } this._renderedInitially = true; diff --git a/packages/morph-attr/tests/attr-morph-test.js b/packages/morph-attr/tests/attr-morph-test.js index 7284f5b2..a9b242bc 100644 --- a/packages/morph-attr/tests/attr-morph-test.js +++ b/packages/morph-attr/tests/attr-morph-test.js @@ -2,6 +2,7 @@ import DOMHelper from "../dom-helper"; import SafeString from "htmlbars-util/safe-string"; +import AttrMorph from "morph-attr"; var svgNamespace = "http://www.w3.org/2000/svg", xlinkNamespace = "http://www.w3.org/1999/xlink"; @@ -249,3 +250,27 @@ test("embed src as data uri is sanitized", function() { 'unsafe:data:image/svg+xml;base64,PH', 'attribute is escaped'); }); + +// Regression test for https://github.com/tildeio/htmlbars/pull/447. +test("the value property of an input element is not set if the value hasn't changed", function() { + let calls = 0; + + let domHelperStub = { + setPropertyStrict() { + calls++; + } + }; + + let input = document.createElement('input'); + let morph = AttrMorph.create(input, 'value', domHelperStub); + + equal(calls, 0); + morph.setContent('one'); + equal(calls, 1); + morph.setContent('one'); + equal(calls, 1); + morph.setContent('two'); + equal(calls, 2); + morph.setContent('two'); + equal(calls, 2); +});