Skip to content

Commit

Permalink
Merge 04f3a39 into 33c8360
Browse files Browse the repository at this point in the history
  • Loading branch information
marvinhagemeister committed Sep 11, 2019
2 parents 33c8360 + 04f3a39 commit ced8a6a
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 8 deletions.
3 changes: 2 additions & 1 deletion mangle.json
Expand Up @@ -39,7 +39,8 @@
"$_render": "__r",
"$_hook": "__h",
"$_catchError": "__e",
"$_unmount": "_e"
"$_unmount": "_e",
"$_lastValue": "__s"
}
}
}
4 changes: 4 additions & 0 deletions src/diff/index.js
Expand Up @@ -255,6 +255,10 @@ function diffElementNodes(dom, newVNode, oldVNode, context, isSvg, excessDomChil
// (as above, don't diff props during hydration)
if (!isHydrating) {
if (('value' in newProps) && newProps.value!==undefined && newProps.value !== dom.value) dom.value = newProps.value==null ? '' : newProps.value;
// preact/#1899
// We need this value for input masking.
dom._lastValue = dom.value;

if (('checked' in newProps) && newProps.checked!==undefined && newProps.checked !== dom.checked) dom.checked = newProps.checked;
}
}
Expand Down
3 changes: 2 additions & 1 deletion src/diff/props.js
Expand Up @@ -122,5 +122,6 @@ function setProperty(dom, name, value, oldValue, isSvg) {
* @private
*/
function eventProxy(e) {
return this._listeners[e.type](options.event ? options.event(e) : e);
this._listeners[e.type](options.event ? options.event(e) : e);
if (this._lastValue!=this.value) this.value = this._lastValue;
}
41 changes: 35 additions & 6 deletions test/browser/render.test.js
Expand Up @@ -25,6 +25,12 @@ function sortAttributes(html) {
});
}

function fireEvent(on, type) {
let e = document.createEvent('Event');
e.initEvent(type, true, true);
on.dispatchEvent(e);
}

describe('render()', () => {
let scratch, rerender;

Expand Down Expand Up @@ -274,6 +280,35 @@ describe('render()', () => {
expect(root.children[3]).to.have.property('value', '');
});

it('should sync controlled input value', () => {
class Controlled extends Component {
constructor(props) {
super(props);
this.state = { v: '' };
this.onInput = e => {
this.setState({ v: e.target.value.slice(0, 3) });
};
}

render() {
return <input value={this.state.v} onInput={this.onInput} />;
}
}

render(<Controlled />, scratch);

const input = scratch.firstChild;
input.value = 'abc';
fireEvent(input, 'input');
rerender();

input.value = 'abcde';
fireEvent(input, 'input');
expect(input.value).to.equal('abc');
rerender();
expect(input.value).to.equal('abc');
});

it('should set value inside the specified range', () => {
render(
<input type="range" value={0.5} min="0" max="1" step="0.05" />,
Expand Down Expand Up @@ -509,12 +544,6 @@ describe('render()', () => {
describe('event handling', () => {
let proto;

function fireEvent(on, type) {
let e = document.createEvent('Event');
e.initEvent(type, true, true);
on.dispatchEvent(e);
}

beforeEach(() => {
proto = document.createElement('div').constructor.prototype;

Expand Down

0 comments on commit ced8a6a

Please sign in to comment.