gitlab-org--gitlab-foss/app/assets/javascripts/username_validator.js.es6
Alfredo Sumaran 4e68b88193 Merge branch 'clean-no-undef' into 'master'
Explicitly declare all javascript globals and all eslint rule violations

This merge request takes every single external global variable referenced within a javascript file and explicitly marks it with a `/* global Foo */` comment block at the top of the script.

This also expands all blanket instances of `/* eslint-disable */` with an explicit list of disabled rules.  This is useful because if we need to search for violations of a particular rule we can simply grep the codebase for something like `no-unused-vars` or `semi` and find all of the places where this rule has yet to be fixed.

Lastly, it also removes and resolves any existing `no-undef` eslint violations.  This is useful for catching mistakes like forgetting to declare a variable with `var`/`let`/`const` which can cause hard to find bugs.

## What does this MR do?

1. Looks for generic uses of `/* eslint-disable */` and refactors them into individual rule exceptions.
2. Looks for all occurrences of `/* eslint-disable ... no-undef */` and resolves them by either fixing bugs or declaring globals with `/* global Foo */`.

## Are there points in the code the reviewer needs to double check?

This touches a lot of files, most changes touch nothing other than comment blocks or whitespace.  The exceptions are the following 14 files which required some small bug fixes after removing `no-undef`:

- api.js
- breakpoints.js
- build.js
- commits.js
- diff_notes/components/jump_to_discussion.js.es6
- gfm_auto_complete.js.es6
- gl_dropdown.js
- groups_select.js
- importer_status.js
- namespace_select.js
- notes.js
- preview_markdown.js
- projects_list.js
- single_file_diff.js

## Why was this MR needed?

Removal of ~"technical debt" and some necessary changes to help !7288 

## Screenshots (if relevant)

N/A

## Does this MR meet the acceptance criteria?

- [ ] ~~[Changelog entry](https://docs.gitlab.com/ce/development/changelog.html) added~~
- [ ] ~~[Documentation created/updated](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/doc/development/doc_styleguide.md)~~
- [ ] ~~API support added~~
- Tests
  - [ ] ~~Added for this feature/bug~~
  - [ ] All builds are passing
- [x] Conform by the [merge request performance guides](http://docs.gitlab.com/ce/development/merge_request_performance_guidelines.html)
- [x] Conform by the [style guides](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/CONTRIBUTING.md#style-guides)
- [x] Branch has no merge conflicts with `master` (if it does - rebase it please)
- [x] [Squashed related commits together](https://git-scm.com/book/en/Git-Tools-Rewriting-History#Squashing-Commits)

## What are the relevant issue numbers?

N/A

See merge request !8043
2016-12-15 00:52:46 +00:00

135 lines
3.8 KiB
JavaScript

/* eslint-disable comma-dangle, consistent-return, class-methods-use-this, arrow-parens, no-param-reassign, max-len */
((global) => {
const debounceTimeoutDuration = 1000;
const invalidInputClass = 'gl-field-error-outline';
const successInputClass = 'gl-field-success-outline';
const unavailableMessageSelector = '.username .validation-error';
const successMessageSelector = '.username .validation-success';
const pendingMessageSelector = '.username .validation-pending';
const invalidMessageSelector = '.username .gl-field-error';
class UsernameValidator {
constructor() {
this.inputElement = $('#new_user_username');
this.inputDomElement = this.inputElement.get(0);
this.state = {
available: false,
valid: false,
pending: false,
empty: true
};
const debounceTimeout = _.debounce((username) => {
this.validateUsername(username);
}, debounceTimeoutDuration);
this.inputElement.on('keyup.username_check', () => {
const username = this.inputElement.val();
this.state.valid = this.inputDomElement.validity.valid;
this.state.empty = !username.length;
if (this.state.valid) {
return debounceTimeout(username);
}
this.renderState();
});
// Override generic field validation
this.inputElement.on('invalid', this.interceptInvalid.bind(this));
}
renderState() {
// Clear all state
this.clearFieldValidationState();
if (this.state.valid && this.state.available) {
return this.setSuccessState();
}
if (this.state.empty) {
return this.clearFieldValidationState();
}
if (this.state.pending) {
return this.setPendingState();
}
if (!this.state.available) {
return this.setUnavailableState();
}
if (!this.state.valid) {
return this.setInvalidState();
}
}
interceptInvalid(event) {
event.preventDefault();
event.stopPropagation();
}
validateUsername(username) {
if (this.state.valid) {
this.state.pending = true;
this.state.available = false;
this.renderState();
return $.ajax({
type: 'GET',
url: `${gon.relative_url_root}/users/${username}/exists`,
dataType: 'json',
success: (res) => this.setAvailabilityState(res.exists)
});
}
}
setAvailabilityState(usernameTaken) {
if (usernameTaken) {
this.state.valid = false;
this.state.available = false;
} else {
this.state.available = true;
}
this.state.pending = false;
this.renderState();
}
clearFieldValidationState() {
this.inputElement.siblings('p').hide();
this.inputElement.removeClass(invalidInputClass)
.removeClass(successInputClass);
}
setUnavailableState() {
const $usernameUnavailableMessage = this.inputElement.siblings(unavailableMessageSelector);
this.inputElement.addClass(invalidInputClass).removeClass(successInputClass);
$usernameUnavailableMessage.show();
}
setSuccessState() {
const $usernameSuccessMessage = this.inputElement.siblings(successMessageSelector);
this.inputElement.addClass(successInputClass).removeClass(invalidInputClass);
$usernameSuccessMessage.show();
}
setPendingState() {
const $usernamePendingMessage = $(pendingMessageSelector);
if (this.state.pending) {
$usernamePendingMessage.show();
} else {
$usernamePendingMessage.hide();
}
}
setInvalidState() {
const $inputErrorMessage = $(invalidMessageSelector);
this.inputElement.addClass(invalidInputClass).removeClass(successInputClass);
$inputErrorMessage.show();
}
}
global.UsernameValidator = UsernameValidator;
})(window);