├── .gitignore ├── .npmignore ├── LICENSE ├── README.md ├── package.json └── src └── index.js /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | lib/ 3 | .DS_Store 4 | npm-debug.log 5 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | src/ 2 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2015 Chiel Robben 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | React Autofill 2 | ============== 3 | A component that polyfills a change event in Safari when input fields are 4 | autofilled. 5 | 6 | ## Installation 7 | ``` 8 | npm install --save react-autofill 9 | ``` 10 | 11 | ## Usage 12 | ES2015 (aka. ES6): 13 | ```js 14 | import React from 'react'; 15 | import ReactDOM from 'react-dom'; 16 | import autofill from 'react-autofill'; 17 | 18 | class Form extends React.Component { 19 | 20 | constructor() { 21 | super(); 22 | this.state = {}; 23 | } 24 | 25 | handleChange(e) { 26 | 27 | const { name, value } = e.currentTarget; 28 | const nextState = {}; 29 | 30 | nextState[name] = value; 31 | 32 | this.setState(nextState); 33 | 34 | } 35 | 36 | render() { 37 | 38 | return ( 39 |
40 | 44 |
45 | ); 46 | 47 | } 48 | 49 | } 50 | 51 | ReactDOM.render(React.createElement(autofill(Form)), document.body); 52 | 53 | ``` 54 | ES7 (aka. ES2016): 55 | ```js 56 | @autofill 57 | class Form extends React.Component { 58 | ... 59 | } 60 | ``` 61 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-autofill", 3 | "version": "1.1.4", 4 | "description": "A polyfill for Safari that triggers a change event on autofill", 5 | "main": "./lib/index.js", 6 | "scripts": { 7 | "build": "babel src --out-dir lib", 8 | "prepublish": "npm run build", 9 | "test": "echo \"Error: no test specified\" && exit 1" 10 | }, 11 | "repository": { 12 | "type": "git", 13 | "url": "https://github.com/Pephers/react-autofill.git" 14 | }, 15 | "keywords": [ 16 | "autofill", 17 | "autocomplete" 18 | ], 19 | "author": "Chiel Robben ", 20 | "license": "MIT", 21 | "peerDependencies": { 22 | "react": "^0.14.0 || ^15.0.0", 23 | "react-dom": "^0.14.0 || ^15.0.0" 24 | }, 25 | "devDependencies": { 26 | "babel": "^5.8.29" 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | 4 | export default function autofill(DecoratedComponent) { 5 | 6 | return class AutofillWrapper extends React.Component { 7 | 8 | constructor(props, context) { 9 | 10 | super(props, context); 11 | 12 | this._listeners = []; 13 | 14 | } 15 | 16 | componentDidMount() { 17 | 18 | const forms = ReactDOM.findDOMNode(this).querySelectorAll('form'); 19 | 20 | [].forEach.call(forms, (form) => { 21 | [].forEach.call(form.elements, (element) => { 22 | 23 | if (element.name === '') { 24 | return; 25 | } 26 | 27 | this._listeners.push(setInterval(function () { 28 | 29 | if (!this.element || this._previousValue === this.element.value) { 30 | return; 31 | } 32 | 33 | this._previousValue = this.element.value; 34 | 35 | const evt = document.createEvent('HTMLEvents'); 36 | evt.initEvent('input', true, true); 37 | this.element.dispatchEvent(evt); 38 | 39 | }.bind({ element }), 20)); 40 | 41 | }); 42 | }); 43 | 44 | } 45 | 46 | componentWillUnmount() { 47 | 48 | this._listeners.forEach(function (listener) { 49 | clearInterval(listener); 50 | }); 51 | 52 | } 53 | 54 | render() { 55 | return ; 56 | } 57 | 58 | } 59 | 60 | } 61 | --------------------------------------------------------------------------------