diff --git a/doc/development/new_fe_guide/style/javascript.md b/doc/development/new_fe_guide/style/javascript.md
index 7985b893c9e..3019eaa089c 100644
--- a/doc/development/new_fe_guide/style/javascript.md
+++ b/doc/development/new_fe_guide/style/javascript.md
@@ -1,208 +1,196 @@
# JavaScript style guide
-We use [Airbnb's JavaScript Style Guide][airbnb-style-guide] and it's accompanying linter to manage most of our JavaScript style guidelines.
+We use [Airbnb's JavaScript Style Guide](https://github.com/airbnb/javascript) and it's accompanying
+linter to manage most of our JavaScript style guidelines.
-In addition to the style guidelines set by Airbnb, we also have a few specific rules listed below.
+In addition to the style guidelines set by Airbnb, we also have a few specific rules
+listed below.
> **Tip:**
You can run eslint locally by running `yarn eslint`
-## Arrays
+## Avoid forEach
-
+Avoid forEach when mutating data. Use `map`, `reduce` or `filter` instead of `forEach`
+when mutating data. This will minimize mutations in functions,
+which aligns with [Airbnb's style guide](https://github.com/airbnb/javascript#testing--for-real).
-- [1.1](#avoid-foreach) **Avoid ForEach when mutating data** Use `map`, `reduce` or `filter` instead of `forEach` when mutating data. This will minimize mutations in functions ([which is aligned with Airbnb's style guide][airbnb-minimize-mutations])
+```javascript
+// bad
+users.forEach((user, index) => {
+ user.id = index;
+});
- ```
- // bad
- users.forEach((user, index) => {
- user.id = index;
- });
+// good
+const usersWithId = users.map((user, index) => {
+ return Object.assign({}, user, { id: index });
+});
+```
- // good
- const usersWithId = users.map((user, index) => {
- return Object.assign({}, user, { id: index });
- });
- ```
+## Limit number of parameters
-## Functions
+If your function or method has more than 3 parameters, use an object as a parameter
+instead.
-
+```javascript
+// bad
+function a(p1, p2, p3) {
+ // ...
+};
-- [2.1](#limit-params) **Limit number of parameters** If your function or method has more than 3 parameters, use an object as a parameter instead.
+// good
+function a(p) {
+ // ...
+};
+```
- ```
- // bad
- function a(p1, p2, p3) {
- // ...
- };
+## Avoid side effects in constructors
- // good
- function a(p) {
- // ...
- };
- ```
+Avoid making asynchronous calls, API requests or DOM manipulations in the `constructor`.
+Move them into separate functions instead. This will make tests easier to write and
+code easier to maintain.
-## Classes & constructors
+```javascript
+// bad
+class myClass {
+ constructor(config) {
+ this.config = config;
+ axios.get(this.config.endpoint)
+ }
+}
-
+// good
+class myClass {
+ constructor(config) {
+ this.config = config;
+ }
-- [3.1](#avoid-constructor-side-effects) **Avoid side effects in constructors** Avoid making some operations in the `constructor`, such as asynchronous calls, API requests and DOM manipulations. Prefer moving them into separate functions. This will make tests easier to write and code easier to maintain.
+ makeRequest() {
+ axios.get(this.config.endpoint)
+ }
+}
+const instance = new myClass();
+instance.makeRequest();
- ```javascript
- // bad
- class myClass {
- constructor(config) {
- this.config = config;
- axios.get(this.config.endpoint)
- }
- }
+```
- // good
- class myClass {
- constructor(config) {
- this.config = config;
- }
+## Avoid classes to handle DOM events
- makeRequest() {
- axios.get(this.config.endpoint)
- }
- }
- const instance = new myClass();
- instance.makeRequest();
+If the only purpose of the class is to bind a DOM event and handle the callback, prefer
+using a function.
- ```
+```javascript
+// bad
+class myClass {
+ constructor(config) {
+ this.config = config;
+ }
-
+ init() {
+ document.addEventListener('click', () => {});
+ }
+}
-- [3.2](#avoid-classes-to-handle-dom-events) **Avoid classes to handle DOM events** If the only purpose of the class is to bind a DOM event and handle the callback, prefer using a function.
+// good
- ```
- // bad
- class myClass {
- constructor(config) {
- this.config = config;
- }
+const myFunction = () => {
+ document.addEventListener('click', () => {
+ // handle callback here
+ });
+}
+```
- init() {
- document.addEventListener('click', () => {});
- }
- }
+## Pass element container to constructor
- // good
+When your class manipulates the DOM, receive the element container as a parameter.
+This is more maintainable and performant.
- const myFunction = () => {
- document.addEventListener('click', () => {
- // handle callback here
- });
- }
- ```
+```javascript
+// bad
+class a {
+ constructor() {
+ document.querySelector('.b');
+ }
+}
-
+// good
+class a {
+ constructor(options) {
+ options.container.querySelector('.b');
+ }
+}
+```
-- [3.3](#element-container) **Pass element container to constructor** When your class manipulates the DOM, receive the element container as a parameter.
- This is more maintainable and performant.
+## Use ParseInt
- ```
- // bad
- class a {
- constructor() {
- document.querySelector('.b');
- }
- }
+Use `ParseInt` when converting a numeric string into a number.
- // good
- class a {
- constructor(options) {
- options.container.querySelector('.b');
- }
- }
- ```
+```javascript
+// bad
+Number('10')
-## Type Casting & Coercion
+// good
+parseInt('10', 10);
+```
-
+## CSS Selectors - Use `js-` prefix
-- [4.1](#use-parseint) **Use ParseInt** Use `ParseInt` when converting a numeric string into a number.
+If a CSS class is only being used in JavaScript as a reference to the element, prefix
+the class name with `js-`.
- ```
- // bad
- Number('10')
+```html
+// bad
+
- // good
- parseInt('10', 10);
- ```
+// good
+
+```
-## CSS Selectors
+## Absolute vs relative paths for modules
-
+Use relative paths if the module you are importing is less than two levels up.
-- [5.1](#use-js-prefix) **Use js prefix** If a CSS class is only being used in JavaScript as a reference to the element, prefix the class name with `js-`
+```javascript
+// bad
+import GitLabStyleGuide from '~/guides/GitLabStyleGuide';
- ```
- // bad
-
+// good
+import GitLabStyleGuide from '../GitLabStyleGuide';
+```
- // good
-
- ```
+If the module you are importing is two or more levels up, use an absolute path instead:
-## Modules
+```javascript
+// bad
+import GitLabStyleGuide from '../../../guides/GitLabStyleGuide';
-
+// good
+import GitLabStyleGuide from '~/GitLabStyleGuide';
+```
-- [6.1](#use-absolute-paths) **Use absolute paths for nearby modules** Use absolute paths if the module you are importing is less than two levels up.
+Additionally, **do not add to global namespace**.
- ```
- // bad
- import GitLabStyleGuide from '~/guides/GitLabStyleGuide';
+## Do not use `DOMContentLoaded` in non-page modules
- // good
- import GitLabStyleGuide from '../GitLabStyleGuide';
- ```
+Imported modules should act the same each time they are loaded. `DOMContentLoaded`
+events are only allowed on modules loaded in the `/pages/*` directory because those
+are loaded dynamically with webpack.
-
+## Avoid XSS
-- [6.2](#use-relative-paths) **Use relative paths for distant modules** If the module you are importing is two or more levels up, use a relative path instead of an absolute path.
+Do not use `innerHTML`, `append()` or `html()` to set content. It opens up too many
+vulnerabilities.
- ```
- // bad
- import GitLabStyleGuide from '../../../guides/GitLabStyleGuide';
+## Disabling ESLint in new files
- // good
- import GitLabStyleGuide from '~/GitLabStyleGuide';
- ```
+Do not disable ESLint when creating new files. Existing files may have existing rules
+disabled due to legacy compatibility reasons but they are in the process of being refactored.
-
+Do not disable specific ESLint rules. Due to technical debt, you may disable the following
+rules only if you are invoking/instantiating existing code modules.
-- [6.3](#global-namespace) **Do not add to global namespace**
+ - [no-new](http://eslint.org/docs/rules/no-new)
+ - [class-method-use-this](http://eslint.org/docs/rules/class-methods-use-this)
-
-
-- [6.4](#domcontentloaded) **Do not use DOMContentLoaded in non-page modules** Imported modules should act the same each time they are loaded. `DOMContentLoaded` events are only allowed on modules loaded in the `/pages/*` directory because those are loaded dynamically with webpack.
-
-## Security
-
-
-
-- [7.1](#avoid-xss) **Avoid XSS** Do not use `innerHTML`, `append()` or `html()` to set content. It opens up too many vulnerabilities.
-
-## ESLint
-
-
-
-- [8.1](#disable-eslint-file) **Disabling ESLint in new files** Do not disable ESLint when creating new files. Existing files may have existing rules disabled due to legacy compatibility reasons but they are in the process of being refactored.
-
-
-
-- [8.2](#disable-eslint-rule) **Disabling ESLint rule** Do not disable specific ESLint rules. Due to technical debt, you may disable the following rules only if you are invoking/instantiating existing code modules
-
- - [no-new][no-new]
- - [class-method-use-this][class-method-use-this]
-
-> Note: Disable these rules on a per line basis. This makes it easier to refactor in the future. E.g. use `eslint-disable-next-line` or `eslint-disable-line`
-
-[airbnb-style-guide]: https://github.com/airbnb/javascript
-[airbnb-minimize-mutations]: https://github.com/airbnb/javascript#testing--for-real
-[no-new]: http://eslint.org/docs/rules/no-new
-[class-method-use-this]: http://eslint.org/docs/rules/class-methods-use-this
+> Note: Disable these rules on a per line basis. This makes it easier to refactor
+ in the future. E.g. use `eslint-disable-next-line` or `eslint-disable-line`.