From e111d7185bd0d2f8537ba92bb27e52468e349890 Mon Sep 17 00:00:00 2001 From: Brandon Pugh Date: Sat, 13 Feb 2016 20:17:31 -0600 Subject: [PATCH 01/44] Migrate build process to nwb - Removes .npmignore in favor of whitelisting with "files" in package.json - Removes dist folder and instead builds to umd folder that is only published to npm and hosted on npmcdn instead of checking into git - Remove 'use strict' statement since babel inserts it automactically --- .gitignore | 9 +- .npmignore | 7 - demo/index.html | 2 +- dist/react-maskedinput.js | 1337 --------------------------------- dist/react-maskedinput.min.js | 5 - nwb.config.js | 21 + package.json | 42 +- src/{index.jsx => index.js} | 2 - 8 files changed, 45 insertions(+), 1380 deletions(-) delete mode 100644 .npmignore delete mode 100644 dist/react-maskedinput.js delete mode 100644 dist/react-maskedinput.min.js create mode 100644 nwb.config.js rename src/{index.jsx => index.js} (99%) diff --git a/.gitignore b/.gitignore index 46f1072..4994ab3 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,7 @@ -lib/ -node_modules/ \ No newline at end of file +/coverage +/demo/dist +/es6 +/lib +/node_modules +/umd +npm-debug.log diff --git a/.npmignore b/.npmignore deleted file mode 100644 index 564d394..0000000 --- a/.npmignore +++ /dev/null @@ -1,7 +0,0 @@ -demo -src -test -.gitignore -.jshintrc -.travis.yml -gulpfile.js diff --git a/demo/index.html b/demo/index.html index e1c166d..e8b0e1f 100644 --- a/demo/index.html +++ b/demo/index.html @@ -5,7 +5,7 @@ - + - - -
- - +render(, document.getElementById('demo')) diff --git a/demo/src/style.css b/demo/src/style.css new file mode 100644 index 0000000..0c54f0c --- /dev/null +++ b/demo/src/style.css @@ -0,0 +1,41 @@ +body { + box-sizing: border-box; + width: 550px; + margin: 1em auto; + padding: 0 1em; + font-family: sans-serif; +} +code { + font-size: 1.3em; +} +h1 { + font-size: 3em; + text-align: center; + margin-top: 0; +} +p.lead { + font-weight: bold; + text-align: center; +} +hr { + margin-top: 20px; + margin-bottom: 20px; + border: 0; + border-top: 1px solid #222; +} +.form-field { + margin-bottom: .5em; +} +label { + display: inline-block; + width: 7em; + text-align: right; + margin-right: .75em; +} +input { + border: none; + font-size: 1.5em; +} +footer { + text-align: center; +} From 898a14a1ca4d25d69e16948d0e7d6d18c555902a Mon Sep 17 00:00:00 2001 From: Michael Henderson Date: Fri, 8 Apr 2016 12:49:41 -0400 Subject: [PATCH 10/44] Updating React and ReactDOM dependencies to v15; allowing minor and patch updates in peerDependencies --- package.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index 14a214a..072f8e0 100644 --- a/package.json +++ b/package.json @@ -31,13 +31,13 @@ "inputmask-core": "^2.1.1" }, "peerDependencies": { - "react": "0.14.x" + "react": "0.14.x || 15.x.x" }, "devDependencies": { "eslint-config-jonnybuchanan": "2.0.3", "nwb": "0.8.x", - "react": "0.14.x", - "react-dom": "0.14.x" + "react": "15.x.x", + "react-dom": "15.x.x" }, "repository": { "type": "git", From 36eb9481c111512a3002dd302811459e6161cba6 Mon Sep 17 00:00:00 2001 From: Dustan Kasten Date: Mon, 11 Apr 2016 10:47:04 -0400 Subject: [PATCH 11/44] v3.1.1 changelist --- CHANGES.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGES.md b/CHANGES.md index 7b69d30..3df2db5 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,3 +1,7 @@ +## 3.1.2 / 2016-04-11 + +* Support for React 15.x.x + ## 3.1.1 / 2016-03-09 * Convert tooling to use [nwb](https://github.com/insin/nwb/) [[bpugh]][[bpugh]] From cd97d3e81c0f1c89020835c31b56f92f1cc0e0f1 Mon Sep 17 00:00:00 2001 From: Dustan Kasten Date: Mon, 11 Apr 2016 10:47:10 -0400 Subject: [PATCH 12/44] 3.1.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 072f8e0..d416487 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "react-maskedinput", "description": "Masked React component", - "version": "3.1.1", + "version": "3.1.2", "main": "./lib/index.js", "jsnext:main": "es6/index.js", "standalone": "MaskedInput", From 47f45f611d5821cde830859c706e50042e6cc4d0 Mon Sep 17 00:00:00 2001 From: Brandon Pugh Date: Fri, 29 Apr 2016 21:57:00 -0500 Subject: [PATCH 13/44] Update nwb dependency to 0.9.x Updates a number of transitive dependency versions as a result of all the left-pad hubbub --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index d416487..789696f 100644 --- a/package.json +++ b/package.json @@ -35,7 +35,7 @@ }, "devDependencies": { "eslint-config-jonnybuchanan": "2.0.3", - "nwb": "0.8.x", + "nwb": "0.9.x", "react": "15.x.x", "react-dom": "15.x.x" }, From d9ac7a0c20a8c8aa8ed749082968d477bccb0281 Mon Sep 17 00:00:00 2001 From: Arseny Sysolyatin Date: Mon, 2 May 2016 18:31:51 +0400 Subject: [PATCH 14/44] Call this.props.onChange only if it's defined (#39) Call this.props.onChange only if it's defined --- src/index.js | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/src/index.js b/src/index.js index e1b70dd..747c39e 100644 --- a/src/index.js +++ b/src/index.js @@ -88,7 +88,9 @@ var MaskedInput = React.createClass({ if (this.mask.undo()) { e.target.value = this._getDisplayValue() this._updateInputSelection() - this.props.onChange(e) + if (this.props.onChange) { + this.props.onChange(e) + } } return } @@ -97,7 +99,9 @@ var MaskedInput = React.createClass({ if (this.mask.redo()) { e.target.value = this._getDisplayValue() this._updateInputSelection() - this.props.onChange(e) + if (this.props.onChange) { + this.props.onChange(e) + } } return } @@ -111,7 +115,9 @@ var MaskedInput = React.createClass({ if (value) { this._updateInputSelection() } - this.props.onChange(e) + if (this.props.onChange) { + this.props.onChange(e) + } } } }, @@ -128,7 +134,9 @@ var MaskedInput = React.createClass({ if (this.mask.input(e.key)) { e.target.value = this.mask.getValue() this._updateInputSelection() - this.props.onChange(e) + if (this.props.onChange) { + this.props.onChange(e) + } } }, @@ -142,7 +150,9 @@ var MaskedInput = React.createClass({ e.target.value = this.mask.getValue() // Timeout needed for IE setTimeout(this._updateInputSelection, 0) - this.props.onChange(e) + if (this.props.onChange) { + this.props.onChange(e) + } } }, From 1c698bc0265a1f0e1b5188e0701a817b97c07e58 Mon Sep 17 00:00:00 2001 From: Dustan Kasten Date: Mon, 2 May 2016 10:38:23 -0400 Subject: [PATCH 15/44] v3.1.3 --- CHANGES.md | 5 +++++ package.json | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGES.md b/CHANGES.md index 3df2db5..c9c1b42 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,3 +1,8 @@ +## 3.1.3 / 2016-05-02 + +* Don’t call `onChange` function if undefined. +* Update nwb to 0.9.x + ## 3.1.2 / 2016-04-11 * Support for React 15.x.x diff --git a/package.json b/package.json index 789696f..a9ecc3f 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "react-maskedinput", "description": "Masked React component", - "version": "3.1.2", + "version": "3.1.3", "main": "./lib/index.js", "jsnext:main": "es6/index.js", "standalone": "MaskedInput", From 61e395bf4388373e14a79412d2597652b6b6dd7d Mon Sep 17 00:00:00 2001 From: Dustan Kasten Date: Mon, 2 May 2016 13:15:43 -0400 Subject: [PATCH 16/44] Init tests (#51) * basic tests * travis --- .travis.yml | 5 +++++ tests/index-test.js | 50 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+) create mode 100644 .travis.yml create mode 100644 tests/index-test.js diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..5c036ab --- /dev/null +++ b/.travis.yml @@ -0,0 +1,5 @@ +language: node_js +node_js: + - "4" + - "5" +script: npm test diff --git a/tests/index-test.js b/tests/index-test.js new file mode 100644 index 0000000..e48f6e9 --- /dev/null +++ b/tests/index-test.js @@ -0,0 +1,50 @@ +/* eslint-env mocha */ +import React from 'react' +import ReactDOM from 'react-dom' +import expect from 'expect' +import MaskedInput from 'src' + +const setup = () => { + const element = document.createElement('div') + document.body.appendChild(element) + return element; +}; + +const cleanup = (element) => { + ReactDOM.unmountComponentAtNode(element) + document.body.removeChild(element) +} + +describe('MaskedInput', () => { + it('should render (smokescreen test)', () => { + expect.spyOn(console, 'error') + expect().toExist() + expect(console.error.calls[0].arguments[0]).toBe( + 'Warning: Failed propType: Required prop `mask` was not specified in ' + + '`MaskedInput`.' + ) + }) + + it('should handle a masking workflow', () => { + const el = setup() + let ref = null + ReactDOM.render( + { + if (r) ref = r + }} + mask="11/11" + />, + el + ) + const input = ReactDOM.findDOMNode(ref) + + // initial state + expect(input.value).toBe('') + expect(input.placeholder).toBe('__/__') + expect(input.size).toBe(5) + + cleanup(el) + }) +}) + From d78f89b6e01c3ecb515a3ab491b78b7f23b122dd Mon Sep 17 00:00:00 2001 From: Vyacheslav Slinko Date: Fri, 20 May 2016 18:48:03 +0300 Subject: [PATCH 17/44] Proxy focus and blur methos (#52) --- src/index.js | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/index.js b/src/index.js index 747c39e..71be730 100644 --- a/src/index.js +++ b/src/index.js @@ -160,6 +160,14 @@ var MaskedInput = React.createClass({ var value = this.mask.getValue() return value === this.mask.emptyValue ? '' : value }, + + focus() { + this.input.focus(); + }, + + blur() { + this.input.blur(); + }, render() { var {mask, formatCharacters, size, placeholder, ...props} = this.props From aee2ccf6eb950f5a62c94f2afdcc140343d78c18 Mon Sep 17 00:00:00 2001 From: martinphee Date: Tue, 24 May 2016 08:34:55 -0500 Subject: [PATCH 18/44] Add support for updating the `mask`. Fixes #8 When resetting the mask the cursor would jump to the end of the line. This PR fixes that behavior. --- demo/src/index.js | 16 +++++++++++++++- src/index.js | 19 +++++++++++++++++++ tests/index-test.js | 41 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 75 insertions(+), 1 deletion(-) diff --git a/demo/src/index.js b/demo/src/index.js index e2a64e6..024e4b8 100644 --- a/demo/src/index.js +++ b/demo/src/index.js @@ -23,7 +23,8 @@ const App = React.createClass({ leading: '', custom: '', changing: '', - pattern: '1111 1111' + pattern: '1111 1111', + cardPattern: '1111 1111 1111 1111' } }, @@ -37,6 +38,14 @@ const App = React.createClass({ this.setState({pattern: e.target.value}) }, + _onCardChange(e) { + if(/^3[47]/.test(e.target.value)) { + this.setState({cardPattern: "1111 111111 11111"}) + } else { + this.setState({cardPattern: '1111 1111 1111 1111'}) + } + }, + render() { return

@@ -86,6 +95,11 @@ const App = React.createClass({ {PATTERNS.map(pattern => )}

+

Dynamically changing the pattern as the user types:

+
+ + +

Custom format character (W=[a-zA-Z0-9_], transformed to uppercase) and placeholder character (en space):

diff --git a/src/index.js b/src/index.js index 747c39e..5750d70 100644 --- a/src/index.js +++ b/src/index.js @@ -49,6 +49,25 @@ var MaskedInput = React.createClass({ } }, + componentWillUpdate(nextProps, nextState) { + if (nextProps.mask !== this.props.mask) { + this._updatePattern(nextProps) + } + }, + + componentDidUpdate(prevProps) { + if (prevProps.mask !== this.props.mask && this.mask.selection.start) { + this._updateInputSelection() + } + }, + + _updatePattern: function(props) { + this.mask.setPattern(props.mask, { + value: this.mask.getRawValue(), + selection: getSelection(this.input) + }); + }, + _updateMaskSelection() { this.mask.selection = getSelection(this.input) }, diff --git a/tests/index-test.js b/tests/index-test.js index e48f6e9..889a838 100644 --- a/tests/index-test.js +++ b/tests/index-test.js @@ -46,5 +46,46 @@ describe('MaskedInput', () => { cleanup(el) }) + + it('should handle updating mask masking', () => { + const el = setup() + let ref = null + let defaultMask = '1111 1111 1111 1111' + let amexMask = '1111 111111 11111' + let mask = defaultMask + + function render() { + ReactDOM.render( + { + if (r) ref = r + }} + mask={mask} + />, + el + ) + } + + render(); + let input = ReactDOM.findDOMNode(ref) + + // initial state + expect(input.value).toBe('') + expect(input.placeholder).toBe('____ ____ ____ ____') + expect(input.size).toBe(19) + expect(input.selectionStart).toBe(0) + + mask = amexMask + render(); + input = ReactDOM.findDOMNode(ref) + + // initial state + expect(input.value).toBe('') + expect(input.placeholder).toBe('____ ______ _____') + expect(input.size).toBe(17) + expect(input.selectionStart).toBe(0) + + cleanup(el) + }) }) From ed4808660b67d75794978bb85daee2f87941b810 Mon Sep 17 00:00:00 2001 From: Jason Quense Date: Tue, 24 May 2016 14:55:35 -0400 Subject: [PATCH 19/44] v3.2.0 --- CHANGES.md | 7 ++++++- package.json | 2 +- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index c9c1b42..fa2ef21 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,8 +1,12 @@ +## 3.2.0 / 2016-05-24 + +* Allow dynamic pattern updating [[martyphee][martyphee]] + ## 3.1.3 / 2016-05-02 * Don’t call `onChange` function if undefined. * Update nwb to 0.9.x - +s ## 3.1.2 / 2016-04-11 * Support for React 15.x.x @@ -60,3 +64,4 @@ Initial release features: [jquense]: https://github.com/jquense [muffinresearch]: https://github.com/muffinresearch +[martyphee]: https://github.com/martyphee diff --git a/package.json b/package.json index a9ecc3f..9935e8f 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "react-maskedinput", "description": "Masked React component", - "version": "3.1.3", + "version": "3.2.0", "main": "./lib/index.js", "jsnext:main": "es6/index.js", "standalone": "MaskedInput", From bab325fcd36dba523d9aa1b1da385da7ffb4b019 Mon Sep 17 00:00:00 2001 From: Alexandr Date: Wed, 20 Jul 2016 18:14:39 +0400 Subject: [PATCH 20/44] Fix issue #61, remove react warning (#62) --- src/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/index.js b/src/index.js index 20568a2..238a544 100644 --- a/src/index.js +++ b/src/index.js @@ -189,7 +189,7 @@ var MaskedInput = React.createClass({ }, render() { - var {mask, formatCharacters, size, placeholder, ...props} = this.props + var {mask, formatCharacters, size, placeholder, placeholderChar, ...props} = this.props var patternLength = this.mask.pattern.length return this.input = r } From fc424406d7be795aebd10b486eadaa5044725e7b Mon Sep 17 00:00:00 2001 From: Dustan Kasten Date: Wed, 20 Jul 2016 10:38:50 -0400 Subject: [PATCH 21/44] flint on posttest. fix lint (#63) --- package.json | 3 ++- src/index.js | 10 +++++----- tests/index-test.js | 16 +++++++++------- 3 files changed, 16 insertions(+), 13 deletions(-) diff --git a/package.json b/package.json index 9935e8f..20f36eb 100644 --- a/package.json +++ b/package.json @@ -22,9 +22,10 @@ "scripts": { "build": "nwb build", "clean": "nwb clean", - "lint": "eslint src", + "lint": "eslint src tests", "start": "nwb serve", "test": "nwb test", + "posttest": "npm run lint", "test:watch": "nwb test --server" }, "dependencies": { diff --git a/src/index.js b/src/index.js index 238a544..1602a1e 100644 --- a/src/index.js +++ b/src/index.js @@ -65,7 +65,7 @@ var MaskedInput = React.createClass({ this.mask.setPattern(props.mask, { value: this.mask.getRawValue(), selection: getSelection(this.input) - }); + }) }, _updateMaskSelection() { @@ -179,13 +179,13 @@ var MaskedInput = React.createClass({ var value = this.mask.getValue() return value === this.mask.emptyValue ? '' : value }, - + focus() { - this.input.focus(); + this.input.focus() }, - + blur() { - this.input.blur(); + this.input.blur() }, render() { diff --git a/tests/index-test.js b/tests/index-test.js index 889a838..8c6ae6d 100644 --- a/tests/index-test.js +++ b/tests/index-test.js @@ -7,8 +7,8 @@ import MaskedInput from 'src' const setup = () => { const element = document.createElement('div') document.body.appendChild(element) - return element; -}; + return element +} const cleanup = (element) => { ReactDOM.unmountComponentAtNode(element) @@ -19,9 +19,11 @@ describe('MaskedInput', () => { it('should render (smokescreen test)', () => { expect.spyOn(console, 'error') expect().toExist() - expect(console.error.calls[0].arguments[0]).toBe( - 'Warning: Failed propType: Required prop `mask` was not specified in ' + - '`MaskedInput`.' + expect(console.error.calls[0].arguments[0]).toMatch( + new RegExp( + 'Warning: Failed prop type: Required prop ' + + '`mask` was not specified in `MaskedInput`.' + ) ) }) @@ -66,7 +68,7 @@ describe('MaskedInput', () => { ) } - render(); + render() let input = ReactDOM.findDOMNode(ref) // initial state @@ -76,7 +78,7 @@ describe('MaskedInput', () => { expect(input.selectionStart).toBe(0) mask = amexMask - render(); + render() input = ReactDOM.findDOMNode(ref) // initial state From 65dd7b626f09a3fb6f8ad94407b5b23c232b1710 Mon Sep 17 00:00:00 2001 From: Dustan Kasten Date: Wed, 20 Jul 2016 10:40:56 -0400 Subject: [PATCH 22/44] 3.2.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 20f36eb..a7eb45c 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "react-maskedinput", "description": "Masked React component", - "version": "3.2.0", + "version": "3.2.1", "main": "./lib/index.js", "jsnext:main": "es6/index.js", "standalone": "MaskedInput", From 4da17a82dd8c6b843ff81d9cbad418c3e4ddca47 Mon Sep 17 00:00:00 2001 From: Dustan Kasten Date: Fri, 22 Jul 2016 11:43:47 -0400 Subject: [PATCH 23/44] 3.2.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index a7eb45c..0525df0 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "react-maskedinput", "description": "Masked React component", - "version": "3.2.1", + "version": "3.2.2", "main": "./lib/index.js", "jsnext:main": "es6/index.js", "standalone": "MaskedInput", From b2b37caf6f9f77c6d5e7155331309f8f3f7f3324 Mon Sep 17 00:00:00 2001 From: Hunter Cassidy Date: Wed, 27 Jul 2016 16:13:38 -0400 Subject: [PATCH 24/44] update new patterns before new values to prevent leftover placeholder characters (#64) --- src/index.js | 7 ++++--- tests/index-test.js | 43 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 3 deletions(-) diff --git a/src/index.js b/src/index.js index 1602a1e..a20d694 100644 --- a/src/index.js +++ b/src/index.js @@ -41,12 +41,13 @@ var MaskedInput = React.createClass({ }, componentWillReceiveProps(nextProps) { - if (this.props.value !== nextProps.value) { - this.mask.setValue(nextProps.value) - } + // update the pattern first to avoid left over placeholders if (this.props.mask !== nextProps.mask) { this.mask.setPattern(nextProps.mask, {value: this.mask.getRawValue()}) } + if (this.props.value !== nextProps.value) { + this.mask.setValue(nextProps.value) + } }, componentWillUpdate(nextProps, nextState) { diff --git a/tests/index-test.js b/tests/index-test.js index 8c6ae6d..3ffa9fc 100644 --- a/tests/index-test.js +++ b/tests/index-test.js @@ -89,5 +89,48 @@ describe('MaskedInput', () => { cleanup(el) }) + + it('should remove leftover placeholder characters when switching to smaller mask', () => { + const el = setup() + let ref = null + let defaultMask = '1111 1111 1111 1111' + let amexMask = '1111 111111 11111' + let mask = defaultMask + let value = null + + function render(props) { + ReactDOM.render( + { + if (r) ref = r + }} + mask={mask} + value={value} + />, + el + ) + } + + render() + let input = ReactDOM.findDOMNode(ref) + + // initial state + expect(input.value).toBe('') + expect(input.placeholder).toBe('____ ____ ____ ____') + expect(input.size).toBe(19) + expect(input.selectionStart).toBe(0) + + mask = amexMask + value = '1234 123456 12345' + render() + input = ReactDOM.findDOMNode(ref) + console.log(input) + + // initial state + expect(input.value).toBe('1234 123456 12345') + expect(input.size).toBe(17) + + cleanup(el) + }) }) From a2ba36f7c6867257b7513c57e1e3b95de3ba6d5e Mon Sep 17 00:00:00 2001 From: Dustan Kasten Date: Wed, 27 Jul 2016 16:15:39 -0400 Subject: [PATCH 25/44] 3.2.3 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 0525df0..a916da3 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "react-maskedinput", "description": "Masked React component", - "version": "3.2.2", + "version": "3.2.3", "main": "./lib/index.js", "jsnext:main": "es6/index.js", "standalone": "MaskedInput", From 9367fe050139fca4b88e3fef4e8f81ec5f31220c Mon Sep 17 00:00:00 2001 From: Hunter Cassidy Date: Tue, 9 Aug 2016 11:08:28 -0400 Subject: [PATCH 26/44] add conditional for mask and value changing at same time (#66) --- src/index.js | 17 +++++- tests/index-test.js | 136 +++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 141 insertions(+), 12 deletions(-) diff --git a/src/index.js b/src/index.js index a20d694..d91f6e2 100644 --- a/src/index.js +++ b/src/index.js @@ -41,11 +41,22 @@ var MaskedInput = React.createClass({ }, componentWillReceiveProps(nextProps) { - // update the pattern first to avoid left over placeholders - if (this.props.mask !== nextProps.mask) { + if (this.props.mask !== nextProps.mask && this.props.value !== nextProps.mask) { + // if we get a new value and a new mask at the same time + // check if the mask.value is still the initial value + // - if so use the nextProps value + // - otherwise the `this.mask` has a value for us (most likely from paste action) + if (this.mask.getValue() === this.mask.emptyValue) { + this.mask.setPattern(nextProps.mask, {value: nextProps.value}) + } + else { + this.mask.setPattern(nextProps.mask, {value: this.mask.getRawValue()}) + } + } + else if (this.props.mask !== nextProps.mask) { this.mask.setPattern(nextProps.mask, {value: this.mask.getRawValue()}) } - if (this.props.value !== nextProps.value) { + else if (this.props.value !== nextProps.value) { this.mask.setValue(nextProps.value) } }, diff --git a/tests/index-test.js b/tests/index-test.js index 3ffa9fc..1179fe6 100644 --- a/tests/index-test.js +++ b/tests/index-test.js @@ -49,26 +49,25 @@ describe('MaskedInput', () => { cleanup(el) }) - it('should handle updating mask masking', () => { + it('should handle updating mask', () => { const el = setup() let ref = null let defaultMask = '1111 1111 1111 1111' let amexMask = '1111 111111 11111' - let mask = defaultMask - function render() { + function render(props) { ReactDOM.render( { if (r) ref = r }} - mask={mask} + {...props} />, el ) } - render() + render({mask: defaultMask}) let input = ReactDOM.findDOMNode(ref) // initial state @@ -77,8 +76,7 @@ describe('MaskedInput', () => { expect(input.size).toBe(19) expect(input.selectionStart).toBe(0) - mask = amexMask - render() + render({mask: amexMask}) input = ReactDOM.findDOMNode(ref) // initial state @@ -90,6 +88,81 @@ describe('MaskedInput', () => { cleanup(el) }) + it('should handle updating value', () => { + const el = setup() + let ref = null + let defaultMask = '1111 1111 1111 1111' + + function render(props) { + ReactDOM.render( + ref = r} + {...props} + />, + el + ) + } + + render({mask: defaultMask, value: ''}) + let input = ReactDOM.findDOMNode(ref) + + // initial state + expect(input.value).toBe('') + expect(input.placeholder).toBe('____ ____ ____ ____') + expect(input.size).toBe(19) + expect(input.selectionStart).toBe(0) + + // update value + render({mask: defaultMask, value: '4111111111111111'}) + input = ReactDOM.findDOMNode(ref) + + // initial state + expect(input.value).toBe('4111 1111 1111 1111') + expect(input.size).toBe(19) + expect(input.selectionStart).toBe(19) + + cleanup(el) + }) + + it('should handle updating mask and value', () => { + const el = setup() + let ref = null + let defaultMask = '1111 1111 1111 1111' + let amexMask = '1111 111111 11111' + let value = '' + let mask = defaultMask + + function render(props) { + ReactDOM.render( + ref = r} + {...props} + />, + el + ) + } + + render({mask, value}) + let input = ReactDOM.findDOMNode(ref) + + // initial state + expect(input.value).toBe('') + expect(input.placeholder).toBe('____ ____ ____ ____') + expect(input.size).toBe(19) + expect(input.selectionStart).toBe(0) + + // update mask and value + render({mask: amexMask, value: '378282246310005'}) + input = ReactDOM.findDOMNode(ref) + + // initial state + expect(input.value).toBe('3782 822463 10005') + expect(input.size).toBe(17) + expect(input.selectionStart).toBe(17) + + cleanup(el) + }) + it('should remove leftover placeholder characters when switching to smaller mask', () => { const el = setup() let ref = null @@ -124,7 +197,6 @@ describe('MaskedInput', () => { value = '1234 123456 12345' render() input = ReactDOM.findDOMNode(ref) - console.log(input) // initial state expect(input.value).toBe('1234 123456 12345') @@ -132,5 +204,51 @@ describe('MaskedInput', () => { cleanup(el) }) -}) + it('should handle updating multiple values', () => { + const el = setup() + let ref = null + let defaultMask = '1111 1111 1111 1111' + const mastercard = '5555555555554444' + const visa = '4111111111111111' + + function render(props) { + ReactDOM.render( + ref = r} + {...props} + />, + el + ) + } + + render({mask: defaultMask, value: ''}) + let input = ReactDOM.findDOMNode(ref) + + // initial state + expect(input.value).toBe('') + expect(input.placeholder).toBe('____ ____ ____ ____') + expect(input.size).toBe(19) + expect(input.selectionStart).toBe(0) + + // update mask and value + render({mask: defaultMask, value: visa}) + input = ReactDOM.findDOMNode(ref) + + // initial state + expect(input.value).toBe('4111 1111 1111 1111') + expect(input.size).toBe(19) + expect(input.selectionStart).toBe(19) + + // update mask and value + render({mask: defaultMask, value: mastercard}) + input = ReactDOM.findDOMNode(ref) + + // initial state + expect(input.value).toBe('5555 5555 5555 4444') + expect(input.size).toBe(19) + expect(input.selectionStart).toBe(19) + + cleanup(el) + }) +}) From f69008751cca24734a105fc87e309a6844f821e7 Mon Sep 17 00:00:00 2001 From: Dustan Kasten Date: Tue, 9 Aug 2016 11:09:27 -0400 Subject: [PATCH 27/44] 3.2.4 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index a916da3..9a3b93c 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "react-maskedinput", "description": "Masked React component", - "version": "3.2.3", + "version": "3.2.4", "main": "./lib/index.js", "jsnext:main": "es6/index.js", "standalone": "MaskedInput", From eda4e4c7474d250c52b356063c1b569c355b122c Mon Sep 17 00:00:00 2001 From: 9ja Boy <9jaboy@users.noreply.github.com> Date: Mon, 29 Aug 2016 09:29:54 -0500 Subject: [PATCH 28/44] Use onBeforeInput so Chrome for Android works. Fix #19 (#47) --- src/index.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/index.js b/src/index.js index d91f6e2..23b2b72 100644 --- a/src/index.js +++ b/src/index.js @@ -162,7 +162,7 @@ var MaskedInput = React.createClass({ e.preventDefault() this._updateMaskSelection() - if (this.mask.input(e.key)) { + if (this.mask.input((e.key || e.data))) { e.target.value = this.mask.getValue() this._updateInputSelection() if (this.props.onChange) { @@ -208,7 +208,7 @@ var MaskedInput = React.createClass({ maxLength={patternLength} onChange={this._onChange} onKeyDown={this._onKeyDown} - onKeyPress={this._onKeyPress} + onBeforeInput={this._onKeyPress} onPaste={this._onPaste} placeholder={placeholder || this.mask.emptyValue} size={size || patternLength} From 50d0da3e56328944543218fbfecf6e8090459a55 Mon Sep 17 00:00:00 2001 From: Dustan Kasten Date: Mon, 29 Aug 2016 10:32:53 -0400 Subject: [PATCH 29/44] v3.3.0-beta.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 9a3b93c..28182bc 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "react-maskedinput", "description": "Masked React component", - "version": "3.2.4", + "version": "3.3.0-beta.1", "main": "./lib/index.js", "jsnext:main": "es6/index.js", "standalone": "MaskedInput", From ae57dc280694fe49601f05d8c0978d20a5d4aaef Mon Sep 17 00:00:00 2001 From: npmcdn-to-unpkg-bot Date: Wed, 31 Aug 2016 13:31:44 +0100 Subject: [PATCH 30/44] Replace npmcdn.com with unpkg.com (#68) --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index a11b6dc..cbfb565 100644 --- a/README.md +++ b/README.md @@ -20,8 +20,8 @@ npm install react-maskedinput --save The browser bundle exposes a global `MaskedInput` variable and expects to find a global `React` (>= 0.14.0) variable to work with. -* [react-maskedinput.js](https://npmcdn.com/react-maskedinput/umd/react-maskedinput.js) (development version) -* [react-maskedinput.min.js](https://npmcdn.com/react-maskedinput/umd/react-maskedinput.min.js) (compressed production version) +* [react-maskedinput.js](https://unpkg.com/react-maskedinput/umd/react-maskedinput.js) (development version) +* [react-maskedinput.min.js](https://unpkg.com/react-maskedinput/umd/react-maskedinput.min.js) (compressed production version) ## Usage From 3898d50662c8f9aabeb0720636ed4e3f2079e5bf Mon Sep 17 00:00:00 2001 From: Dustan Kasten Date: Mon, 10 Oct 2016 11:21:33 -0400 Subject: [PATCH 31/44] v3.3.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 28182bc..efbfb4f 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "react-maskedinput", "description": "Masked React component", - "version": "3.3.0-beta.1", + "version": "3.3.0", "main": "./lib/index.js", "jsnext:main": "es6/index.js", "standalone": "MaskedInput", From ebb9d756ad510b8008cebfbb8b086101f46f812f Mon Sep 17 00:00:00 2001 From: Alexey Bondarenko Date: Wed, 2 Nov 2016 17:03:54 +0200 Subject: [PATCH 32/44] removed react internals --- package.json | 1 + src/index.js | 47 +++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 46 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index efbfb4f..1a2f008 100644 --- a/package.json +++ b/package.json @@ -35,6 +35,7 @@ "react": "0.14.x || 15.x.x" }, "devDependencies": { + "babel-eslint": "^7.1.0", "eslint-config-jonnybuchanan": "2.0.3", "nwb": "0.9.x", "react": "15.x.x", diff --git a/src/index.js b/src/index.js index 23b2b72..48ca442 100644 --- a/src/index.js +++ b/src/index.js @@ -1,6 +1,4 @@ var React = require('react') -var {getSelection, setSelection} = require('react/lib/ReactInputSelection') - var InputMask = require('inputmask-core') var KEYCODE_Z = 90 @@ -14,6 +12,51 @@ function isRedo(e) { return (e.ctrlKey || e.metaKey) && e.keyCode === (e.shiftKey ? KEYCODE_Z : KEYCODE_Y) } +function getSelection (el) { + var start, end, rangeEl, clone; + + if( el.selectionStart !== undefined){ + start = el.selectionStart + end = el.selectionEnd + } + else { + try { + el.focus() + rangeEl = el.createTextRange() + clone = rangeEl.duplicate() + + rangeEl.moveToBookmark(document.selection.createRange().getBookmark()); + clone.setEndPoint('EndToStart', rangeEl); + + start = clone.text.length; + end = start + rangeEl.text.length + } + catch(e) { /* not focused or not visible */ } + } + + return { start, end } +} + +function setSelection(el, selection){ + var rangeEl; + + try { + if( el.selectionStart !== undefined){ + el.focus() + el.setSelectionRange(selection.start, selection.end) + } + else { + el.focus(); + rangeEl = el.createTextRange(); + rangeEl.collapse(true); + rangeEl.moveStart('character', selection.start); + rangeEl.moveEnd('character', selection.end - selection.start); + rangeEl.select(); + } + } + catch(e) { /* not focused or not visible */ } +} + var MaskedInput = React.createClass({ propTypes: { mask: React.PropTypes.string.isRequired, From 8b5629a8970a8a7d240c8c15530643a1a11e1e30 Mon Sep 17 00:00:00 2001 From: Alexey Bondarenko Date: Wed, 2 Nov 2016 17:54:42 +0200 Subject: [PATCH 33/44] lint fix --- package.json | 1 - src/index.js | 30 +++++++++++++++--------------- 2 files changed, 15 insertions(+), 16 deletions(-) diff --git a/package.json b/package.json index 1a2f008..efbfb4f 100644 --- a/package.json +++ b/package.json @@ -35,7 +35,6 @@ "react": "0.14.x || 15.x.x" }, "devDependencies": { - "babel-eslint": "^7.1.0", "eslint-config-jonnybuchanan": "2.0.3", "nwb": "0.9.x", "react": "15.x.x", diff --git a/src/index.js b/src/index.js index 48ca442..5dc3e47 100644 --- a/src/index.js +++ b/src/index.js @@ -13,9 +13,9 @@ function isRedo(e) { } function getSelection (el) { - var start, end, rangeEl, clone; + var start, end, rangeEl, clone - if( el.selectionStart !== undefined){ + if (el.selectionStart !== undefined) { start = el.selectionStart end = el.selectionEnd } @@ -25,11 +25,11 @@ function getSelection (el) { rangeEl = el.createTextRange() clone = rangeEl.duplicate() - rangeEl.moveToBookmark(document.selection.createRange().getBookmark()); - clone.setEndPoint('EndToStart', rangeEl); + rangeEl.moveToBookmark(document.selection.createRange().getBookmark()) + clone.setEndPoint('EndToStart', rangeEl) - start = clone.text.length; - end = start + rangeEl.text.length + start = clone.text.length + end = start + rangeEl.text.length } catch(e) { /* not focused or not visible */ } } @@ -37,21 +37,21 @@ function getSelection (el) { return { start, end } } -function setSelection(el, selection){ - var rangeEl; +function setSelection(el, selection) { + var rangeEl try { - if( el.selectionStart !== undefined){ + if(el.selectionStart !== undefined) { el.focus() el.setSelectionRange(selection.start, selection.end) } else { - el.focus(); - rangeEl = el.createTextRange(); - rangeEl.collapse(true); - rangeEl.moveStart('character', selection.start); - rangeEl.moveEnd('character', selection.end - selection.start); - rangeEl.select(); + el.focus() + rangeEl = el.createTextRange() + rangeEl.collapse(true) + rangeEl.moveStart('character', selection.start) + rangeEl.moveEnd('character', selection.end - selection.start) + rangeEl.select() } } catch(e) { /* not focused or not visible */ } From 8da370c5c8fc21aedba047af9ec944dd18590985 Mon Sep 17 00:00:00 2001 From: Alexey Bondarenko Date: Wed, 2 Nov 2016 18:11:48 +0200 Subject: [PATCH 34/44] fixed by eslint --- src/index.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/index.js b/src/index.js index 5dc3e47..a902abd 100644 --- a/src/index.js +++ b/src/index.js @@ -31,7 +31,7 @@ function getSelection (el) { start = clone.text.length end = start + rangeEl.text.length } - catch(e) { /* not focused or not visible */ } + catch (e) { /* not focused or not visible */ } } return { start, end } @@ -41,7 +41,7 @@ function setSelection(el, selection) { var rangeEl try { - if(el.selectionStart !== undefined) { + if (el.selectionStart !== undefined) { el.focus() el.setSelectionRange(selection.start, selection.end) } @@ -54,7 +54,7 @@ function setSelection(el, selection) { rangeEl.select() } } - catch(e) { /* not focused or not visible */ } + catch (e) { /* not focused or not visible */ } } var MaskedInput = React.createClass({ From 821048e342dc40b3b1a17e8fa9f2fdb7e1794f39 Mon Sep 17 00:00:00 2001 From: Dustan Kasten Date: Tue, 22 Nov 2016 12:11:09 -0500 Subject: [PATCH 35/44] Make smokescreen test resilient to 15.4 error message change --- tests/index-test.js | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/tests/index-test.js b/tests/index-test.js index 1179fe6..f733cb8 100644 --- a/tests/index-test.js +++ b/tests/index-test.js @@ -20,10 +20,13 @@ describe('MaskedInput', () => { expect.spyOn(console, 'error') expect().toExist() expect(console.error.calls[0].arguments[0]).toMatch( - new RegExp( - 'Warning: Failed prop type: Required prop ' + - '`mask` was not specified in `MaskedInput`.' - ) + new RegExp('Warning: Failed prop type:') + ) + expect(console.error.calls[0].arguments[0]).toMatch( + new RegExp('`mask`') + ) + expect(console.error.calls[0].arguments[0]).toMatch( + new RegExp('required', 'i') ) }) From ad934c355684486bf05c70605edeb809eb356dcf Mon Sep 17 00:00:00 2001 From: Dustan Kasten Date: Tue, 22 Nov 2016 12:11:30 -0500 Subject: [PATCH 36/44] 3.3.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index efbfb4f..3022f4e 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "react-maskedinput", "description": "Masked React component", - "version": "3.3.0", + "version": "3.3.1", "main": "./lib/index.js", "jsnext:main": "es6/index.js", "standalone": "MaskedInput", From fa0b07e519885a4049b4da1ba760a2d0aa7675cc Mon Sep 17 00:00:00 2001 From: Joe Love Date: Thu, 1 Dec 2016 16:21:00 +0000 Subject: [PATCH 37/44] Can't enter more than one character in Edge browser (#79) * add user agent sniffing for keypress event name (eww) * remove semi-colons to match coding style * fix bug with android chrome, bah * small tweak to (hopefully) fix android chrome) gs * just make it exclude android * rename method --- src/index.js | 36 +++++++++++++++++++++++------------- 1 file changed, 23 insertions(+), 13 deletions(-) diff --git a/src/index.js b/src/index.js index a902abd..de95ca6 100644 --- a/src/index.js +++ b/src/index.js @@ -235,6 +235,21 @@ var MaskedInput = React.createClass({ return value === this.mask.emptyValue ? '' : value }, + _keyPressPropName() { + return navigator.userAgent.match(/Android/i) + ? 'onBeforeInput' + : 'onKeyPress' + }, + + _getEventHandlers() { + return { + onChange: this._onChange, + onKeyDown: this._onKeyDown, + onPaste: this._onPaste, + [this._keyPressPropName()]: this._onKeyPress + } + }, + focus() { this.input.focus() }, @@ -244,19 +259,14 @@ var MaskedInput = React.createClass({ }, render() { - var {mask, formatCharacters, size, placeholder, placeholderChar, ...props} = this.props - var patternLength = this.mask.pattern.length - return this.input = r } - maxLength={patternLength} - onChange={this._onChange} - onKeyDown={this._onKeyDown} - onBeforeInput={this._onKeyPress} - onPaste={this._onPaste} - placeholder={placeholder || this.mask.emptyValue} - size={size || patternLength} - value={this._getDisplayValue()} - /> + var ref = r => this.input = r + var maxLength = this.mask.pattern.length + var value = this._getDisplayValue() + var eventHandlers = this._getEventHandlers() + var { size = maxLength, placeholder = this.mask.emptyValue } = this.props + var props = { ...this.props, ...eventHandlers, ref, maxLength, value, size, placeholder } + + return } }) From d6155cdcf85b0c0694d16d4b68e22be2209894b3 Mon Sep 17 00:00:00 2001 From: Dustan Kasten Date: Thu, 1 Dec 2016 11:24:11 -0500 Subject: [PATCH 38/44] 3.3.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 3022f4e..8765d48 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "react-maskedinput", "description": "Masked React component", - "version": "3.3.1", + "version": "3.3.2", "main": "./lib/index.js", "jsnext:main": "es6/index.js", "standalone": "MaskedInput", From 55c1b76dc7f647b85b5324424d1134bab5085994 Mon Sep 17 00:00:00 2001 From: Dustan Kasten Date: Thu, 1 Dec 2016 11:25:06 -0500 Subject: [PATCH 39/44] v3.3.2 changelog --- CHANGES.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGES.md b/CHANGES.md index fa2ef21..80340fc 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,3 +1,7 @@ +## 3.3.2 / 2016-12-01 + +* Fix for both Android and MS Edge input entering + ## 3.2.0 / 2016-05-24 * Allow dynamic pattern updating [[martyphee][martyphee]] From e37eba91bfbb554289d8f218eef70d22f24548d8 Mon Sep 17 00:00:00 2001 From: Dustan Kasten Date: Thu, 1 Dec 2016 16:02:35 -0500 Subject: [PATCH 40/44] 3.3.3 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 8765d48..17d935b 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "react-maskedinput", "description": "Masked React component", - "version": "3.3.2", + "version": "3.3.3", "main": "./lib/index.js", "jsnext:main": "es6/index.js", "standalone": "MaskedInput", From e31d3237f9f2f9b49d4c58afa02564e7d4bdf8fc Mon Sep 17 00:00:00 2001 From: Avindra Goolcharan Date: Mon, 12 Dec 2016 15:44:26 -0500 Subject: [PATCH 41/44] Changelog: fix typo (#81) just removes a stray char that was breaking the formatting --- CHANGES.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGES.md b/CHANGES.md index 80340fc..a327b7e 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -10,7 +10,7 @@ * Don’t call `onChange` function if undefined. * Update nwb to 0.9.x -s + ## 3.1.2 / 2016-04-11 * Support for React 15.x.x From ffae092b9aa0622813b7753c5c092738f2e7fbf5 Mon Sep 17 00:00:00 2001 From: Nathan Stitt Date: Mon, 12 Dec 2016 14:44:51 -0600 Subject: [PATCH 42/44] Silence React 15.4 invalid property warnings (#80) * Restore console.error after testing it * remove planceHolderChar and formatCharacters props Before passing them to input in order to silence invalid prop warnings introduced in React 15.4 --- src/index.js | 5 +++-- tests/index-test.js | 22 ++++++++++++++++++++++ 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/src/index.js b/src/index.js index de95ca6..4f26b34 100644 --- a/src/index.js +++ b/src/index.js @@ -264,9 +264,10 @@ var MaskedInput = React.createClass({ var value = this._getDisplayValue() var eventHandlers = this._getEventHandlers() var { size = maxLength, placeholder = this.mask.emptyValue } = this.props - var props = { ...this.props, ...eventHandlers, ref, maxLength, value, size, placeholder } - return + var {placeholderChar, formatCharacters, ...cleanedProps} = this.props + var inputProps = { ...cleanedProps, ...eventHandlers, ref, maxLength, value, size, placeholder } + return } }) diff --git a/tests/index-test.js b/tests/index-test.js index f733cb8..fa12f70 100644 --- a/tests/index-test.js +++ b/tests/index-test.js @@ -28,6 +28,7 @@ describe('MaskedInput', () => { expect(console.error.calls[0].arguments[0]).toMatch( new RegExp('required', 'i') ) + console.error.restore() }) it('should handle a masking workflow', () => { @@ -208,6 +209,27 @@ describe('MaskedInput', () => { cleanup(el) }) + it('cleans props from input', () => { + const el = setup() + let ref = null + let defaultMask = '1111 1111 1111 1111' + function render(props) { + ReactDOM.render( + ref = r} {...props} />, + el + ) + } + expect.spyOn(console, 'error') + render({mask: defaultMask, value: '', + placeholderChar: 'X', formatCharacters: {A: null}}) + expect(console.error).toNotHaveBeenCalled() + console.error.restore() + let input = ReactDOM.findDOMNode(ref) + expect(input.getAttribute('placeholderChar')).toNotExist() + expect(input.getAttribute('formatCharacters')).toNotExist() + cleanup(el) + }) + it('should handle updating multiple values', () => { const el = setup() let ref = null From 16990c1abf1c63427e1131df95c6e7575bd20f3e Mon Sep 17 00:00:00 2001 From: Aesop Wolf Date: Wed, 14 Dec 2016 18:48:50 -0800 Subject: [PATCH 43/44] add check for navigator (#83) * add check for navigator This enables server side rendering * fix eslint errors * changes per feedback `typeof navigator !== 'undefined'` otherwise strict mode will still throw `return 'onKeyPress'` as a fallback in case someone is removing navigator from the global scope --- src/index.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/index.js b/src/index.js index 4f26b34..7389581 100644 --- a/src/index.js +++ b/src/index.js @@ -236,9 +236,12 @@ var MaskedInput = React.createClass({ }, _keyPressPropName() { - return navigator.userAgent.match(/Android/i) + if (typeof navigator !== 'undefined') { + return navigator.userAgent.match(/Android/i) ? 'onBeforeInput' : 'onKeyPress' + } + return 'onKeyPress' }, _getEventHandlers() { From 8f3701dc90393f3ed6aa4700ee193241900992c3 Mon Sep 17 00:00:00 2001 From: Dustan Kasten Date: Wed, 14 Dec 2016 21:50:12 -0500 Subject: [PATCH 44/44] 3.3.4 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 17d935b..10ec80a 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "react-maskedinput", "description": "Masked React component", - "version": "3.3.3", + "version": "3.3.4", "main": "./lib/index.js", "jsnext:main": "es6/index.js", "standalone": "MaskedInput",