├── .eslintignore
├── .editorconfig
├── src
├── detect-autofill.scss
└── detect-autofill.js
├── .npmignore
├── .releaserc
├── .eslintrc.js
├── .travis.yml
├── .github
└── ISSUE_TEMPLATE
│ ├── feature_request.md
│ └── bug_report.md
├── webpack.config.js
├── LICENSE
├── demos
└── index.html
├── CHANGELOG.md
├── package.json
├── README.md
└── CODE_OF_CONDUCT.md
/.eslintignore:
--------------------------------------------------------------------------------
1 | dist/
2 | node_modules/
3 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*]
4 | charset = utf-8
5 | end_of_line = lf
6 | indent_size = 2
7 | indent_style = space
8 | insert_final_newline = true
9 | trim_trailing_whitespace = true
10 |
11 | [*.md]
12 | insert_final_newline = false
13 | trim_trailing_whitespace = false
--------------------------------------------------------------------------------
/src/detect-autofill.scss:
--------------------------------------------------------------------------------
1 | INPUT, SELECT, TEXTAREA {
2 | &:-webkit-autofill {
3 | animation-name: onautofillstart;
4 | }
5 |
6 | &:not(:-webkit-autofill) {
7 | animation-name: onautofillcancel;
8 | }
9 | }
10 |
11 | @keyframes onautofillstart { from {} }
12 | @keyframes onautofillcancel { from {} }
13 |
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | # Directories
2 | .github/
3 | .npm/
4 | demos/
5 | node_modules/
6 | src/
7 |
8 | # Files
9 | .DS_STORE
10 | .eslintcache
11 | npm-debug.log*
12 | *.config.js
13 | .editorconfig
14 | .eslintignore
15 | .eslintrc.js
16 | .gitattributes
17 | .gitignore
18 | .releaserc
19 | .travis.yml
20 | CHANGELOG.md
21 | CODE_OF_CONDUCT.md
22 | README.md
23 | webpack.config.js
24 |
--------------------------------------------------------------------------------
/.releaserc:
--------------------------------------------------------------------------------
1 | {
2 | "branch": "master",
3 | "plugins": [
4 | "@semantic-release/commit-analyzer",
5 | "@semantic-release/release-notes-generator",
6 | "@semantic-release/npm",
7 | "@semantic-release/github",
8 | "@semantic-release/changelog",
9 | "@semantic-release/git"
10 | ],
11 | "repositoryUrl": "https://github.com/matteobad/detect-autofill.git"
12 | }
13 |
--------------------------------------------------------------------------------
/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | "env": {
3 | "browser": true,
4 | "es6": true
5 | },
6 | "extends": [
7 | "google"
8 | ],
9 | "globals": {
10 | "Atomics": "readonly",
11 | "SharedArrayBuffer": "readonly"
12 | },
13 | "parserOptions": {
14 | "ecmaVersion": 2018,
15 | "sourceType": "module"
16 | },
17 | "rules": {
18 | "no-var": "off"
19 | }
20 | };
21 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: node_js
2 |
3 | node_js:
4 | - 10
5 |
6 | jobs:
7 | include:
8 | # Define the release stage that runs semantic-release
9 | - stage: release
10 | node_js: lts/*
11 | # Advanced: optionally overwrite your default `script` step to skip the tests
12 | script:
13 | - npm run build
14 | deploy:
15 | provider: script
16 | skip_cleanup: true
17 | script:
18 | - npx semantic-release
19 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature_request.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Feature request
3 | about: Suggest an idea for this project
4 | title: ''
5 | labels: ''
6 | assignees: ''
7 | ---
8 |
9 | **Is your feature request related to a problem? Please describe.**
10 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
11 |
12 | **Describe the solution you'd like**
13 | A clear and concise description of what you want to happen.
14 |
15 | **Describe alternatives you've considered**
16 | A clear and concise description of any alternative solutions or features you've considered.
17 |
18 | **Additional context**
19 | Add any other context or screenshots about the feature request here.
20 |
--------------------------------------------------------------------------------
/webpack.config.js:
--------------------------------------------------------------------------------
1 | const path = require('path');
2 |
3 | const config = {
4 | entry: path.resolve(__dirname, 'src', 'detect-autofill.js'),
5 | output: {
6 | filename: 'detect-autofill.js',
7 | path: path.resolve(__dirname, 'dist'),
8 | },
9 | module: {
10 | rules: [{
11 | test: /\.scss$/,
12 | use: [
13 | 'style-loader', // creates style nodes from JS strings
14 | 'css-loader', // translates CSS into CommonJS
15 | 'sass-loader', // compiles Sass to CSS, using Node Sass by default
16 | ],
17 | }],
18 | },
19 | plugins: [],
20 | };
21 |
22 | module.exports = (env, argv) => {
23 | if (argv.mode === 'development') {
24 | config.devtool = 'source-map';
25 | }
26 |
27 | config.mode = argv.mode;
28 |
29 | return config;
30 | };
31 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/bug_report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Bug report
3 | about: Create a report to help us improve
4 | title: ''
5 | labels: ''
6 | assignees: ''
7 |
8 | ---
9 |
10 | **Describe the bug**
11 | A clear and concise description of what the bug is.
12 |
13 | **To Reproduce**
14 | Steps to reproduce the behavior:
15 |
16 | 1. Go to '...'
17 | 2. Click on '....'
18 | 3. Scroll down to '....'
19 | 4. See error
20 |
21 | **Expected behavior**
22 | A clear and concise description of what you expected to happen.
23 |
24 | **Screenshots**
25 | If applicable, add screenshots to help explain your problem.
26 |
27 | **Desktop (please complete the following information):**
28 |
29 | * OS: [e.g. iOS]
30 | * Browser [e.g. chrome, safari]
31 | * Version [e.g. 22]
32 |
33 | **Smartphone (please complete the following information):**
34 |
35 | * Device: [e.g. iPhone6]
36 | * OS: [e.g. iOS8.1]
37 | * Browser [e.g. stock browser, safari]
38 | * Version [e.g. 22]
39 |
40 | **Additional context**
41 |
42 | Add any other context about the problem here.
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2019 Matteo Badini
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/demos/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Autofill Detect - Fake Login
8 |
9 |
10 |
11 |
12 |
13 |
14 |
25 |
26 |
27 |
28 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | ## [1.1.4](https://github.com/matteobad/detect-autofill/compare/v1.1.3...v1.1.4) (2021-04-07)
2 |
3 |
4 | ### Bug Fixes
5 |
6 | * doc ([d2c5b12](https://github.com/matteobad/detect-autofill/commit/d2c5b124b30431160bdcc3ce4293f0ccfd18a1ff))
7 |
8 | ## [1.1.3](https://github.com/matteobad/detect-autofill/compare/v1.1.2...v1.1.3) (2020-04-11)
9 |
10 |
11 | ### Bug Fixes
12 |
13 | * IE11 prevent default ([e7b1712](https://github.com/matteobad/detect-autofill/commit/e7b171266b87087157a4f292f6981410871a1f60))
14 |
15 | ## [1.1.2](https://github.com/matteobad/detect-autofill/compare/v1.1.1...v1.1.2) (2020-02-02)
16 |
17 |
18 | ### Bug Fixes
19 |
20 | * update npmignore ([82b2019](https://github.com/matteobad/detect-autofill/commit/82b2019be6e73573ffd0454e4a4aea14ee7560c7))
21 |
22 | ## [1.1.1](https://github.com/matteobad/detect-autofill/compare/v1.1.0...v1.1.1) (2019-11-02)
23 |
24 |
25 | ### Bug Fixes
26 |
27 | * eslint errors ([6acbee5](https://github.com/matteobad/detect-autofill/commit/6acbee5dc5d2d545c88b80ece96aaa61dc77d785))
28 |
29 | # [1.1.0](https://github.com/matteobad/detect-autofill/compare/v1.0.0...v1.1.0) (2019-07-20)
30 |
31 |
32 | ### Bug Fixes
33 |
34 | * greenkeeper conflict ([864e363](https://github.com/matteobad/detect-autofill/commit/864e363))
35 |
36 |
37 | ### Features
38 |
39 | * reduce bundle size with closure compiler ([b530610](https://github.com/matteobad/detect-autofill/commit/b530610))
40 |
41 | # 1.0.0 (2019-07-19)
42 |
43 |
44 | ### Bug Fixes
45 |
46 | * add iOS support ([7ae79d4](https://github.com/matteobad/detect-autofill/commit/7ae79d4))
47 |
48 |
49 | ### Features
50 |
51 | * first commit ([de628b5](https://github.com/matteobad/detect-autofill/commit/de628b5))
52 | * setup npm and github keys on travis ([93d3e38](https://github.com/matteobad/detect-autofill/commit/93d3e38))
53 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "detect-autofill",
3 | "version": "1.1.4",
4 | "description": "Small javascript library to detect and even prevent browsers autofill of form elements. Usefull for implementing floating labels or applying custom logics/styles.",
5 | "main": "dist/detect-autofill.js",
6 | "scripts": {
7 | "commit": "git-cz",
8 | "clean": "rimraf dist",
9 | "lint": "eslint src/**/*.js",
10 | "lint:fix": "eslint src/**/*.js --fix",
11 | "build": "webpack --mode=production",
12 | "watch": "webpack --mode=development -w",
13 | "test": "npm run lint",
14 | "prepublishOnly": "npm run clean && npm run lint && npm run build && npm run test",
15 | "semantic-release": "semantic-release",
16 | "travis-deploy-once": "travis-deploy-once"
17 | },
18 | "repository": {
19 | "type": "git",
20 | "url": "https://github.com/matteobad/detect-autofill.git"
21 | },
22 | "keywords": [
23 | "autocomplete",
24 | "autofill",
25 | "-webkit-autofill",
26 | "floating-label",
27 | "vanilla"
28 | ],
29 | "author": "Matteo Badini ",
30 | "license": "MIT",
31 | "bugs": {
32 | "url": "https://github.com/matteobad/detect-autofill/issues"
33 | },
34 | "homepage": "https://github.com/matteobad/detect-autofill#readme",
35 | "dependencies": {
36 | "custom-event-polyfill": "^1.0.7"
37 | },
38 | "devDependencies": {
39 | "@semantic-release/changelog": "^5.0.1",
40 | "@semantic-release/commit-analyzer": "^8.0.1",
41 | "@semantic-release/git": "^9.0.0",
42 | "@semantic-release/github": "^7.2.1",
43 | "@semantic-release/npm": "^7.1.0",
44 | "@semantic-release/release-notes-generator": "^9.0.2",
45 | "commitizen": "^4.2.3",
46 | "css-loader": "^5.2.0",
47 | "cz-conventional-changelog": "^3.3.0",
48 | "eslint": "^7.23.0",
49 | "eslint-config-google": "^0.14.0",
50 | "husky": "^4.2.5",
51 | "sass": "^1.32.8",
52 | "sass-loader": "^11.0.1",
53 | "semantic-release": "^17.4.2",
54 | "style-loader": "^2.0.0",
55 | "webpack": "^5.30.0",
56 | "webpack-cli": "^4.6.0"
57 | },
58 | "config": {
59 | "commitizen": {
60 | "path": "cz-conventional-changelog"
61 | }
62 | },
63 | "husky": {
64 | "hooks": {
65 | "pre-commit": "npm run lint && npm run test"
66 | }
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/src/detect-autofill.js:
--------------------------------------------------------------------------------
1 | import './detect-autofill.scss';
2 | import 'custom-event-polyfill';
3 |
4 | document.addEventListener('animationstart', onAnimationStart, true);
5 | document.addEventListener('input', onInput, true);
6 |
7 | /**
8 | * Handler for -webkit based browser that listen for a custom
9 | * animation create using the :pseudo-selector in the stylesheet.
10 | * Works with Chrome, Safari
11 | *
12 | * @param {AnimationEvent} event
13 | */
14 | function onAnimationStart(event) {
15 | ('onautofillstart' === event.animationName) ?
16 | autocomplete(event.target) :
17 | cancelAutocomplete(event.target);
18 | }
19 |
20 | /**
21 | * Handler for non-webkit based browser that listen for input
22 | * event to trigger the autocomplete-cancel process.
23 | * Works with Firefox, Edge, IE11
24 | *
25 | * @param {InputEvent} event
26 | */
27 | function onInput(event) {
28 | ('insertReplacementText' === event.inputType || !('data' in event)) ?
29 | autocomplete(event.target) :
30 | cancelAutocomplete(event.target);
31 | }
32 |
33 | /**
34 | * Manage an input element when its value is autocompleted
35 | * by the browser in the following steps:
36 | * - add [autocompleted] attribute from event.target
37 | * - create 'onautocomplete' cancelable CustomEvent
38 | * - dispatch the Event
39 | *
40 | * @param {HtmlInputElement} element
41 | */
42 | function autocomplete(element) {
43 | if (element.hasAttribute('autocompleted')) return;
44 | element.setAttribute('autocompleted', '');
45 |
46 | var event = new window.CustomEvent('onautocomplete', {
47 | bubbles: true, cancelable: true, detail: null,
48 | });
49 |
50 | // no autofill if preventDefault is called
51 | if (!element.dispatchEvent(event)) {
52 | element.value = '';
53 | }
54 | }
55 |
56 | /**
57 | * Manage an input element when its autocompleted value is
58 | * removed by the browser in the following steps:
59 | * - remove [autocompleted] attribute from event.target
60 | * - create 'onautocomplete' non-cancelable CustomEvent
61 | * - dispatch the Event
62 | *
63 | * @param {HtmlInputElement} element
64 | */
65 | function cancelAutocomplete(element) {
66 | if (!element.hasAttribute('autocompleted')) return;
67 | element.removeAttribute('autocompleted');
68 |
69 | // dispatch event
70 | element.dispatchEvent(new window.CustomEvent('onautocomplete', {
71 | bubbles: true, cancelable: false, detail: null,
72 | }));
73 | }
74 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Detect browsers autofill
2 |
3 | [](https://badge.fury.io/js/detect-autofill) [](https://travis-ci.org/matteobad/detect-autofill/)   [](https://greenkeeper.io/) [](https://opensource.org/licenses/MIT)
4 |
5 | * [Getting started](#getting-started)
6 | * [Features](#features)
7 | * [Browser support](#browser-support)
8 | * [Demo](https://matteobad.github.io/focus-within-polyfill)
9 |
10 | ## TLDR
11 |
12 | 1. Import script in the head
13 |
14 | ```html
15 |
16 | ...
17 |
18 | ...
19 |
20 | ```
21 |
22 | 2. add event listeners
23 | 3. do your things...
24 |
25 | ```js
26 | document.addEventListener('onautocomplete', function(e) {
27 | e.target.hasAttribute('autocompleted'); // true or false
28 | e.preventDefault(); // prevent autocomplete
29 | // do you stuff...
30 | })
31 | ```
32 |
33 | ## Getting Started
34 |
35 | Small javascript library to detect browser autofill of form elements. Usefull for implementing floating labels or appling custom styles.
36 |
37 | Modern browsers all have some ability to autocomplete the forms in a web page. It can be a login or a registration form, and the autofill can be triggered automatiaclly by the browser or manually by the user. In both cases **there is no native way to detect the autocomplete**. This is where this small library comes in handy.
38 |
39 | Every browser has it's own way to autocomplete a form. Basically this library creates and triggers a `CustomEvent` called `autocomplete` every time this happends.
40 |
41 | Furthermore this custom event can be prevented like all native events in order to block browser autofill using `e.preventDefault()`.
42 |
43 | ## Features
44 |
45 | * Polyfill for CustomEvent integrated
46 | * CustomEvent on `onautocomplete`
47 | * CustomEvent on `onautocomplete` cancel
48 | * Possibility to prevent `onautocomplete`
49 |
50 | ## Browser Support
51 |
52 | | CustomEvent | Edge | IE11 | Chrome | Firefox | Safari | Opera | iOS |
53 | | -------------- |:----:|:-----:|:------:|:-------:|:------:|:-----:|:---:|
54 | | `onautocomplete` | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
55 |
56 | \* This script uses different technics to detect autofill based on the browser:
57 |
58 | * **Chrome**, **Opera** and **Safari** uses the pseudo-class `:-webkit-autofill` to trigger a custom animation.
59 | * **Firefox** uses input event on document and checks for a propriety `inputType` property of the event.
60 | * **IE**, **Edge** and **iOS** uses the same input event but they have to check the `data` property.
61 | * **Android** ha not yet been tested any help is welcomed.
62 |
63 | ## Demos
64 |
65 | The [demos](https://github.com/matteobad/detect-autofill/tree/master/demos) can be tested on every browser. If something is not working properly, please open an issue or a PR.
66 |
67 | | Title | Source code | Live demo |
68 | | ----- | ----------- | --------- |
69 | | Fake login page | [Code](demos/fake-login.html) | [Live](https://matteobad.github.io/detect-autofill/demos/fake-login.html) |
70 |
--------------------------------------------------------------------------------
/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | # Contributor Covenant Code of Conduct
2 |
3 | ## Our Pledge
4 |
5 | In the interest of fostering an open and welcoming environment, we as
6 | contributors and maintainers pledge to making participation in our project and
7 | our community a harassment-free experience for everyone, regardless of age, body
8 | size, disability, ethnicity, sex characteristics, gender identity and expression,
9 | level of experience, education, socio-economic status, nationality, personal
10 | appearance, race, religion, or sexual identity and orientation.
11 |
12 | ## Our Standards
13 |
14 | Examples of behavior that contributes to creating a positive environment
15 | include:
16 |
17 | * Using welcoming and inclusive language
18 | * Being respectful of differing viewpoints and experiences
19 | * Gracefully accepting constructive criticism
20 | * Focusing on what is best for the community
21 | * Showing empathy towards other community members
22 |
23 | Examples of unacceptable behavior by participants include:
24 |
25 | * The use of sexualized language or imagery and unwelcome sexual attention or
26 | advances
27 | * Trolling, insulting/derogatory comments, and personal or political attacks
28 | * Public or private harassment
29 | * Publishing others' private information, such as a physical or electronic
30 | address, without explicit permission
31 | * Other conduct which could reasonably be considered inappropriate in a
32 | professional setting
33 |
34 | ## Our Responsibilities
35 |
36 | Project maintainers are responsible for clarifying the standards of acceptable
37 | behavior and are expected to take appropriate and fair corrective action in
38 | response to any instances of unacceptable behavior.
39 |
40 | Project maintainers have the right and responsibility to remove, edit, or
41 | reject comments, commits, code, wiki edits, issues, and other contributions
42 | that are not aligned to this Code of Conduct, or to ban temporarily or
43 | permanently any contributor for other behaviors that they deem inappropriate,
44 | threatening, offensive, or harmful.
45 |
46 | ## Scope
47 |
48 | This Code of Conduct applies within all project spaces, and it also applies when
49 | an individual is representing the project or its community in public spaces.
50 | Examples of representing a project or community include using an official
51 | project e-mail address, posting via an official social media account, or acting
52 | as an appointed representative at an online or offline event. Representation of
53 | a project may be further defined and clarified by project maintainers.
54 |
55 | ## Enforcement
56 |
57 | Instances of abusive, harassing, or otherwise unacceptable behavior may be
58 | reported by contacting the project team at matteo.badini95@gmail.com. All
59 | complaints will be reviewed and investigated and will result in a response that
60 | is deemed necessary and appropriate to the circumstances. The project team is
61 | obligated to maintain confidentiality with regard to the reporter of an incident.
62 | Further details of specific enforcement policies may be posted separately.
63 |
64 | Project maintainers who do not follow or enforce the Code of Conduct in good
65 | faith may face temporary or permanent repercussions as determined by other
66 | members of the project's leadership.
67 |
68 | ## Attribution
69 |
70 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
71 | available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
72 |
73 | [homepage]: https://www.contributor-covenant.org
74 |
75 | For answers to common questions about this code of conduct, see
76 | https://www.contributor-covenant.org/faq
77 |
78 |
--------------------------------------------------------------------------------