diff --git a/app/assets/javascripts/LabelManager.js b/app/assets/javascripts/LabelManager.js
index 151455ce4a3a9f49c928593e864639e555d497cb..d4a4c7abaa1fb3932036d9320cc01a195a2677f4 100644
--- a/app/assets/javascripts/LabelManager.js
+++ b/app/assets/javascripts/LabelManager.js
@@ -3,6 +3,7 @@
     LabelManager.prototype.errorMessage = 'Unable to update label prioritization at this time';
 
     function LabelManager(opts) {
+      // Defaults
       var ref, ref1, ref2;
       if (opts == null) {
         opts = {};
@@ -28,6 +29,7 @@
       $btn = $(e.currentTarget);
       $label = $("#" + ($btn.data('domId')));
       action = $btn.parents('.js-prioritized-labels').length ? 'remove' : 'add';
+      // Make sure tooltip will hide
       $tooltip = $("#" + ($btn.find('.has-tooltip:visible').attr('aria-describedby')));
       $tooltip.tooltip('destroy');
       return _this.toggleLabelPriority($label, action);
@@ -42,6 +44,7 @@
       url = $label.find('.js-toggle-priority').data('url');
       $target = this.prioritizedLabels;
       $from = this.otherLabels;
+      // Optimistic update
       if (action === 'remove') {
         $target = this.otherLabels;
         $from = this.prioritizedLabels;
@@ -53,6 +56,7 @@
         $target.find('.empty-message').addClass('hidden');
       }
       $label.detach().appendTo($target);
+      // Return if we are not persisting state
       if (!persistState) {
         return;
       }
@@ -61,6 +65,7 @@
           url: url,
           type: 'DELETE'
         });
+        // Restore empty message
         if (!$from.find('li').length) {
           $from.find('.empty-message').removeClass('hidden');
         }
diff --git a/app/assets/javascripts/api.js b/app/assets/javascripts/api.js
index 84b292e59c643756ceefa00024be7529557b8a68..6df2ecf57a298d823000ccd3cc0013a79af962b0 100644
--- a/app/assets/javascripts/api.js
+++ b/app/assets/javascripts/api.js
@@ -24,6 +24,8 @@
         return callback(group);
       });
     },
+    // Return groups list. Filtered by query
+    // Only active groups retrieved
     groups: function(query, skip_ldap, callback) {
       var url = Api.buildUrl(Api.groupsPath);
       return $.ajax({
@@ -38,6 +40,7 @@
         return callback(groups);
       });
     },
+    // Return namespaces list. Filtered by query
     namespaces: function(query, callback) {
       var url = Api.buildUrl(Api.namespacesPath);
       return $.ajax({
@@ -52,6 +55,7 @@
         return callback(namespaces);
       });
     },
+    // Return projects list. Filtered by query
     projects: function(query, order, callback) {
       var url = Api.buildUrl(Api.projectsPath);
       return $.ajax({
@@ -82,6 +86,7 @@
         return callback(message.responseJSON);
       });
     },
+    // Return group projects list. Filtered by query
     groupProjects: function(group_id, query, callback) {
       var url = Api.buildUrl(Api.groupProjectsPath)
         .replace(':id', group_id);
@@ -97,6 +102,7 @@
         return callback(projects);
       });
     },
+    // Return text for a specific license
     licenseText: function(key, data, callback) {
       var url = Api.buildUrl(Api.licensePath)
         .replace(':key', key);
diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js
index fea6f41d5e9e94f605600d868f5a23d5986db46b..31fa508d6c14595fa2598beebdd81cd551fb5e37 100644
--- a/app/assets/javascripts/application.js
+++ b/app/assets/javascripts/application.js
@@ -1,3 +1,9 @@
+// This is a manifest file that'll be compiled into including all the files listed below.
+// Add new JavaScript/Coffee code in separate files in this directory and they'll automatically
+// be included in the compiled file accessible from http://example.com/assets/application.js
+// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
+// the compiled file.
+//
 /*= require jquery2 */
 /*= require jquery-ui/autocomplete */
 /*= require jquery-ui/datepicker */
@@ -76,6 +82,7 @@
     }
   };
 
+  // Disable button if text field is empty
   window.disableButtonIfEmptyField = function(field_selector, button_selector) {
     var closest_submit, field;
     field = $(field_selector);
@@ -92,6 +99,7 @@
     });
   };
 
+  // Disable button if any input field with given selector is empty
   window.disableButtonIfAnyEmptyField = function(form, form_selector, button_selector) {
     var closest_submit, updateButtons;
     closest_submit = form.find(button_selector);
@@ -128,6 +136,8 @@
   window.addEventListener("hashchange", shiftWindow);
 
   window.onload = function() {
+    // Scroll the window to avoid the topnav bar
+    // https://github.com/twitter/bootstrap/issues/1768
     if (location.hash) {
       return setTimeout(shiftWindow, 100);
     }
@@ -149,6 +159,8 @@
       return $(this).select().one('mouseup', function(e) {
         return e.preventDefault();
       });
+    // Click a .js-select-on-focus field, select the contents
+    // Prevent a mouseup event from deselecting the input
     });
     $('.remove-row').bind('ajax:success', function() {
       $(this).tooltip('destroy')
@@ -163,6 +175,7 @@
     });
     $('select.select2').select2({
       width: 'resolve',
+      // Initialize select2 selects
       dropdownAutoWidth: true
     });
     $('.js-select2').bind('select2-close', function() {
@@ -170,7 +183,9 @@
         $('.select2-container-active').removeClass('select2-container-active');
         return $(':focus').blur();
       }), 1);
+    // Close select2 on escape
     });
+    // Initialize tooltips
     $body.tooltip({
       selector: '.has-tooltip, [data-toggle="tooltip"]',
       placement: function(_, el) {
@@ -179,14 +194,17 @@
     });
     $('.trigger-submit').on('change', function() {
       return $(this).parents('form').submit();
+    // Form submitter
     });
     gl.utils.localTimeAgo($('abbr.timeago, .js-timeago'), true);
+    // Flash
     if ((flash = $(".flash-container")).length > 0) {
       flash.click(function() {
         return $(this).fadeOut();
       });
       flash.show();
     }
+    // Disable form buttons while a form is submitting
     $body.on('ajax:complete, ajax:beforeSend, submit', 'form', function(e) {
       var buttons;
       buttons = $('[type="submit"]', this);
@@ -207,6 +225,7 @@
       }
     });
     $('.account-box').hover(function() {
+      // Show/Hide the profile menu when hovering the account box
       return $(this).toggleClass('hover');
     });
     $document.on('click', '.diff-content .js-show-suppressed-diff', function() {
@@ -214,6 +233,7 @@
       $container = $(this).parent();
       $container.next('table').show();
       return $container.remove();
+    // Commit show suppressed diff
     });
     $('.navbar-toggle').on('click', function() {
       $('.header-content .title').toggle();
@@ -221,6 +241,7 @@
       $('.header-content .navbar-collapse').toggle();
       return $('.navbar-toggle').toggleClass('active');
     });
+    // Show/hide comments on diff
     $body.on("click", ".js-toggle-diff-comments", function(e) {
       var $this = $(this);
       $this.toggleClass('active');
diff --git a/app/assets/javascripts/autosave.js b/app/assets/javascripts/autosave.js
index 7116512d6b7be2d5ba3e6062f8d6cb589572f20e..a9aec6e8ea48950c66ae6bf9ff05e8cb7be218b0 100644
--- a/app/assets/javascripts/autosave.js
+++ b/app/assets/javascripts/autosave.js
@@ -16,7 +16,7 @@
     }
 
     Autosave.prototype.restore = function() {
-      var e, error, text;
+      var e, text;
       if (window.localStorage == null) {
         return;
       }
@@ -41,7 +41,7 @@
       if ((text != null ? text.length : void 0) > 0) {
         try {
           return window.localStorage.setItem(this.key, text);
-        } catch (undefined) {}
+        } catch (error) {}
       } else {
         return this.reset();
       }
@@ -53,7 +53,7 @@
       }
       try {
         return window.localStorage.removeItem(this.key);
-      } catch (undefined) {}
+      } catch (error) {}
     };
 
     return Autosave;
diff --git a/app/assets/javascripts/awards_handler.js b/app/assets/javascripts/awards_handler.js
index 5ea18ea8b7a7c6f4b3fc357e10f466bbbb91b09a..0decc6d09e6d9c3a0f50492372e23305efc4b2c0 100644
--- a/app/assets/javascripts/awards_handler.js
+++ b/app/assets/javascripts/awards_handler.js
@@ -86,6 +86,8 @@
     AwardsHandler.prototype.positionMenu = function($menu, $addBtn) {
       var css, position;
       position = $addBtn.data('position');
+      // The menu could potentially be off-screen or in a hidden overflow element
+      // So we position the element absolute in the body
       css = {
         top: ($addBtn.offset().top + $addBtn.outerHeight()) + "px"
       };
@@ -284,6 +286,7 @@
       if (emojiIcon.length > 0) {
         unicodeName = emojiIcon.data('unicode-name');
       } else {
+        // Find by alias
         unicodeName = $(".emoji-menu-content [data-aliases*=':" + emoji + ":']").data('unicode-name');
       }
       return "emoji-" + unicodeName;
@@ -350,8 +353,10 @@
         return function(ev) {
           var found_emojis, h5, term, ul;
           term = $(ev.target).val();
+          // Clean previous search results
           $('ul.emoji-menu-search, h5.emoji-search').remove();
           if (term) {
+            // Generate a search result block
             h5 = $('<h5>').text('Search results');
             found_emojis = _this.searchEmojis(term).show();
             ul = $('<ul>').addClass('emoji-menu-list emoji-menu-search').append(found_emojis);
diff --git a/app/assets/javascripts/behaviors/autosize.js b/app/assets/javascripts/behaviors/autosize.js
index f977a1e8a7b072806b0bd7cdaacadfd24ee94262..dc8ae601961e2434f9523ac63621a6b05eafedc4 100644
--- a/app/assets/javascripts/behaviors/autosize.js
+++ b/app/assets/javascripts/behaviors/autosize.js
@@ -1,7 +1,5 @@
 
 /*= require jquery.ba-resize */
-
-
 /*= require autosize */
 
 (function() {
diff --git a/app/assets/javascripts/behaviors/details_behavior.js b/app/assets/javascripts/behaviors/details_behavior.js
index 3631d1b74ac17a6e9da357919cedc1c72f1a8861..1df681a4816bd4b4fb763810566e40566a459b1f 100644
--- a/app/assets/javascripts/behaviors/details_behavior.js
+++ b/app/assets/javascripts/behaviors/details_behavior.js
@@ -5,6 +5,12 @@
       container = $(this).closest(".js-details-container");
       return container.toggleClass("open");
     });
+    // Show details content. Hides link after click.
+    //
+    // %div
+    //   %a.js-details-expand
+    //   %div.js-details-content
+    //
     return $("body").on("click", ".js-details-expand", function(e) {
       $(this).next('.js-details-content').removeClass("hide");
       $(this).hide();
diff --git a/app/assets/javascripts/behaviors/quick_submit.js b/app/assets/javascripts/behaviors/quick_submit.js
index 3527d0a95fc584bda085641ce28a822f39640bde..54b7360ab41632b2c6f88cefecee7d4f8fb542ea 100644
--- a/app/assets/javascripts/behaviors/quick_submit.js
+++ b/app/assets/javascripts/behaviors/quick_submit.js
@@ -1,6 +1,20 @@
-
+// Quick Submit behavior
+//
+// When a child field of a form with a `js-quick-submit` class receives a
+// "Meta+Enter" (Mac) or "Ctrl+Enter" (Linux/Windows) key combination, the form
+// is submitted.
+//
 /*= require extensions/jquery */
 
+//
+// ### Example Markup
+//
+//   <form action="/foo" class="js-quick-submit">
+//     <input type="text" />
+//     <textarea></textarea>
+//     <input type="submit" value="Submit" />
+//   </form>
+//
 (function() {
   var isMac, keyCodeIs;
 
@@ -17,6 +31,7 @@
 
   $(document).on('keydown.quick_submit', '.js-quick-submit', function(e) {
     var $form, $submit_button;
+    // Enter
     if (!keyCodeIs(e, 13)) {
       return;
     }
@@ -33,8 +48,11 @@
     return $form.submit();
   });
 
+  // If the user tabs to a submit button on a `js-quick-submit` form, display a
+  // tooltip to let them know they could've used the hotkey
   $(document).on('keyup.quick_submit', '.js-quick-submit input[type=submit], .js-quick-submit button[type=submit]', function(e) {
     var $this, title;
+    // Tab
     if (!keyCodeIs(e, 9)) {
       return;
     }
diff --git a/app/assets/javascripts/behaviors/requires_input.js b/app/assets/javascripts/behaviors/requires_input.js
index db0b36b24e9e53f081ed466fc30e6047541fdd84..894034bdd541b4da146a779c2f1e2f2fd10aeb63 100644
--- a/app/assets/javascripts/behaviors/requires_input.js
+++ b/app/assets/javascripts/behaviors/requires_input.js
@@ -1,6 +1,18 @@
-
+// Requires Input behavior
+//
+// When called on a form with input fields with the `required` attribute, the
+// form's submit button will be disabled until all required fields have values.
+//
 /*= require extensions/jquery */
 
+//
+// ### Example Markup
+//
+//   <form class="js-requires-input">
+//     <input type="text" required="required">
+//     <input type="submit" value="Submit">
+//   </form>
+//
 (function() {
   $.fn.requiresInput = function() {
     var $button, $form, fieldSelector, requireInput, required;
@@ -11,14 +23,17 @@
     requireInput = function() {
       var values;
       values = _.map($(fieldSelector, $form), function(field) {
+        // Collect the input values of *all* required fields
         return field.value;
       });
+      // Disable the button if any required fields are empty
       if (values.length && _.any(values, _.isEmpty)) {
         return $button.disable();
       } else {
         return $button.enable();
       }
     };
+    // Set initial button state
     requireInput();
     return $form.on('change input', fieldSelector, requireInput);
   };
@@ -27,6 +42,8 @@
     var $form, hideOrShowHelpBlock;
     $form = $('form.js-requires-input');
     $form.requiresInput();
+    // Hide or Show the help block when creating a new project
+    // based on the option selected
     hideOrShowHelpBlock = function(form) {
       var selected;
       selected = $('.js-select-namespace option:selected');
diff --git a/app/assets/javascripts/behaviors/toggler_behavior.js b/app/assets/javascripts/behaviors/toggler_behavior.js
index 5467e3edc69278fb5e8d89b1e2c145df027a0a32..a6ce378d67a4c1197d7f4386c1173cbb8a9e19e3 100644
--- a/app/assets/javascripts/behaviors/toggler_behavior.js
+++ b/app/assets/javascripts/behaviors/toggler_behavior.js
@@ -1,5 +1,12 @@
 (function(w) {
   $(function() {
+    // Toggle button. Show/hide content inside parent container.
+    // Button does not change visibility. If button has icon - it changes chevron style.
+    //
+    // %div.js-toggle-container
+    //   %a.js-toggle-button
+    //   %div.js-toggle-content
+    //
     $('body').on('click', '.js-toggle-button', function(e) {
       e.preventDefault();
       $(this)
diff --git a/app/assets/javascripts/blob/blob_file_dropzone.js b/app/assets/javascripts/blob/blob_file_dropzone.js
index f4044f22db20f514b2adf7ebbc8dcb50ae08894f..8cca1aa923237ba0db0ff9c648df447ac58823c9 100644
--- a/app/assets/javascripts/blob/blob_file_dropzone.js
+++ b/app/assets/javascripts/blob/blob_file_dropzone.js
@@ -8,6 +8,8 @@
         autoDiscover: false,
         autoProcessQueue: false,
         url: form.attr('action'),
+        // Rails uses a hidden input field for PUT
+        // http://stackoverflow.com/questions/21056482/how-to-set-method-put-in-form-tag-in-rails
         method: method,
         clickable: true,
         uploadMultiple: false,
@@ -36,6 +38,7 @@
             formData.append('commit_message', form.find('.js-commit-message').val());
           });
         },
+        // Override behavior of adding error underneath preview
         error: function(file, errorMessage) {
           var stripped;
           stripped = $("<div/>").html(errorMessage).text();
diff --git a/app/assets/javascripts/blob/template_selector.js b/app/assets/javascripts/blob/template_selector.js
index b0a37ef0e0a4f57b1b76b51ab24c3f63e48bc432..b18b6962382fa2d78e18a38ebd87fa0692deeee6 100644
--- a/app/assets/javascripts/blob/template_selector.js
+++ b/app/assets/javascripts/blob/template_selector.js
@@ -66,6 +66,9 @@
       // be added by all subclasses.
     };
 
+    // To be implemented on the extending class
+    // e.g.
+    // Api.gitignoreText item.name, @requestFileSuccess.bind(@)
     TemplateSelector.prototype.requestFileSuccess = function(file, skipFocus) {
       this.editor.setValue(file.content, 1);
       if (!skipFocus) this.editor.focus();
diff --git a/app/assets/javascripts/blob_edit/edit_blob.js b/app/assets/javascripts/blob_edit/edit_blob.js
index 649c79daee8b13a8eeed7a7d055d594ab3f584b8..b846bab04243bf0d325b2a2e958aec05d8b471dd 100644
--- a/app/assets/javascripts/blob_edit/edit_blob.js
+++ b/app/assets/javascripts/blob_edit/edit_blob.js
@@ -18,6 +18,8 @@
         return function() {
           return $("#file-content").val(_this.editor.getValue());
         };
+      // Before a form submission, move the content from the Ace editor into the
+      // submitted textarea
       })(this));
       this.initModePanesAndLinks();
       new BlobLicenseSelectors({
diff --git a/app/assets/javascripts/breakpoints.js b/app/assets/javascripts/breakpoints.js
index 1e0148e579817a38b91e81c3428d39d3bdae303b..5fef972517809f72de9fbb0e14067976fbfc9029 100644
--- a/app/assets/javascripts/breakpoints.js
+++ b/app/assets/javascripts/breakpoints.js
@@ -23,6 +23,7 @@
         if ($(allDeviceSelector.join(",")).length) {
           return;
         }
+        // Create all the elements
         els = $.map(BREAKPOINTS, function(breakpoint) {
           return "<div class='device-" + breakpoint + " visible-" + breakpoint + "'></div>";
         });
@@ -40,6 +41,7 @@
       BreakpointInstance.prototype.getBreakpointSize = function() {
         var $visibleDevice;
         $visibleDevice = this.visibleDevice;
+        // the page refreshed via turbolinks
         if (!$visibleDevice().length) {
           this.setup();
         }
diff --git a/app/assets/javascripts/build.js b/app/assets/javascripts/build.js
index 4d066f1364686f4bf19df67a4e1087ec5ae60bf8..10abeb50f4b37f2a467d02d7c9fca059a18f2113 100644
--- a/app/assets/javascripts/build.js
+++ b/app/assets/javascripts/build.js
@@ -16,6 +16,7 @@
       this.toggleSidebar = bind(this.toggleSidebar, this);
       this.updateDropdown = bind(this.updateDropdown, this);
       clearInterval(Build.interval);
+      // Init breakpoint checker
       this.bp = Breakpoints.get();
       $('.js-build-sidebar').niceScroll();
 
@@ -42,6 +43,9 @@
             $(this).data("state", "enabled");
             return $(this).text("disable autoscroll");
           }
+        //
+        // Bind autoscroll button to follow build output
+        //
         });
         Build.interval = setInterval((function(_this) {
           return function() {
@@ -49,6 +53,10 @@
               return _this.getBuildTrace();
             }
           };
+        //
+        // Check for new build output if user still watching build page
+        // Only valid for runnig build when output changes during time
+        //
         })(this), 4000);
       }
     }
diff --git a/app/assets/javascripts/commit/image-file.js b/app/assets/javascripts/commit/image-file.js
index c0d0b2d049fae7feb9eeb7ce431df914a518a6ac..e893491b19bb47c0504f88b59a95c8fe36c5ef89 100644
--- a/app/assets/javascripts/commit/image-file.js
+++ b/app/assets/javascripts/commit/image-file.js
@@ -2,6 +2,7 @@
   this.ImageFile = (function() {
     var prepareFrames;
 
+    // Width where images must fits in, for 2-up this gets divided by 2
     ImageFile.availWidth = 900;
 
     ImageFile.viewModes = ['two-up', 'swipe'];
@@ -9,6 +10,7 @@
     function ImageFile(file) {
       this.file = file;
       this.requestImageInfo($('.two-up.view .frame.deleted img', this.file), (function(_this) {
+        // Determine if old and new file has same dimensions, if not show 'two-up' view
         return function(deletedWidth, deletedHeight) {
           return _this.requestImageInfo($('.two-up.view .frame.added img', _this.file), function(width, height) {
             if (width === deletedWidth && height === deletedHeight) {
diff --git a/app/assets/javascripts/commits.js b/app/assets/javascripts/commits.js
index 37f168c51902ba2b5b01efb0614815e5fdd3a166..9132089adcdde55f080e64cc69c3992ac627cdbc 100644
--- a/app/assets/javascripts/commits.js
+++ b/app/assets/javascripts/commits.js
@@ -45,6 +45,7 @@
           CommitsList.content.html(data.html);
           return history.replaceState({
             page: commitsUrl
+          // Change url so if user reload a page - search results are saved
           }, document.title, commitsUrl);
         },
         dataType: "json"
diff --git a/app/assets/javascripts/copy_to_clipboard.js b/app/assets/javascripts/copy_to_clipboard.js
index c43af17442b46be1cdd0c041d486d6ac6bdff599..3e20db7e3081a8f04df95287f517de2899e51a27 100644
--- a/app/assets/javascripts/copy_to_clipboard.js
+++ b/app/assets/javascripts/copy_to_clipboard.js
@@ -6,14 +6,19 @@
 
   genericSuccess = function(e) {
     showTooltip(e.trigger, 'Copied!');
+    // Clear the selection and blur the trigger so it loses its border
     e.clearSelection();
     return $(e.trigger).blur();
   };
 
+  // Safari doesn't support `execCommand`, so instead we inform the user to
+  // copy manually.
+  //
+  // See http://clipboardjs.com/#browser-support
   genericError = function(e) {
     var key;
     if (/Mac/i.test(navigator.userAgent)) {
-      key = '&#8984;';
+      key = '&#8984;'; // Command
     } else {
       key = 'Ctrl';
     }
diff --git a/app/assets/javascripts/diff.js b/app/assets/javascripts/diff.js
index 3dd7ceba92faaa61683d2304f521d12274f1b207..c8634b78f2bcd1ac96fb323896f938f28197b974 100644
--- a/app/assets/javascripts/diff.js
+++ b/app/assets/javascripts/diff.js
@@ -39,6 +39,9 @@
             bottom: unfoldBottom,
             offset: offset,
             unfold: unfold,
+            // indent is used to compensate for single space indent to fit
+            // '+' and '-' prepended to diff lines,
+            // see https://gitlab.com/gitlab-org/gitlab-ce/issues/707
             indent: 1,
             view: file.data('view')
           };
diff --git a/app/assets/javascripts/dispatcher.js b/app/assets/javascripts/dispatcher.js
index 179d3bc38a5a2b4e81bb9b815249f53fb15b5aa7..99b16f7d59bd1451cac0d802a36813b4e07e85a4 100644
--- a/app/assets/javascripts/dispatcher.js
+++ b/app/assets/javascripts/dispatcher.js
@@ -164,6 +164,8 @@
           }
           break;
         case 'projects:network:show':
+          // Ensure we don't create a particular shortcut handler here. This is
+          // already created, where the network graph is created.
           shortcut_handler = true;
           break;
         case 'projects:forks:new':
@@ -260,12 +262,14 @@
               shortcut_handler = new ShortcutsNavigation();
           }
       }
+      // If we haven't installed a custom shortcut handler, install the default one
       if (!shortcut_handler) {
         return new Shortcuts();
       }
     };
 
     Dispatcher.prototype.initSearch = function() {
+      // Only when search form is present
       if ($('.search').length) {
         return new SearchAutocomplete();
       }
diff --git a/app/assets/javascripts/due_date_select.js b/app/assets/javascripts/due_date_select.js
index 5a725a41fd123f9d4084136f621dde967c8d4b4a..bf68b7e3a9b757a3d51293645b906c6d5960a1df 100644
--- a/app/assets/javascripts/due_date_select.js
+++ b/app/assets/javascripts/due_date_select.js
@@ -2,6 +2,7 @@
   this.DueDateSelect = (function() {
     function DueDateSelect() {
       var $datePicker, $dueDate, $loading;
+      // Milestone edit/new form
       $datePicker = $('.datepicker');
       if ($datePicker.length) {
         $dueDate = $('#milestone_due_date');
@@ -16,6 +17,7 @@
         e.preventDefault();
         return $.datepicker._clearDate($datePicker);
       });
+      // Issuable sidebar
       $loading = $('.js-issuable-update .due_date').find('.block-loading').hide();
       $('.js-due-date-select').each(function(i, dropdown) {
         var $block, $dropdown, $dropdownParent, $selectbox, $sidebarValue, $value, $valueContent, abilityName, addDueDate, fieldName, issueUpdateURL;
@@ -38,6 +40,7 @@
         });
         addDueDate = function(isDropdown) {
           var data, date, mediumDate, value;
+          // Create the post date
           value = $("input[name='" + fieldName + "']").val();
           if (value !== '') {
             date = new Date(value.replace(new RegExp('-', 'g'), ','));
diff --git a/app/assets/javascripts/extensions/jquery.js b/app/assets/javascripts/extensions/jquery.js
index ae3dde63da382bfb6cb24695daeb34579f1c5c2f..4978e24949c2624b3d9d082b9e62a8598166c4eb 100644
--- a/app/assets/javascripts/extensions/jquery.js
+++ b/app/assets/javascripts/extensions/jquery.js
@@ -1,3 +1,4 @@
+// Disable an element and add the 'disabled' Bootstrap class
 (function() {
   $.fn.extend({
     disable: function() {
@@ -5,6 +6,7 @@
     }
   });
 
+  // Enable an element and remove the 'disabled' Bootstrap class
   $.fn.extend({
     enable: function() {
       return $(this).removeAttr('disabled').removeClass('disabled');
diff --git a/app/assets/javascripts/gfm_auto_complete.js.es6 b/app/assets/javascripts/gfm_auto_complete.js.es6
index 3dca06d36b1f9115f2352d515d7b4ff50301c001..d0786bf00531431ee6889c42c875a239aba2734b 100644
--- a/app/assets/javascripts/gfm_auto_complete.js.es6
+++ b/app/assets/javascripts/gfm_auto_complete.js.es6
@@ -1,3 +1,4 @@
+// Creates the variables for setting up GFM auto-completion
 (function() {
   if (window.GitLab == null) {
     window.GitLab = {};
@@ -8,18 +9,22 @@
     dataLoaded: false,
     cachedData: {},
     dataSource: '',
+    // Emoji
     Emoji: {
       template: '<li>${name} <img alt="${name}" height="20" src="${path}" width="20" /></li>'
     },
+    // Team Members
     Members: {
       template: '<li>${username} <small>${title}</small></li>'
     },
     Labels: {
       template: '<li><span class="dropdown-label-box" style="background: ${color}"></span> ${title}</li>'
     },
+    // Issues and MergeRequests
     Issues: {
       template: '<li><small>${id}</small> ${title}</li>'
     },
+    // Milestones
     Milestones: {
       template: '<li>${title}</li>'
     },
@@ -48,8 +53,11 @@
       }
     },
     setup: function(input) {
+      // Add GFM auto-completion to all input fields, that accept GFM input.
       this.input = input || $('.js-gfm-input');
+      // destroy previous instances
       this.destroyAtWho();
+      // set up instances
       this.setupAtWho();
       if (this.dataSource) {
         if (!this.dataLoading && !this.cachedData) {
@@ -63,6 +71,11 @@
                 return _this.loadData(data);
               });
             };
+          // We should wait until initializations are done
+          // and only trigger the last .setup since
+          // The previous .dataSource belongs to the previous issuable
+          // and the last one will have the **proper** .dataSource property
+          // TODO: Make this a singleton and turn off events when moving to another page
           })(this), 1000);
         }
         if (this.cachedData != null) {
@@ -71,6 +84,7 @@
       }
     },
     setupAtWho: function() {
+      // Emoji
       this.input.atwho({
         at: ':',
         displayTpl: (function(_this) {
@@ -90,6 +104,7 @@
           beforeInsert: this.DefaultOptions.beforeInsert
         }
       });
+      // Team Members
       this.input.atwho({
         at: '@',
         displayTpl: (function(_this) {
@@ -321,13 +336,22 @@
     loadData: function(data) {
       this.cachedData = data;
       this.dataLoaded = true;
+      // load members
       this.input.atwho('load', '@', data.members);
+      // load issues
       this.input.atwho('load', 'issues', data.issues);
+      // load milestones
       this.input.atwho('load', 'milestones', data.milestones);
+      // load merge requests
       this.input.atwho('load', 'mergerequests', data.mergerequests);
+      // load emojis
       this.input.atwho('load', ':', data.emojis);
+      // load labels
       this.input.atwho('load', '~', data.labels);
+      // load commands
       this.input.atwho('load', '/', data.commands);
+      // This trigger at.js again
+      // otherwise we would be stuck with loading until the user types
       return $(':focus').trigger('keyup');
     }
   };
diff --git a/app/assets/javascripts/gl_dropdown.js b/app/assets/javascripts/gl_dropdown.js
index 77b2082cba07e6fcead94cab49b169cdbf840e89..bea141bae5161c4ad16b90a22ead52e30401f454 100644
--- a/app/assets/javascripts/gl_dropdown.js
+++ b/app/assets/javascripts/gl_dropdown.js
@@ -21,12 +21,14 @@
       $clearButton = $inputContainer.find('.js-dropdown-input-clear');
       this.indeterminateIds = [];
       $clearButton.on('click', (function(_this) {
+        // Clear click
         return function(e) {
           e.preventDefault();
           e.stopPropagation();
           return _this.input.val('').trigger('keyup').focus();
         };
       })(this));
+      // Key events
       timeout = "";
       this.input
         .on('keydown', function (e) {
@@ -49,6 +51,7 @@
           if (keyCode === 13 && !options.elIsInput) {
             return false;
           }
+          // Only filter asynchronously only if option remote is set
           if (this.options.remote) {
             clearTimeout(timeout);
             return timeout = setTimeout(function() {
@@ -79,11 +82,27 @@
       if ((data != null) && !this.options.filterByText) {
         results = data;
         if (search_text !== '') {
+          // When data is an array of objects therefore [object Array] e.g.
+          // [
+          //   { prop: 'foo' },
+          //   { prop: 'baz' }
+          // ]
           if (_.isArray(data)) {
             results = fuzzaldrinPlus.filter(data, search_text, {
               key: this.options.keys
             });
           } else {
+            // If data is grouped therefore an [object Object]. e.g.
+            // {
+            //   groupName1: [
+            //     { prop: 'foo' },
+            //     { prop: 'baz' }
+            //   ],
+            //   groupName2: [
+            //     { prop: 'abc' },
+            //     { prop: 'def' }
+            //   ]
+            // }
             if (gl.utils.isObject(data)) {
               results = {};
               for (key in data) {
@@ -140,6 +159,7 @@
           this.options.beforeSend();
         }
         return this.dataEndpoint("", (function(_this) {
+          // Fetch the data by calling the data funcfion
           return function(data) {
             if (_this.options.success) {
               _this.options.success(data);
@@ -171,6 +191,7 @@
           };
         })(this)
       });
+    // Fetch the data through ajax if the data is a string
     };
 
     return GitLabDropdownRemote;
@@ -209,13 +230,18 @@
       self = this;
       selector = $(this.el).data("target");
       this.dropdown = selector != null ? $(selector) : $(this.el).parent();
+      // Set Defaults
       ref = this.options, this.filterInput = (ref1 = ref.filterInput) != null ? ref1 : this.getElement(FILTER_INPUT), this.highlight = (ref2 = ref.highlight) != null ? ref2 : false, this.filterInputBlur = (ref3 = ref.filterInputBlur) != null ? ref3 : true;
+      // If no input is passed create a default one
       self = this;
+      // If selector was passed
       if (_.isString(this.filterInput)) {
         this.filterInput = this.getElement(this.filterInput);
       }
       searchFields = this.options.search ? this.options.search.fields : [];
       if (this.options.data) {
+        // If we provided data
+        // data could be an array of objects or a group of arrays
         if (_.isObject(this.options.data) && !_.isFunction(this.options.data)) {
           this.fullData = this.options.data;
           currentIndex = -1;
@@ -232,10 +258,12 @@
                   return _this.filter.input.trigger('keyup');
                 }
               };
+            // Remote data
             })(this)
           });
         }
       }
+      // Init filterable
       if (this.options.filterable) {
         this.filter = new GitLabDropdownFilter(this.filterInput, {
           elIsInput: $(this.el).is('input'),
@@ -278,12 +306,14 @@
           })(this)
         });
       }
+      // Event listeners
       this.dropdown.on("shown.bs.dropdown", this.opened);
       this.dropdown.on("hidden.bs.dropdown", this.hidden);
       $(this.el).on("update.label", this.updateLabel);
       this.dropdown.on("click", ".dropdown-menu, .dropdown-menu-close", this.shouldPropagate);
       this.dropdown.on('keyup', (function(_this) {
         return function(e) {
+          // Escape key
           if (e.which === 27) {
             return $('.dropdown-menu-close', _this.dropdown).trigger('click');
           }
@@ -327,6 +357,7 @@
       }
     }
 
+    // Finds an element inside wrapper element
     GitLabDropdown.prototype.getElement = function(selector) {
       return this.dropdown.find(selector);
     };
@@ -344,6 +375,7 @@
         }
       }
       menu.toggleClass(PAGE_TWO_CLASS);
+      // Focus first visible input on active page
       return this.dropdown.find('[class^="dropdown-page-"]:visible :text:visible:first').focus();
     };
 
@@ -351,23 +383,28 @@
       var full_html, groupData, html, name;
       this.renderedData = data;
       if (this.options.filterable && data.length === 0) {
+        // render no matching results
         html = [this.noResults()];
       } else {
+        // Handle array groups
         if (gl.utils.isObject(data)) {
           html = [];
           for (name in data) {
             groupData = data[name];
             html.push(this.renderItem({
               header: name
+            // Add header for each group
             }, name));
             this.renderData(groupData, name).map(function(item) {
               return html.push(item);
             });
           }
         } else {
+          // Render each row
           html = this.renderData(data);
         }
       }
+      // Render the full menu
       full_html = this.renderMenu(html);
       return this.appendMenu(full_html);
     };
@@ -406,6 +443,7 @@
       if (this.options.setActiveIds) {
         this.options.setActiveIds.call(this);
       }
+      // Makes indeterminate items effective
       if (this.fullData && this.dropdown.find('.dropdown-menu-toggle').hasClass('js-filter-bulk-update')) {
         this.parseData(this.fullData);
       }
@@ -427,6 +465,8 @@
       if (this.options.filterable) {
         $input.blur().val("");
       }
+      // Triggering 'keyup' will re-render the dropdown which is not always required
+      // specially if we want to keep the state of the dropdown needed for bulk-assignment
       if (!this.options.persistWhenHide) {
         $input.trigger("keyup");
       }
@@ -439,6 +479,7 @@
       return this.dropdown.trigger('hidden.gl.dropdown');
     };
 
+    // Render the full menu
     GitLabDropdown.prototype.renderMenu = function(html) {
       var menu_html;
       menu_html = "";
@@ -450,6 +491,7 @@
       return menu_html;
     };
 
+    // Append the menu into the dropdown
     GitLabDropdown.prototype.appendMenu = function(html) {
       var selector;
       selector = '.dropdown-content';
@@ -465,19 +507,24 @@
         group = false;
       }
       if (index == null) {
+        // Render the row
         index = false;
       }
       html = "";
+      // Divider
       if (data === "divider") {
         return "<li class='divider'></li>";
       }
+      // Separator is a full-width divider
       if (data === "separator") {
         return "<li class='separator'></li>";
       }
+      // Header
       if (data.header != null) {
         return _.template('<li class="dropdown-header"><%- header %></li>')({ header: data.header });
       }
       if (this.options.renderRow) {
+        // Call the render function
         html = this.options.renderRow.call(this.options, data, this);
       } else {
         if (!selected) {
@@ -489,11 +536,13 @@
             selected = true;
           }
         }
+        // Set URL
         if (this.options.url != null) {
           url = this.options.url(data);
         } else {
           url = data.url != null ? data.url : '#';
         }
+        // Set Text
         if (this.options.text != null) {
           text = this.options.text(data);
         } else {
@@ -584,6 +633,7 @@
         if (value == null) {
           field.remove();
         }
+        // Toggle active class for the tick mark
         el.addClass(ACTIVE_CLASS);
         if (value != null) {
           if (!field.length && fieldName) {
@@ -604,6 +654,7 @@
 
     GitLabDropdown.prototype.addInput = function(fieldName, value, selectedObject) {
       var $input;
+      // Create hidden input for form
       $input = $('<input>').attr('type', 'hidden').attr('name', fieldName).val(value);
       if (this.options.inputId != null) {
         $input.attr('id', this.options.inputId);
@@ -625,6 +676,7 @@
       if (this.dropdown.find(".dropdown-toggle-page").length) {
         selector = ".dropdown-page-one " + selector;
       }
+      // simulate a click on the first link
       $el = $(selector, this.dropdown);
       if ($el.length) {
         var href = $el.attr('href');
@@ -653,11 +705,15 @@
             e.stopImmediatePropagation();
             PREV_INDEX = currentIndex;
             $listItems = $(selector, _this.dropdown);
+            // if @options.filterable
+            //   $input.blur()
             if (currentKeyCode === 40) {
+              // Move down
               if (currentIndex < ($listItems.length - 1)) {
                 currentIndex += 1;
               }
             } else if (currentKeyCode === 38) {
+              // Move up
               if (currentIndex > 0) {
                 currentIndex -= 1;
               }
@@ -685,24 +741,32 @@
 
     GitLabDropdown.prototype.highlightRowAtIndex = function($listItems, index) {
       var $dropdownContent, $listItem, dropdownContentBottom, dropdownContentHeight, dropdownContentTop, dropdownScrollTop, listItemBottom, listItemHeight, listItemTop;
+      // Remove the class for the previously focused row
       $('.is-focused', this.dropdown).removeClass('is-focused');
+      // Update the class for the row at the specific index
       $listItem = $listItems.eq(index);
       $listItem.find('a:first-child').addClass("is-focused");
+      // Dropdown content scroll area
       $dropdownContent = $listItem.closest('.dropdown-content');
       dropdownScrollTop = $dropdownContent.scrollTop();
       dropdownContentHeight = $dropdownContent.outerHeight();
       dropdownContentTop = $dropdownContent.prop('offsetTop');
       dropdownContentBottom = dropdownContentTop + dropdownContentHeight;
+      // Get the offset bottom of the list item
       listItemHeight = $listItem.outerHeight();
       listItemTop = $listItem.prop('offsetTop');
       listItemBottom = listItemTop + listItemHeight;
       if (!index) {
+        // Scroll the dropdown content to the top
         $dropdownContent.scrollTop(0)
       } else if (index === ($listItems.length - 1)) {
+        // Scroll the dropdown content to the bottom
         $dropdownContent.scrollTop($dropdownContent.prop('scrollHeight'));
       } else if (listItemBottom > (dropdownContentBottom + dropdownScrollTop)) {
+        // Scroll the dropdown content down
         $dropdownContent.scrollTop(listItemBottom - dropdownContentBottom + CURSOR_SELECT_SCROLL_PADDING);
       } else if (listItemTop < (dropdownContentTop + dropdownScrollTop)) {
+        // Scroll the dropdown content up
         return $dropdownContent.scrollTop(listItemTop - dropdownContentTop - CURSOR_SELECT_SCROLL_PADDING);
       }
     };
diff --git a/app/assets/javascripts/gl_form.js b/app/assets/javascripts/gl_form.js
index 528a673eb15c07a341806fd35d1ca9452a953b52..2703adc07052cb2da0eee652fd6289f9e834126f 100644
--- a/app/assets/javascripts/gl_form.js
+++ b/app/assets/javascripts/gl_form.js
@@ -3,12 +3,15 @@
     function GLForm(form) {
       this.form = form;
       this.textarea = this.form.find('textarea.js-gfm-input');
+      // Before we start, we should clean up any previous data for this form
       this.destroy();
+      // Setup the form
       this.setupForm();
       this.form.data('gl-form', this);
     }
 
     GLForm.prototype.destroy = function() {
+      // Clean form listeners
       this.clearEventListeners();
       return this.form.data('gl-form', null);
     };
@@ -21,12 +24,15 @@
         this.form.find('.div-dropzone').remove();
         this.form.addClass('gfm-form');
         disableButtonIfEmptyField(this.form.find('.js-note-text'), this.form.find('.js-comment-button'));
+        // remove notify commit author checkbox for non-commit notes
         GitLab.GfmAutoComplete.setup(this.form.find('.js-gfm-input'));
         new DropzoneInput(this.form);
         autosize(this.textarea);
+        // form and textarea event listeners
         this.addEventListeners();
         gl.text.init(this.form);
       }
+      // hide discard button
       this.form.find('.js-note-discard').hide();
       return this.form.show();
     };
diff --git a/app/assets/javascripts/graphs/graphs_bundle.js b/app/assets/javascripts/graphs/graphs_bundle.js
index b95faadc8e72f17e7cdb90eab9203622916bee02..4886da9f21fa479cfd1d59adfce3ead9924b6d2c 100644
--- a/app/assets/javascripts/graphs/graphs_bundle.js
+++ b/app/assets/javascripts/graphs/graphs_bundle.js
@@ -1,7 +1,11 @@
-
+// This is a manifest file that'll be compiled into including all the files listed below.
+// Add new JavaScript/Coffee code in separate files in this directory and they'll automatically
+// be included in the compiled file accessible from http://example.com/assets/application.js
+// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
+// the compiled file.
+//
 /*= require_tree . */
 
 (function() {
 
-
 }).call(this);
diff --git a/app/assets/javascripts/graphs/stat_graph_contributors_graph.js b/app/assets/javascripts/graphs/stat_graph_contributors_graph.js
index a646ca1d84f00fb45ee004bd060adc960c9c7be8..7d9d4d7c679c17a17abd38f407d1ce8b1c166175 100644
--- a/app/assets/javascripts/graphs/stat_graph_contributors_graph.js
+++ b/app/assets/javascripts/graphs/stat_graph_contributors_graph.js
@@ -204,6 +204,7 @@
 
     function ContributorsAuthorGraph(data1) {
       this.data = data1;
+      // Don't split graph size in half for mobile devices.
       if ($(window).width() < 768) {
         this.width = $('.content').width() - 80;
       } else {
diff --git a/app/assets/javascripts/groups_select.js b/app/assets/javascripts/groups_select.js
index fd5b6dc0ddd405ff5ee3a9076ec9cb5b95de803f..7c2eebcdd44e8b674964cc20cfa5f96d37fc4376 100644
--- a/app/assets/javascripts/groups_select.js
+++ b/app/assets/javascripts/groups_select.js
@@ -38,6 +38,7 @@
               return _this.formatSelection.apply(_this, args);
             },
             dropdownCssClass: "ajax-groups-dropdown",
+            // we do not want to escape markup since we are displaying html in results
             escapeMarkup: function(m) {
               return m;
             }
diff --git a/app/assets/javascripts/issuable.js.es6 b/app/assets/javascripts/issuable.js.es6
index 82c14ef0157b44559184afc97d150e1becf86461..53faaa38a0cf99ba1af5bfbd8dcd397947dd1147 100644
--- a/app/assets/javascripts/issuable.js.es6
+++ b/app/assets/javascripts/issuable.js.es6
@@ -38,9 +38,11 @@
       return $(document).off('click', '.js-label-filter-remove').on('click', '.js-label-filter-remove', function(e) {
         var $button;
         $button = $(this);
+        // Remove the label input box
         $('input[name="label_name[]"]').filter(function() {
           return this.value === $button.data('label');
         }).remove();
+        // Submit the form to get new data
         Issuable.filterResults($('.filter-form'));
         return $('.js-label-select').trigger('update.label');
       });
diff --git a/app/assets/javascripts/issue.js b/app/assets/javascripts/issue.js
index e6422602ce811df735af174dd53a6a009268ffcf..261bf6137c2a326620020e8d1c92ade6db57eccd 100644
--- a/app/assets/javascripts/issue.js
+++ b/app/assets/javascripts/issue.js
@@ -1,10 +1,6 @@
 
 /*= require flash */
-
-
 /*= require jquery.waitforimages */
-
-
 /*= require task_list */
 
 (function() {
@@ -13,6 +9,7 @@
   this.Issue = (function() {
     function Issue() {
       this.submitNoteForm = bind(this.submitNoteForm, this);
+      // Prevent duplicate event bindings
       this.disableTaskList();
       if ($('a.btn-close').length) {
         this.initTaskList();
@@ -99,6 +96,8 @@
         url: $('form.js-issuable-update').attr('action'),
         data: patchData
       });
+    // TODO (rspeicher): Make the issue description inline-editable like a note so
+    // that we can re-use its form here
     };
 
     Issue.prototype.initMergeRequests = function() {
@@ -128,6 +127,8 @@
     Issue.prototype.initCanCreateBranch = function() {
       var $container;
       $container = $('#new-branch');
+      // If the user doesn't have the required permissions the container isn't
+      // rendered at all.
       if ($container.length === 0) {
         return;
       }
diff --git a/app/assets/javascripts/issues-bulk-assignment.js b/app/assets/javascripts/issues-bulk-assignment.js
index 8ca904904262e1b49585c986639e9993f107ad45..62a7fc9a06c6d0b2d546ef84450dab7c2957f469 100644
--- a/app/assets/javascripts/issues-bulk-assignment.js
+++ b/app/assets/javascripts/issues-bulk-assignment.js
@@ -1,14 +1,17 @@
 (function() {
   this.IssuableBulkActions = (function() {
     function IssuableBulkActions(opts) {
+      // Set defaults
       var ref, ref1, ref2;
       if (opts == null) {
         opts = {};
       }
       this.container = (ref = opts.container) != null ? ref : $('.content'), this.form = (ref1 = opts.form) != null ? ref1 : this.getElement('.bulk-update'), this.issues = (ref2 = opts.issues) != null ? ref2 : this.getElement('.issuable-list > li');
+      // Save instance
       this.form.data('bulkActions', this);
       this.willUpdateLabels = false;
       this.bindEvents();
+      // Fixes bulk-assign not working when navigating through pages
       Issuable.initChecks();
     }
 
@@ -86,6 +89,7 @@
       ref1 = this.getLabelsFromSelection();
       for (j = 0, len1 = ref1.length; j < len1; j++) {
         id = ref1[j];
+        // Only the ones that we are not going to keep
         if (labelsToKeep.indexOf(id) === -1) {
           result.push(id);
         }
@@ -147,6 +151,8 @@
       indeterminatedLabels = this.getUnmarkedIndeterminedLabels();
       labelsToApply = this.getLabelsToApply();
       indeterminatedLabels.map(function(id) {
+        // We need to exclude label IDs that will be applied
+        // By not doing this will cause issues from selection to not add labels at all
         if (labelsToApply.indexOf(id) === -1) {
           return result.push(id);
         }
diff --git a/app/assets/javascripts/labels.js b/app/assets/javascripts/labels.js
index fe071fca67ca4396c312976be004e4e87cd875a5..cb16e2ba81444c03dac6bae555150518da78d5ae 100644
--- a/app/assets/javascripts/labels.js
+++ b/app/assets/javascripts/labels.js
@@ -26,13 +26,16 @@
       var previewColor;
       previewColor = $('input#label_color').val();
       return $('div.label-color-preview').css('background-color', previewColor);
+    // Updates the the preview color with the hex-color input
     };
 
+    // Updates the preview color with a click on a suggested color
     Labels.prototype.setSuggestedColor = function(e) {
       var color;
       color = $(e.currentTarget).data('color');
       $('input#label_color').val(color);
       this.updateColorPreview();
+      // Notify the form, that color has changed
       $('.label-form').trigger('keyup');
       return e.preventDefault();
     };
diff --git a/app/assets/javascripts/labels_select.js b/app/assets/javascripts/labels_select.js
index bab23ff5ac04ffbc32d5093f0584b8eaa48913a7..29a967a35a0d2926e1257c60dbe3a9ecc59b0149 100644
--- a/app/assets/javascripts/labels_select.js
+++ b/app/assets/javascripts/labels_select.js
@@ -156,11 +156,13 @@
                 selectedClass.push('is-indeterminate');
               }
               if (active.indexOf(label.id) !== -1) {
+                // Remove is-indeterminate class if the item will be marked as active
                 i = selectedClass.indexOf('is-indeterminate');
                 if (i !== -1) {
                   selectedClass.splice(i, 1);
                 }
                 selectedClass.push('is-active');
+                // Add input manually
                 instance.addInput(this.fieldName, label.id);
               }
             }
@@ -172,6 +174,7 @@
             }
             if (label.duplicate) {
               spacing = 100 / label.color.length;
+              // Reduce the colors to 4
               label.color = label.color.filter(function(color, i) {
                 return i < 4;
               });
@@ -192,11 +195,13 @@
             } else {
               colorEl = '';
             }
+            // We need to identify which items are actually labels
             if (label.id) {
               selectedClass.push('label-item');
               $a.attr('data-label-id', label.id);
             }
             $a.addClass(selectedClass.join(' ')).html(colorEl + " " + label.title);
+            // Return generated html
             return $li.html($a).prop('outerHTML');
           },
           persistWhenHide: $dropdown.data('persistWhenHide'),
@@ -238,6 +243,7 @@
             isIssueIndex = page === 'projects:issues:index';
             isMRIndex = page === 'projects:merge_requests:index';
             $selectbox.hide();
+            // display:block overrides the hide-collapse rule
             $value.removeAttr('style');
             if (page === 'projects:boards:show') {
               return;
@@ -255,6 +261,7 @@
               }
             }
             if ($dropdown.hasClass('js-filter-bulk-update')) {
+              // If we are persisting state we need the classes
               if (!this.options.persistWhenHide) {
                 return $dropdown.parent().find('.is-active, .is-indeterminate').removeClass();
               }
@@ -324,7 +331,9 @@
       if ($('.selected_issue:checked').length) {
         return;
       }
+      // Remove inputs
       $('.issues_bulk_update .labels-filter input[type="hidden"]').remove();
+      // Also restore button text
       return $('.issues_bulk_update .labels-filter .dropdown-toggle-text').text('Label');
     };
 
diff --git a/app/assets/javascripts/lib/chart.js b/app/assets/javascripts/lib/chart.js
index 8d5e52286b7be5206cb7936ae77d5019d113b5c2..d9b07c10a49bcec7b32b5f5778c48532204c6561 100644
--- a/app/assets/javascripts/lib/chart.js
+++ b/app/assets/javascripts/lib/chart.js
@@ -3,5 +3,4 @@
 
 (function() {
 
-
 }).call(this);
diff --git a/app/assets/javascripts/lib/cropper.js b/app/assets/javascripts/lib/cropper.js
index 8ee81804513b831003744d9a772cd7849e029dc9..a88e640f298ceb424f38adda00b2e95c3615096e 100644
--- a/app/assets/javascripts/lib/cropper.js
+++ b/app/assets/javascripts/lib/cropper.js
@@ -3,5 +3,4 @@
 
 (function() {
 
-
 }).call(this);
diff --git a/app/assets/javascripts/lib/d3.js b/app/assets/javascripts/lib/d3.js
index 31e6033e75666a5a8f8844f9ebbbb0e6cdde88a1..ee1baf5480394633a30f3c419395643bdc02f353 100644
--- a/app/assets/javascripts/lib/d3.js
+++ b/app/assets/javascripts/lib/d3.js
@@ -3,5 +3,4 @@
 
 (function() {
 
-
 }).call(this);
diff --git a/app/assets/javascripts/lib/raphael.js b/app/assets/javascripts/lib/raphael.js
index 923c575dcfe637946f7344a714029775ad98f9d5..6df427bc2b1b31dc2cfa3409e601ed5c1b497210 100644
--- a/app/assets/javascripts/lib/raphael.js
+++ b/app/assets/javascripts/lib/raphael.js
@@ -1,13 +1,8 @@
 
 /*= require raphael */
-
-
 /*= require g.raphael */
-
-
 /*= require g.bar */
 
 (function() {
 
-
 }).call(this);
diff --git a/app/assets/javascripts/lib/utils/datetime_utility.js b/app/assets/javascripts/lib/utils/datetime_utility.js
index d4d5927d3b03e7abfed017f1bdb941210f7f2d24..8fdf4646cd8e7ba8e24db50cc959ae6986e8807d 100644
--- a/app/assets/javascripts/lib/utils/datetime_utility.js
+++ b/app/assets/javascripts/lib/utils/datetime_utility.js
@@ -29,6 +29,7 @@
       if (setTimeago) {
         $timeagoEls.timeago();
         $timeagoEls.tooltip('destroy');
+        // Recreate with custom template
         return $timeagoEls.tooltip({
           template: '<div class="tooltip local-timeago" role="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>'
         });
diff --git a/app/assets/javascripts/lib/utils/emoji_aliases.js.coffee.erb b/app/assets/javascripts/lib/utils/emoji_aliases.js.coffee.erb
deleted file mode 100644
index 80f9936b9c2039ee8e1625128ad862e26d8847e0..0000000000000000000000000000000000000000
--- a/app/assets/javascripts/lib/utils/emoji_aliases.js.coffee.erb
+++ /dev/null
@@ -1,2 +0,0 @@
-gl.emojiAliases = ->
-  JSON.parse('<%= Gitlab::AwardEmoji.aliases.to_json %>')
diff --git a/app/assets/javascripts/lib/utils/emoji_aliases.js.erb b/app/assets/javascripts/lib/utils/emoji_aliases.js.erb
new file mode 100644
index 0000000000000000000000000000000000000000..aeb86c9fa5bc7758a85242bb7fd2242a6ac02b26
--- /dev/null
+++ b/app/assets/javascripts/lib/utils/emoji_aliases.js.erb
@@ -0,0 +1,6 @@
+(function() {
+  gl.emojiAliases = function() {
+    return JSON.parse('<%= Gitlab::AwardEmoji.aliases.to_json %>');
+  };
+
+}).call(this);
diff --git a/app/assets/javascripts/lib/utils/notify.js b/app/assets/javascripts/lib/utils/notify.js
index 42b6ac0589ed3ac8361dee2a34be4e80f62b3516..5b338b00d76a44f00796289954b88a2a840f3999 100644
--- a/app/assets/javascripts/lib/utils/notify.js
+++ b/app/assets/javascripts/lib/utils/notify.js
@@ -6,6 +6,7 @@
       notification = new Notification(message, opts);
       setTimeout(function() {
         return notification.close();
+      // Hide the notification after X amount of seconds
       }, 8000);
       if (onclick) {
         return notification.onclick = onclick;
@@ -22,12 +23,16 @@
         body: body,
         icon: icon
       };
+      // Let's check if the browser supports notifications
       if (!('Notification' in window)) {
 
+      // do nothing
       } else if (Notification.permission === 'granted') {
+        // If it's okay let's create a notification
         return notificationGranted(message, opts, onclick);
       } else if (Notification.permission !== 'denied') {
         return Notification.requestPermission(function(permission) {
+          // If the user accepts, let's create a notification
           if (permission === 'granted') {
             return notificationGranted(message, opts, onclick);
           }
diff --git a/app/assets/javascripts/lib/utils/text_utility.js b/app/assets/javascripts/lib/utils/text_utility.js
index b6636de57670329772e56601c6ef9d73a916e18d..d761a844be96ae3d9e9a10224a86d5d9b58f8450 100644
--- a/app/assets/javascripts/lib/utils/text_utility.js
+++ b/app/assets/javascripts/lib/utils/text_utility.js
@@ -29,6 +29,7 @@
       lineBefore = this.lineBefore(text, textArea);
       lineAfter = this.lineAfter(text, textArea);
       if (lineBefore === blockTag && lineAfter === blockTag) {
+        // To remove the block tag we have to select the line before & after
         if (blockTag != null) {
           textArea.selectionStart = textArea.selectionStart - (blockTag.length + 1);
           textArea.selectionEnd = textArea.selectionEnd + (blockTag.length + 1);
@@ -63,11 +64,11 @@
       if (!inserted) {
         try {
           document.execCommand("ms-beginUndoUnit");
-        } catch (undefined) {}
+        } catch (error) {}
         textArea.value = this.replaceRange(text, textArea.selectionStart, textArea.selectionEnd, insertText);
         try {
           document.execCommand("ms-endUndoUnit");
-        } catch (undefined) {}
+        } catch (error) {}
       }
       return this.moveCursor(textArea, tag, wrap);
     };
diff --git a/app/assets/javascripts/lib/utils/url_utility.js b/app/assets/javascripts/lib/utils/url_utility.js
index 533310cc87c22d88a863663d13698f1a64c1ef42..f84a20cf0feb884f03c76a2e7804d5803e6593c8 100644
--- a/app/assets/javascripts/lib/utils/url_utility.js
+++ b/app/assets/javascripts/lib/utils/url_utility.js
@@ -7,6 +7,8 @@
     if ((base = w.gl).utils == null) {
       base.utils = {};
     }
+    // Returns an array containing the value(s) of the
+    // of the key passed as an argument
     w.gl.utils.getParameterValues = function(sParam) {
       var i, sPageURL, sParameterName, sURLVariables, values;
       sPageURL = decodeURIComponent(window.location.search.substring(1));
@@ -23,6 +25,8 @@
       }
       return values;
     };
+    // @param {Object} params - url keys and value to merge
+    // @param {String} url
     w.gl.utils.mergeUrlParams = function(params, url) {
       var lastChar, newUrl, paramName, paramValue, pattern;
       newUrl = decodeURIComponent(url);
@@ -37,12 +41,14 @@
           newUrl = "" + newUrl + (newUrl.indexOf('?') > 0 ? '&' : '?') + paramName + "=" + paramValue;
         }
       }
+      // Remove a trailing ampersand
       lastChar = newUrl[newUrl.length - 1];
       if (lastChar === '&') {
         newUrl = newUrl.slice(0, -1);
       }
       return newUrl;
     };
+    // removes parameter query string from url. returns the modified url
     w.gl.utils.removeParamQueryString = function(url, param) {
       var urlVariables, variables;
       url = decodeURIComponent(url);
diff --git a/app/assets/javascripts/line_highlighter.js b/app/assets/javascripts/line_highlighter.js
index f145bd3ad74a4658b25a34a12409930d844ada8d..93daea1dce790e93a2760a598a9ef5c50065df18 100644
--- a/app/assets/javascripts/line_highlighter.js
+++ b/app/assets/javascripts/line_highlighter.js
@@ -1,17 +1,49 @@
-
+// LineHighlighter
+//
+// Handles single- and multi-line selection and highlight for blob views.
+//
 /*= require jquery.scrollTo */
 
+//
+// ### Example Markup
+//
+//   <div id="blob-content-holder">
+//     <div class="file-content">
+//       <div class="line-numbers">
+//         <a href="#L1" id="L1" data-line-number="1">1</a>
+//         <a href="#L2" id="L2" data-line-number="2">2</a>
+//         <a href="#L3" id="L3" data-line-number="3">3</a>
+//         <a href="#L4" id="L4" data-line-number="4">4</a>
+//         <a href="#L5" id="L5" data-line-number="5">5</a>
+//       </div>
+//       <pre class="code highlight">
+//         <code>
+//           <span id="LC1" class="line">...</span>
+//           <span id="LC2" class="line">...</span>
+//           <span id="LC3" class="line">...</span>
+//           <span id="LC4" class="line">...</span>
+//           <span id="LC5" class="line">...</span>
+//         </code>
+//       </pre>
+//     </div>
+//   </div>
+//
 (function() {
   var bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
 
   this.LineHighlighter = (function() {
+    // CSS class applied to highlighted lines
     LineHighlighter.prototype.highlightClass = 'hll';
 
+    // Internal copy of location.hash so we're not dependent on `location` in tests
     LineHighlighter.prototype._hash = '';
 
     function LineHighlighter(hash) {
       var range;
       if (hash == null) {
+        // Initialize a LineHighlighter object
+        //
+        // hash - String URL hash for dependency injection in tests
         hash = location.hash;
       }
       this.setHash = bind(this.setHash, this);
@@ -24,6 +56,8 @@
         if (range[0]) {
           this.highlightRange(range);
           $.scrollTo("#L" + range[0], {
+            // Scroll to the first highlighted line on initial load
+            // Offset -50 for the sticky top bar, and another -100 for some context
             offset: -150
           });
         }
@@ -32,6 +66,12 @@
 
     LineHighlighter.prototype.bindEvents = function() {
       $('#blob-content-holder').on('mousedown', 'a[data-line-number]', this.clickHandler);
+      // While it may seem odd to bind to the mousedown event and then throw away
+      // the click event, there is a method to our madness.
+      //
+      // If not done this way, the line number anchor will sometimes keep its
+      // active state even when the event is cancelled, resulting in an ugly border
+      // around the link and/or a persisted underline text decoration.
       return $('#blob-content-holder').on('click', 'a[data-line-number]', function(event) {
         return event.preventDefault();
       });
@@ -44,6 +84,8 @@
       lineNumber = $(event.target).closest('a').data('line-number');
       current = this.hashToRange(this._hash);
       if (!(current[0] && event.shiftKey)) {
+        // If there's no current selection, or there is but Shift wasn't held,
+        // treat this like a single-line selection.
         this.setHash(lineNumber);
         return this.highlightLine(lineNumber);
       } else if (event.shiftKey) {
@@ -59,10 +101,23 @@
 
     LineHighlighter.prototype.clearHighlight = function() {
       return $("." + this.highlightClass).removeClass(this.highlightClass);
+    // Unhighlight previously highlighted lines
     };
 
+    // Convert a URL hash String into line numbers
+    //
+    // hash - Hash String
+    //
+    // Examples:
+    //
+    //   hashToRange('#L5')    # => [5, null]
+    //   hashToRange('#L5-15') # => [5, 15]
+    //   hashToRange('#foo')   # => [null, null]
+    //
+    // Returns an Array
     LineHighlighter.prototype.hashToRange = function(hash) {
       var first, last, matches;
+      //?L(\d+)(?:-(\d+))?$/)
       matches = hash.match(/^#?L(\d+)(?:-(\d+))?$/);
       if (matches && matches.length) {
         first = parseInt(matches[1]);
@@ -73,10 +128,16 @@
       }
     };
 
+    // Highlight a single line
+    //
+    // lineNumber - Line number to highlight
     LineHighlighter.prototype.highlightLine = function(lineNumber) {
       return $("#LC" + lineNumber).addClass(this.highlightClass);
     };
 
+    // Highlight all lines within a range
+    //
+    // range - Array containing the starting and ending line numbers
     LineHighlighter.prototype.highlightRange = function(range) {
       var i, lineNumber, ref, ref1, results;
       if (range[1]) {
@@ -90,6 +151,7 @@
       }
     };
 
+    // Set the URL hash string
     LineHighlighter.prototype.setHash = function(firstLineNumber, lastLineNumber) {
       var hash;
       if (lastLineNumber) {
@@ -101,10 +163,15 @@
       return this.__setLocationHash__(hash);
     };
 
+    // Make the actual hash change in the browser
+    //
+    // This method is stubbed in tests.
     LineHighlighter.prototype.__setLocationHash__ = function(value) {
       return history.pushState({
         turbolinks: false,
         url: value
+      // We're using pushState instead of assigning location.hash directly to
+      // prevent the page from scrolling on the hashchange event
       }, document.title, value);
     };
 
diff --git a/app/assets/javascripts/merge_request.js b/app/assets/javascripts/merge_request.js
index 56ebf84c4f6d0484fd808a93ab090716dabc4e90..05644b3d03c5ccfcd849d891124dda58426223e0 100644
--- a/app/assets/javascripts/merge_request.js
+++ b/app/assets/javascripts/merge_request.js
@@ -1,10 +1,6 @@
 
 /*= require jquery.waitforimages */
-
-
 /*= require task_list */
-
-
 /*= require merge_request_tabs */
 
 (function() {
@@ -12,6 +8,11 @@
 
   this.MergeRequest = (function() {
     function MergeRequest(opts) {
+      // Initialize MergeRequest behavior
+      //
+      // Options:
+      //   action - String, current controller action
+      //
       this.opts = opts != null ? opts : {};
       this.submitNoteForm = bind(this.submitNoteForm, this);
       this.$el = $('.merge-request');
@@ -21,6 +22,7 @@
         };
       })(this));
       this.initTabs();
+      // Prevent duplicate event bindings
       this.disableTaskList();
       this.initMRBtnListeners();
       if ($("a.btn-close").length) {
@@ -28,14 +30,17 @@
       }
     }
 
+    // Local jQuery finder
     MergeRequest.prototype.$ = function(selector) {
       return this.$el.find(selector);
     };
 
     MergeRequest.prototype.initTabs = function() {
       if (this.opts.action !== 'new') {
+        // `MergeRequests#new` has no tab-persisting or lazy-loading behavior
         window.mrTabs = new MergeRequestTabs(this.opts);
       } else {
+        // Show the first tab (Commits)
         return $('.merge-request-tabs a[data-toggle="tab"]:first').tab('show');
       }
     };
@@ -96,6 +101,8 @@
         url: $('form.js-issuable-update').attr('action'),
         data: patchData
       });
+    // TODO (rspeicher): Make the merge request description inline-editable like a
+    // note so that we can re-use its form here
     };
 
     return MergeRequest;
diff --git a/app/assets/javascripts/merge_request_tabs.js b/app/assets/javascripts/merge_request_tabs.js
index ad08209d61e55f598b2019c4fbc6b11da707848a..dcba4a8d27561df78b42892cab48af20a11d171f 100644
--- a/app/assets/javascripts/merge_request_tabs.js
+++ b/app/assets/javascripts/merge_request_tabs.js
@@ -1,6 +1,49 @@
-
+// MergeRequestTabs
+//
+// Handles persisting and restoring the current tab selection and lazily-loading
+// content on the MergeRequests#show page.
+//
 /*= require jquery.cookie */
 
+//
+// ### Example Markup
+//
+//   <ul class="nav-links merge-request-tabs">
+//     <li class="notes-tab active">
+//       <a data-action="notes" data-target="#notes" data-toggle="tab" href="/foo/bar/merge_requests/1">
+//         Discussion
+//       </a>
+//     </li>
+//     <li class="commits-tab">
+//       <a data-action="commits" data-target="#commits" data-toggle="tab" href="/foo/bar/merge_requests/1/commits">
+//         Commits
+//       </a>
+//     </li>
+//     <li class="diffs-tab">
+//       <a data-action="diffs" data-target="#diffs" data-toggle="tab" href="/foo/bar/merge_requests/1/diffs">
+//         Diffs
+//       </a>
+//     </li>
+//   </ul>
+//
+//   <div class="tab-content">
+//     <div class="notes tab-pane active" id="notes">
+//       Notes Content
+//     </div>
+//     <div class="commits tab-pane" id="commits">
+//       Commits Content
+//     </div>
+//     <div class="diffs tab-pane" id="diffs">
+//       Diffs Content
+//     </div>
+//   </div>
+//
+//   <div class="mr-loading-status">
+//     <div class="loading">
+//       Loading Animation
+//     </div>
+//   </div>
+//
 (function() {
   var bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
 
@@ -19,6 +62,7 @@
       this.setCurrentAction = bind(this.setCurrentAction, this);
       this.tabShown = bind(this.tabShown, this);
       this.showTab = bind(this.showTab, this);
+      // Store the `location` object, allowing for easier stubbing in tests
       this._location = location;
       this.bindEvents();
       this.activateTab(this.opts.action);
@@ -77,6 +121,7 @@
       }
     };
 
+    // Activate a tab based on the current action
     MergeRequestTabs.prototype.activateTab = function(action) {
       if (action === 'show') {
         action = 'notes';
@@ -84,20 +129,48 @@
       return $(".merge-request-tabs a[data-action='" + action + "']").tab('show');
     };
 
+    // Replaces the current Merge Request-specific action in the URL with a new one
+    //
+    // If the action is "notes", the URL is reset to the standard
+    // `MergeRequests#show` route.
+    //
+    // Examples:
+    //
+    //   location.pathname # => "/namespace/project/merge_requests/1"
+    //   setCurrentAction('diffs')
+    //   location.pathname # => "/namespace/project/merge_requests/1/diffs"
+    //
+    //   location.pathname # => "/namespace/project/merge_requests/1/diffs"
+    //   setCurrentAction('notes')
+    //   location.pathname # => "/namespace/project/merge_requests/1"
+    //
+    //   location.pathname # => "/namespace/project/merge_requests/1/diffs"
+    //   setCurrentAction('commits')
+    //   location.pathname # => "/namespace/project/merge_requests/1/commits"
+    //
+    // Returns the new URL String
     MergeRequestTabs.prototype.setCurrentAction = function(action) {
       var new_state;
+      // Normalize action, just to be safe
       if (action === 'show') {
         action = 'notes';
       }
       this.currentAction = action;
+      // Remove a trailing '/commits' or '/diffs'
       new_state = this._location.pathname.replace(/\/(commits|diffs|builds|pipelines)(\.html)?\/?$/, '');
+      // Append the new action if we're on a tab other than 'notes'
       if (action !== 'notes') {
         new_state += "/" + action;
       }
+      // Ensure parameters and hash come along for the ride
       new_state += this._location.search + this._location.hash;
       history.replaceState({
         turbolinks: true,
         url: new_state
+      // Replace the current history state with the new one without breaking
+      // Turbolinks' history.
+      //
+      // See https://github.com/rails/turbolinks/issues/363
       }, document.title, new_state);
       return new_state;
     };
@@ -206,6 +279,9 @@
       });
     };
 
+    // Show or hide the loading spinner
+    //
+    // status - Boolean, true to show, false to hide
     MergeRequestTabs.prototype.toggleLoading = function(status) {
       return $('.mr-loading-status .loading').toggle(status);
     };
@@ -232,6 +308,7 @@
 
     MergeRequestTabs.prototype.diffViewType = function() {
       return $('.inline-parallel-buttons a.active').data('view-type');
+    // Returns diff view type
     };
 
     MergeRequestTabs.prototype.expandViewContainer = function() {
@@ -245,6 +322,8 @@
         if ($gutterIcon.is('.fa-angle-double-right')) {
           return $gutterIcon.closest('a').trigger('click', [true]);
         }
+      // Wait until listeners are set
+      // Only when sidebar is expanded
       }, 0);
     };
 
@@ -259,6 +338,9 @@
           return $gutterIcon.closest('a').trigger('click', [true]);
         }
       }, 0);
+    // Expand the issuable sidebar unless the user explicitly collapsed it
+    // Wait until listeners are set
+    // Only when sidebar is collapsed
     };
 
     return MergeRequestTabs;
diff --git a/app/assets/javascripts/merge_request_widget.js b/app/assets/javascripts/merge_request_widget.js
index bd35b6f679d18db622510b9a3c354b261e6b1c6d..7bbcdf5983880534e8362abdf65ec7e327b6fcd2 100644
--- a/app/assets/javascripts/merge_request_widget.js
+++ b/app/assets/javascripts/merge_request_widget.js
@@ -3,6 +3,12 @@
 
   this.MergeRequestWidget = (function() {
     function MergeRequestWidget(opts) {
+      // Initialize MergeRequestWidget behavior
+      //
+      //   check_enable           - Boolean, whether to check automerge status
+      //   merge_check_url - String, URL to use to check automerge status
+      //   ci_status_url        - String, URL to use to check CI status
+      //
       this.opts = opts;
       $('#modal_merge_info').modal({
         show: false
@@ -118,6 +124,8 @@
             if (data.coverage) {
               _this.showCICoverage(data.coverage);
             }
+            // The first check should only update the UI, a notification
+            // should only be displayed on status changes
             if (showNotification && !_this.firstCICheck) {
               status = _this.ciLabelForStatus(data.status);
               if (status === "preparing") {
diff --git a/app/assets/javascripts/milestone.js b/app/assets/javascripts/milestone.js
index e8d51da7d5829ae07bf60c1a0f824df5d0e50b3b..bc1a99057d9820c8e7c0c89bff2409cc8afd329a 100644
--- a/app/assets/javascripts/milestone.js
+++ b/app/assets/javascripts/milestone.js
@@ -110,6 +110,7 @@
         },
         update: function(event, ui) {
           var data;
+          // Prevents sorting from container which element has been removed.
           if ($(this).find(ui.item).length > 0) {
             data = $(this).sortable("serialize");
             return Milestone.sortIssues(data);
diff --git a/app/assets/javascripts/milestone_select.js b/app/assets/javascripts/milestone_select.js
index e897ebdf6304bcdc337fae6d2a60c4d6f3ff779d..c8031174dd21733aa9dc3e78bbf6778a02b121e5 100644
--- a/app/assets/javascripts/milestone_select.js
+++ b/app/assets/javascripts/milestone_select.js
@@ -92,6 +92,7 @@
           },
           hidden: function() {
             $selectbox.hide();
+            // display:block overrides the hide-collapse rule
             return $value.css('display', '');
           },
           clicked: function(selected, $el, e) {
diff --git a/app/assets/javascripts/network/branch-graph.js b/app/assets/javascripts/network/branch-graph.js
index c0fec1f860773b4cb42a9019307b31a6cbfe4963..91132af273a32bd04d096bfc29cb2226ef15e2f0 100644
--- a/app/assets/javascripts/network/branch-graph.js
+++ b/app/assets/javascripts/network/branch-graph.js
@@ -90,6 +90,7 @@
       results = [];
       while (k < this.mspace) {
         this.colors.push(Raphael.getColor(.8));
+        // Skipping a few colors in the spectrum to get more contrast between colors
         Raphael.getColor();
         Raphael.getColor();
         results.push(k++);
@@ -112,6 +113,7 @@
       for (mm = j = 0, len = ref.length; j < len; mm = ++j) {
         day = ref[mm];
         if (cuday !== day[0] || cumonth !== day[1]) {
+          // Dates
           r.text(55, this.offsetY + this.unitTime * mm, day[0]).attr({
             font: "12px Monaco, monospace",
             fill: "#BBB"
@@ -119,6 +121,7 @@
           cuday = day[0];
         }
         if (cumonth !== day[1]) {
+          // Months
           r.text(20, this.offsetY + this.unitTime * mm, day[1]).attr({
             font: "12px Monaco, monospace",
             fill: "#EEE"
@@ -207,6 +210,7 @@
       }
       r = this.r;
       shortrefs = commit.refs;
+      // Truncate if longer than 15 chars
       if (shortrefs.length > 17) {
         shortrefs = shortrefs.substr(0, 15) + "…";
       }
@@ -217,6 +221,7 @@
         title: commit.refs
       });
       textbox = text.getBBox();
+      // Create rectangle based on the size of the textbox
       rect = r.rect(x, y - 7, textbox.width + 5, textbox.height + 5, 4).attr({
         fill: "#000",
         "fill-opacity": .5,
@@ -229,6 +234,7 @@
       });
       label = r.set(rect, text);
       label.transform(["t", -rect.getBBox().width - 15, 0]);
+      // Set text to front
       return text.toFront();
     };
 
@@ -283,11 +289,13 @@
         parentY = this.offsetY + this.unitTime * parentCommit.time;
         parentX1 = this.offsetX + this.unitSpace * (this.mspace - parentCommit.space);
         parentX2 = this.offsetX + this.unitSpace * (this.mspace - parent[1]);
+        // Set line color
         if (parentCommit.space <= commit.space) {
           color = this.colors[commit.space];
         } else {
           color = this.colors[parentCommit.space];
         }
+        // Build line shape
         if (parent[1] === commit.space) {
           offset = [0, 5];
           arrow = "l-2,5,4,0,-2,-5,0,5";
@@ -298,13 +306,17 @@
           offset = [-3, 3];
           arrow = "l-5,0,2,4,3,-4,-4,2";
         }
+        // Start point
         route = ["M", x + offset[0], y + offset[1]];
+        // Add arrow if not first parent
         if (i > 0) {
           route.push(arrow);
         }
+        // Circumvent if overlap
         if (commit.space !== parentCommit.space || commit.space !== parent[1]) {
           route.push("L", parentX2, y + 10, "L", parentX2, parentY - 5);
         }
+        // End point
         route.push("L", parentX1, parentY);
         results.push(r.path(route).attr({
           stroke: color,
@@ -325,6 +337,7 @@
           "fill-opacity": .5,
           stroke: "none"
         });
+        // Displayed in the center
         return this.element.scrollTop(y - this.graphHeight / 2);
       }
     };
diff --git a/app/assets/javascripts/network/network_bundle.js b/app/assets/javascripts/network/network_bundle.js
index 6a7422a77553bf88e625cc29249aa4b9d2cf0afc..67c3e6453647011080c2c5212f1fd8d3155b5cef 100644
--- a/app/assets/javascripts/network/network_bundle.js
+++ b/app/assets/javascripts/network/network_bundle.js
@@ -1,4 +1,9 @@
-
+// This is a manifest file that'll be compiled into including all the files listed below.
+// Add new JavaScript/Coffee code in separate files in this directory and they'll automatically
+// be included in the compiled file accessible from http://example.com/assets/application.js
+// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
+// the compiled file.
+//
 /*= require_tree . */
 
 (function() {
diff --git a/app/assets/javascripts/notes.js b/app/assets/javascripts/notes.js
index ebe9ff2b8c49d836a6f82b5f744f5032ca0f7471..c6854f703fbd182a3398653adf9f3f06a226fb2f 100644
--- a/app/assets/javascripts/notes.js
+++ b/app/assets/javascripts/notes.js
@@ -1,22 +1,10 @@
 
 /*= require autosave */
-
-
 /*= require autosize */
-
-
 /*= require dropzone */
-
-
 /*= require dropzone_input */
-
-
 /*= require gfm_auto_complete */
-
-
 /*= require jquery.atwho */
-
-
 /*= require task_list */
 
 (function() {
@@ -60,26 +48,43 @@
     }
 
     Notes.prototype.addBinding = function() {
+      // add note to UI after creation
       $(document).on("ajax:success", ".js-main-target-form", this.addNote);
       $(document).on("ajax:success", ".js-discussion-note-form", this.addDiscussionNote);
+      // catch note ajax errors
       $(document).on("ajax:error", ".js-main-target-form", this.addNoteError);
+      // change note in UI after update
       $(document).on("ajax:success", "form.edit-note", this.updateNote);
+      // Edit note link
       $(document).on("click", ".js-note-edit", this.showEditForm);
       $(document).on("click", ".note-edit-cancel", this.cancelEdit);
+      // Reopen and close actions for Issue/MR combined with note form submit
       $(document).on("click", ".js-comment-button", this.updateCloseButton);
       $(document).on("keyup input", ".js-note-text", this.updateTargetButtons);
+      // resolve a discussion
       $(document).on('click', '.js-comment-resolve-button', this.resolveDiscussion);
+      // remove a note (in general)
       $(document).on("click", ".js-note-delete", this.removeNote);
+      // delete note attachment
       $(document).on("click", ".js-note-attachment-delete", this.removeAttachment);
+      // reset main target form after submit
       $(document).on("ajax:complete", ".js-main-target-form", this.reenableTargetFormSubmitButton);
       $(document).on("ajax:success", ".js-main-target-form", this.resetMainTargetForm);
+      // reset main target form when clicking discard
       $(document).on("click", ".js-note-discard", this.resetMainTargetForm);
+      // update the file name when an attachment is selected
       $(document).on("change", ".js-note-attachment-input", this.updateFormAttachment);
+      // reply to diff/discussion notes
       $(document).on("click", ".js-discussion-reply-button", this.replyToDiscussionNote);
+      // add diff note
       $(document).on("click", ".js-add-diff-note-button", this.addDiffNote);
+      // hide diff note form
       $(document).on("click", ".js-close-discussion-note-form", this.cancelDiscussionForm);
+      // fetch notes when tab becomes visible
       $(document).on("visibilitychange", this.visibilityChange);
+      // when issue status changes, we need to refresh data
       $(document).on("issuable:change", this.refresh);
+      // when a key is clicked on the notes
       return $(document).on("keydown", ".js-note-text", this.keydownNoteText);
     };
 
@@ -112,6 +117,7 @@
         return;
       }
       $textarea = $(e.target);
+      // Edit previous note when UP arrow is hit
       switch (e.which) {
         case 38:
           if ($textarea.val() !== '') {
@@ -123,6 +129,7 @@
             return myLastNoteEditBtn.trigger('click', [true, myLastNote]);
           }
           break;
+        // Cancel creating diff note or editing any note when ESCAPE is hit
         case 27:
           discussionNoteForm = $textarea.closest('.js-discussion-note-form');
           if (discussionNoteForm.length) {
@@ -247,10 +254,13 @@
         votesBlock = $('.js-awards-block').eq(0);
         gl.awardsHandler.addAwardToEmojiBar(votesBlock, note.name);
         return gl.awardsHandler.scrollToAwards();
+      // render note if it not present in loaded list
+      // or skip if rendered
       } else if (this.isNewNote(note)) {
         this.note_ids.push(note.id);
         $notesList = $('ul.main-notes-list');
         $notesList.append(note.html).syntaxHighlight();
+        // Update datetime format on the recent note
         gl.utils.localTimeAgo($notesList.find("#note_" + note.id + " .js-timeago"), false);
         this.initTaskList();
         this.refresh();
@@ -291,19 +301,26 @@
       row = form.closest("tr");
       note_html = $(note.html);
       note_html.syntaxHighlight();
+      // is this the first note of discussion?
       discussionContainer = $(".notes[data-discussion-id='" + note.discussion_id + "']");
       if ((note.original_discussion_id != null) && discussionContainer.length === 0) {
         discussionContainer = $(".notes[data-discussion-id='" + note.original_discussion_id + "']");
       }
       if (discussionContainer.length === 0) {
+        // insert the note and the reply button after the temp row
         row.after(note.diff_discussion_html);
+        // remove the note (will be added again below)
         row.next().find(".note").remove();
+        // Before that, the container didn't exist
         discussionContainer = $(".notes[data-discussion-id='" + note.discussion_id + "']");
+        // Add note to 'Changes' page discussions
         discussionContainer.append(note_html);
+        // Init discussion on 'Discussion' page if it is merge request page
         if ($('body').attr('data-page').indexOf('projects:merge_request') === 0) {
           $('ul.main-notes-list').append(note.discussion_html).syntaxHighlight();
         }
       } else {
+        // append new note to all matching discussions
         discussionContainer.append(note_html);
       }
 
@@ -327,7 +344,9 @@
     Notes.prototype.resetMainTargetForm = function(e) {
       var form;
       form = $(".js-main-target-form");
+      // remove validation errors
       form.find(".js-errors").remove();
+      // reset text and preview
       form.find(".js-md-write-button").click();
       form.find(".js-note-text").val("").trigger("input");
       form.find(".js-note-text").data("autosave").reset();
@@ -354,9 +373,13 @@
 
     Notes.prototype.setupMainTargetNoteForm = function() {
       var form;
+      // find the form
       form = $(".js-new-note-form");
+      // Set a global clone of the form for later cloning
       this.formClone = form.clone();
+      // show the form
       this.setupNoteForm(form);
+      // fix classes
       form.removeClass("js-new-note-form");
       form.addClass("js-main-target-form");
       form.find("#note_line_code").remove();
@@ -421,6 +444,7 @@
       }
 
       this.renderDiscussionNote(note);
+      // cleanup after successfully creating a diff/discussion note
       this.removeDiscussionNoteForm($form);
     };
 
@@ -433,10 +457,12 @@
 
     Notes.prototype.updateNote = function(_xhr, note, _status) {
       var $html, $note_li;
+      // Convert returned HTML to a jQuery object so we can modify it further
       $html = $(note.html);
       gl.utils.localTimeAgo($('.js-timeago', $html));
       $html.syntaxHighlight();
       $html.find('.js-task-list-container').taskList('enable');
+      // Find the note's `li` element by ID and replace it with the updated HTML
       $note_li = $('.note-row-' + note.id);
 
       $note_li.replaceWith($html);
@@ -461,15 +487,20 @@
       note.addClass("is-editting");
       form = note.find(".note-edit-form");
       form.addClass('current-note-edit-form');
+      // Show the attachment delete link
       note.find(".js-note-attachment-delete").show();
       done = function($noteText) {
         var noteTextVal;
+        // Neat little trick to put the cursor at the end
         noteTextVal = $noteText.val();
+        // Store the original note text in a data attribute to retrieve if a user cancels edit.
         form.find('form.edit-note').data('original-note', noteTextVal);
         return $noteText.val('').val(noteTextVal);
       };
       new GLForm(form);
       if ((scrollTo != null) && (myLastNote != null)) {
+        // scroll to the bottom
+        // so the open of the last element doesn't make a jump
         $('html, body').scrollTop($(document).height());
         return $('html, body').animate({
           scrollTop: myLastNote.offset().top - 150
@@ -505,6 +536,7 @@
       form = note.find(".current-note-edit-form");
       note.removeClass("is-editting");
       form.removeClass("current-note-edit-form");
+      // Replace markdown textarea text with original note text.
       return form.find(".js-note-text").val(form.find('form.edit-note').data('original-note'));
     };
 
@@ -520,6 +552,9 @@
       var noteId;
       noteId = $(e.currentTarget).closest(".note").attr("id");
       $(".note[id='" + noteId + "']").each((function(_this) {
+        // A same note appears in the "Discussion" and in the "Changes" tab, we have
+        // to remove all. Using $(".note[id='noteId']") ensure we get all the notes,
+        // where $("#noteId") would return only one.
         return function(i, el) {
           var note, notes;
           note = $(el);
@@ -533,13 +568,17 @@
             }
           }
 
+          // check if this is the last note for this line
           if (notes.find(".note").length === 1) {
+            // "Discussions" tab
             notes.closest(".timeline-entry").remove();
+            // "Changes" tab / commit view
             notes.closest("tr").remove();
           }
           return note.remove();
         };
       })(this));
+      // Decrement the "Discussions" counter only once
       return this.updateNotesCount(-1);
     };
 
@@ -571,10 +610,12 @@
       var form, replyLink;
       form = this.formClone.clone();
       replyLink = $(e.target).closest(".js-discussion-reply-button");
+      // insert the form after the button
       replyLink
         .closest('.discussion-reply-holder')
         .hide()
         .after(form);
+      // show the form
       return this.setupDiscussionNoteForm(replyLink, form);
     };
 
@@ -589,6 +630,7 @@
      */
 
     Notes.prototype.setupDiscussionNoteForm = function(dataHolder, form) {
+      // setup note target
       form.attr('id', "new-discussion-note-form-" + (dataHolder.data("discussionId")));
       form.attr("data-line-code", dataHolder.data("lineCode"));
       form.find("#note_type").val(dataHolder.data("noteType"));
@@ -636,6 +678,7 @@
       addForm = false;
       notesContentSelector = ".notes_content";
       rowCssToAdd = "<tr class=\"notes_holder js-temp-notes-holder\"><td class=\"notes_line\" colspan=\"2\"></td><td class=\"notes_content\"><div class=\"content\"></div></td></tr>";
+      // In parallel view, look inside the correct left/right pane
       if (this.isParallelView()) {
         lineType = $link.data("lineType");
         notesContentSelector += "." + lineType;
@@ -652,6 +695,7 @@
             e.target = replyButton[0];
             $.proxy(this.replyToDiscussionNote, replyButton[0], e).call();
           } else {
+            // In parallel view, the form may not be present in one of the panes
             noteForm = notesContent.find(".js-discussion-note-form");
             if (noteForm.length === 0) {
               addForm = true;
@@ -659,6 +703,7 @@
           }
         }
       } else {
+        // add a notes row and insert the form
         row.after(rowCssToAdd);
         nextRow = row.next();
         notesContent = nextRow.find(notesContentSelector);
@@ -667,6 +712,7 @@
       if (addForm) {
         newForm = this.formClone.clone();
         newForm.appendTo(notesContent);
+        // show the form
         return this.setupDiscussionNoteForm($link, newForm);
       }
     };
@@ -685,12 +731,15 @@
       glForm = form.data('gl-form');
       glForm.destroy();
       form.find(".js-note-text").data("autosave").reset();
+      // show the reply button (will only work for replies)
       form
         .prev('.discussion-reply-holder')
         .show();
       if (row.is(".js-temp-notes-holder")) {
+        // remove temporary row for diff lines
         return row.remove();
       } else {
+        // only remove the form
         return form.remove();
       }
     };
@@ -712,6 +761,7 @@
     Notes.prototype.updateFormAttachment = function() {
       var filename, form;
       form = $(this).closest("form");
+      // get only the basename
       filename = $(this).val().replace(/^.*[\\\/]/, "");
       return form.find(".js-attachment-filename").text(filename);
     };
diff --git a/app/assets/javascripts/preview_markdown.js b/app/assets/javascripts/preview_markdown.js
index 5fd7579964024c842915af9f237863d7335394f0..5200487814f736f869e2c3634a6f42d8eee73e05 100644
--- a/app/assets/javascripts/preview_markdown.js
+++ b/app/assets/javascripts/preview_markdown.js
@@ -1,9 +1,15 @@
+// MarkdownPreview
+//
+// Handles toggling the "Write" and "Preview" tab clicks, rendering the preview,
+// and showing a warning when more than `x` users are referenced.
+//
 (function() {
   var lastTextareaPreviewed, markdownPreview, previewButtonSelector, writeButtonSelector;
 
   this.MarkdownPreview = (function() {
     function MarkdownPreview() {}
 
+    // Minimum number of users referenced before triggering a warning
     MarkdownPreview.prototype.referenceThreshold = 10;
 
     MarkdownPreview.prototype.ajaxCache = {};
@@ -101,8 +107,10 @@
       return;
     }
     lastTextareaPreviewed = $form.find('textarea.markdown-area');
+    // toggle tabs
     $form.find(writeButtonSelector).parent().removeClass('active');
     $form.find(previewButtonSelector).parent().addClass('active');
+    // toggle content
     $form.find('.md-write-holder').hide();
     $form.find('.md-preview-holder').show();
     return markdownPreview.showPreview($form);
@@ -113,8 +121,10 @@
       return;
     }
     lastTextareaPreviewed = null;
+    // toggle tabs
     $form.find(writeButtonSelector).parent().addClass('active');
     $form.find(previewButtonSelector).parent().removeClass('active');
+    // toggle content
     $form.find('.md-write-holder').show();
     $form.find('textarea.markdown-area').focus();
     return $form.find('.md-preview-holder').hide();
diff --git a/app/assets/javascripts/profile/gl_crop.js b/app/assets/javascripts/profile/gl_crop.js
index a3eea316f67c7aca652b9446ff597734c5243d35..30cd6f6e470c14b6228ea1b3f528a9fe92619764 100644
--- a/app/assets/javascripts/profile/gl_crop.js
+++ b/app/assets/javascripts/profile/gl_crop.js
@@ -5,6 +5,7 @@
   GitLabCrop = (function() {
     var FILENAMEREGEX;
 
+    // Matches everything but the file name
     FILENAMEREGEX = /^.*[\\\/]/;
 
     function GitLabCrop(input, opts) {
@@ -17,11 +18,18 @@
       this.onModalShow = bind(this.onModalShow, this);
       this.onPickImageClick = bind(this.onPickImageClick, this);
       this.fileInput = $(input);
+      // We should rename to avoid spec to fail
+      // Form will submit the proper input filed with a file using FormData
       this.fileInput.attr('name', (this.fileInput.attr('name')) + "-trigger").attr('id', (this.fileInput.attr('id')) + "-trigger");
+      // Set defaults
       this.exportWidth = (ref = opts.exportWidth) != null ? ref : 200, this.exportHeight = (ref1 = opts.exportHeight) != null ? ref1 : 200, this.cropBoxWidth = (ref2 = opts.cropBoxWidth) != null ? ref2 : 200, this.cropBoxHeight = (ref3 = opts.cropBoxHeight) != null ? ref3 : 200, this.form = (ref4 = opts.form) != null ? ref4 : this.fileInput.parents('form'), this.filename = opts.filename, this.previewImage = opts.previewImage, this.modalCrop = opts.modalCrop, this.pickImageEl = opts.pickImageEl, this.uploadImageBtn = opts.uploadImageBtn, this.modalCropImg = opts.modalCropImg;
+      // Required params
+      // Ensure needed elements are jquery objects
+      // If selector is provided we will convert them to a jQuery Object
       this.filename = this.getElement(this.filename);
       this.previewImage = this.getElement(this.previewImage);
       this.pickImageEl = this.getElement(this.pickImageEl);
+      // Modal elements usually are outside the @form element
       this.modalCrop = _.isString(this.modalCrop) ? $(this.modalCrop) : this.modalCrop;
       this.uploadImageBtn = _.isString(this.uploadImageBtn) ? $(this.uploadImageBtn) : this.uploadImageBtn;
       this.modalCropImg = _.isString(this.modalCropImg) ? $(this.modalCropImg) : this.modalCropImg;
@@ -93,8 +101,8 @@
       return this.modalCropImg.attr('src', '').cropper('destroy');
     };
 
-    GitLabCrop.prototype.onUploadImageBtnClick = function(e) {
-      e.preventDefault();
+    GitLabCrop.prototype.onUploadImageBtnClick = function(e) { // Remove attached image
+      e.preventDefault(); // Destroy cropper instance
       this.setBlob();
       this.setPreview();
       this.modalCrop.modal('hide');
diff --git a/app/assets/javascripts/profile/profile.js b/app/assets/javascripts/profile/profile.js
index ed1d87abafed50b7f42e28d07cbf227b456c8e39..60f9fba577785dc6e8bc9ef0fef2d1b8f8058680 100644
--- a/app/assets/javascripts/profile/profile.js
+++ b/app/assets/javascripts/profile/profile.js
@@ -11,9 +11,11 @@
       this.form = (ref = opts.form) != null ? ref : $('.edit-user');
       $('.js-preferences-form').on('change.preference', 'input[type=radio]', function() {
         return $(this).parents('form').submit();
+      // Automatically submit the Preferences form when any of its radio buttons change
       });
       $('#user_notification_email').on('change', function() {
         return $(this).parents('form').submit();
+      // Automatically submit email form when it changes
       });
       $('.update-username').on('ajax:before', function() {
         $('.loading-username').show();
@@ -76,6 +78,7 @@
         },
         complete: function() {
           window.scrollTo(0, 0);
+          // Enable submit button after requests ends
           return self.form.find(':input[disabled]').enable();
         }
       });
@@ -93,6 +96,7 @@
       if (comment && comment.length > 1 && $title.val() === '') {
         return $title.val(comment[1]).change();
       }
+    // Extract the SSH Key title from its comment
     });
     if (gl.utils.getPagePath() === 'profiles') {
       return new Profile();
diff --git a/app/assets/javascripts/profile/profile_bundle.js b/app/assets/javascripts/profile/profile_bundle.js
index b95faadc8e72f17e7cdb90eab9203622916bee02..d6e4d9f7ad82e841360ab4ab8d46a8738dcdcc51 100644
--- a/app/assets/javascripts/profile/profile_bundle.js
+++ b/app/assets/javascripts/profile/profile_bundle.js
@@ -3,5 +3,4 @@
 
 (function() {
 
-
 }).call(this);
diff --git a/app/assets/javascripts/project.js b/app/assets/javascripts/project.js
index 66e097c0a289d529c8cc47455c609bca573e5924..a6c015299a0db796a48753ebb6884cfb04424ae2 100644
--- a/app/assets/javascripts/project.js
+++ b/app/assets/javascripts/project.js
@@ -11,7 +11,13 @@
         url = $("#project_clone").val();
         $('#project_clone').val(url);
         return $('.clone').text(url);
+      // Git protocol switcher
+      // Remove the active class for all buttons (ssh, http, kerberos if shown)
+      // Add the active class for the clicked button
+      // Update the input field
+      // Update the command line instructions
       });
+      // Ref switcher
       this.initRefSwitcher();
       $('.project-refs-select').on('change', function() {
         return $(this).parents('form').submit();
diff --git a/app/assets/javascripts/project_find_file.js b/app/assets/javascripts/project_find_file.js
index 4925f0519f069117b0bc44c28e042c003d926a26..5bf900f3e1d5c4cda2575002394551d1cde138dc 100644
--- a/app/assets/javascripts/project_find_file.js
+++ b/app/assets/javascripts/project_find_file.js
@@ -13,8 +13,11 @@
       this.selectRowUp = bind(this.selectRowUp, this);
       this.filePaths = {};
       this.inputElement = this.element.find(".file-finder-input");
+      // init event
       this.initEvent();
+      // focus text input box
       this.inputElement.focus();
+      // load file list
       this.load(this.options.url);
     }
 
@@ -42,6 +45,7 @@
           }
         }
       });
+    // init event
     };
 
     ProjectFindFile.prototype.findFile = function() {
@@ -49,8 +53,10 @@
       searchText = this.inputElement.val();
       result = searchText.length > 0 ? fuzzaldrinPlus.filter(this.filePaths, searchText) : this.filePaths;
       return this.renderList(result, searchText);
+    // find file
     };
 
+    // files pathes load
     ProjectFindFile.prototype.load = function(url) {
       return $.ajax({
         url: url,
@@ -67,6 +73,7 @@
       });
     };
 
+    // render result
     ProjectFindFile.prototype.renderList = function(filePaths, searchText) {
       var blobItemUrl, filePath, html, i, j, len, matches, results;
       this.element.find(".tree-table > tbody").empty();
@@ -86,6 +93,7 @@
       return results;
     };
 
+    // highlight text(awefwbwgtc -> <b>a</b>wefw<b>b</b>wgt<b>c</b> )
     highlighter = function(element, text, matches) {
       var highlightText, j, lastIndex, len, matchIndex, matchedChars, unmatched;
       lastIndex = 0;
@@ -110,6 +118,7 @@
       return element.append(document.createTextNode(text.substring(lastIndex)));
     };
 
+    // make tbody row html
     ProjectFindFile.prototype.makeHtml = function(filePath, matches, blobItemUrl) {
       var $tr;
       $tr = $("<tr class='tree-item'><td class='tree-item-file-name'><i class='fa fa-file-text-o fa-fw'></i><span class='str-truncated'><a></a></span></td></tr>");
diff --git a/app/assets/javascripts/project_show.js b/app/assets/javascripts/project_show.js
index 8ca4c4279120525b19e0744df248551bee67629f..c8cfc9a9ba896073707006c6238a55d87579ef2d 100644
--- a/app/assets/javascripts/project_show.js
+++ b/app/assets/javascripts/project_show.js
@@ -7,3 +7,5 @@
   })();
 
 }).call(this);
+
+// I kept class for future
diff --git a/app/assets/javascripts/projects_list.js b/app/assets/javascripts/projects_list.js
index 4f415b05dbc4793f29410c8b53a627c43a9cd122..04fb49552e826f727bf8190568372075fcc6d367 100644
--- a/app/assets/javascripts/projects_list.js
+++ b/app/assets/javascripts/projects_list.js
@@ -33,6 +33,7 @@
           $('.projects-list-holder').replaceWith(data.html);
           return history.replaceState({
             page: project_filter_url
+          // Change url so if user reload a page - search results are saved
           }, document.title, project_filter_url);
         },
         dataType: "json"
diff --git a/app/assets/javascripts/protected_branch_dropdown.js.es6 b/app/assets/javascripts/protected_branch_dropdown.js.es6
index 6738dc8862dff3e10683a7ea926337d16a088524..983322cbeccb83d48d53982dd83d64c771aa727b 100644
--- a/app/assets/javascripts/protected_branch_dropdown.js.es6
+++ b/app/assets/javascripts/protected_branch_dropdown.js.es6
@@ -45,6 +45,7 @@ class ProtectedBranchDropdown {
   }
 
   onClickCreateWildcard() {
+    // Refresh the dropdown's data, which ends up calling `getProtectedBranches`
     this.$dropdown.data('glDropdown').remote.execute();
     this.$dropdown.data('glDropdown').selectRowAtIndex(0);
   }
diff --git a/app/assets/javascripts/search_autocomplete.js b/app/assets/javascripts/search_autocomplete.js
index 227e8c696b4ffce37f8fd682c3da4e2871c1ebaa..8abb09c626fd2fdf44ee2dc128897eec0fd21c3b 100644
--- a/app/assets/javascripts/search_autocomplete.js
+++ b/app/assets/javascripts/search_autocomplete.js
@@ -24,6 +24,7 @@
       this.onSearchInputKeyUp = bind(this.onSearchInputKeyUp, this);
       this.onSearchInputKeyDown = bind(this.onSearchInputKeyDown, this);
       this.wrap = (ref = opts.wrap) != null ? ref : $('.search'), this.optsEl = (ref1 = opts.optsEl) != null ? ref1 : this.wrap.find('.search-autocomplete-opts'), this.autocompletePath = (ref2 = opts.autocompletePath) != null ? ref2 : this.optsEl.data('autocomplete-path'), this.projectId = (ref3 = opts.projectId) != null ? ref3 : this.optsEl.data('autocomplete-project-id') || '', this.projectRef = (ref4 = opts.projectRef) != null ? ref4 : this.optsEl.data('autocomplete-project-ref') || '';
+      // Dropdown Element
       this.dropdown = this.wrap.find('.dropdown');
       this.dropdownContent = this.dropdown.find('.dropdown-content');
       this.locationBadgeEl = this.getElement('.location-badge');
@@ -35,6 +36,7 @@
       this.repositoryInputEl = this.getElement('#repository_ref');
       this.clearInput = this.getElement('.js-clear-input');
       this.saveOriginalState();
+      // Only when user is logged in
       if (gon.current_user_id) {
         this.createAutocomplete();
       }
@@ -43,6 +45,7 @@
       this.bindEvents();
     }
 
+    // Finds an element inside wrapper element
     SearchAutocomplete.prototype.getElement = function(selector) {
       return this.wrap.find(selector);
     };
@@ -82,6 +85,7 @@
         }
         return;
       }
+      // Prevent multiple ajax calls
       if (this.loadingSuggestions) {
         return;
       }
@@ -92,14 +96,17 @@
         term: term
       }, function(response) {
         var data, firstCategory, i, lastCategory, len, suggestion;
+        // Hide dropdown menu if no suggestions returns
         if (!response.length) {
           _this.disableAutocomplete();
           return;
         }
         data = [];
+        // List results
         firstCategory = true;
         for (i = 0, len = response.length; i < len; i++) {
           suggestion = response[i];
+          // Add group header before list each group
           if (lastCategory !== suggestion.category) {
             if (!firstCategory) {
               data.push('separator');
@@ -119,6 +126,7 @@
             url: suggestion.url
           });
         }
+        // Add option to proceed with the search
         if (data.length) {
           data.push('separator');
           data.push({
@@ -169,11 +177,13 @@
 
     SearchAutocomplete.prototype.serializeState = function() {
       return {
+        // Search Criteria
         search_project_id: this.projectInputEl.val(),
         group_id: this.groupInputEl.val(),
         search_code: this.searchCodeInputEl.val(),
         repository_ref: this.repositoryInputEl.val(),
         scope: this.scopeInputEl.val(),
+        // Location badge
         _location: this.locationBadgeEl.text()
       };
     };
@@ -194,6 +204,7 @@
 
     SearchAutocomplete.prototype.enableAutocomplete = function() {
       var _this;
+      // No need to enable anything if user is not logged in
       if (!gon.current_user_id) {
         return;
       }
@@ -206,18 +217,22 @@
     };
 
     SearchAutocomplete.prototype.onSearchInputKeyDown = function() {
+      // Saves last length of the entered text
       return this.saveTextLength();
     };
 
     SearchAutocomplete.prototype.onSearchInputKeyUp = function(e) {
       switch (e.keyCode) {
         case KEYCODE.BACKSPACE:
+          // when trying to remove the location badge
           if (this.lastTextLength === 0 && this.badgePresent()) {
             this.removeLocationBadge();
           }
+          // When removing the last character and no badge is present
           if (this.lastTextLength === 1) {
             this.disableAutocomplete();
           }
+          // When removing any character from existin value
           if (this.lastTextLength > 1) {
             this.enableAutocomplete();
           }
@@ -232,9 +247,12 @@
         case KEYCODE.DOWN:
           return;
         default:
+          // Handle the case when deleting the input value other than backspace
+          // e.g. Pressing ctrl + backspace or ctrl + x
           if (this.searchInput.val() === '') {
             this.disableAutocomplete();
           } else {
+            // We should display the menu only when input is not empty
             if (e.keyCode !== KEYCODE.ENTER) {
               this.enableAutocomplete();
             }
@@ -243,7 +261,9 @@
       this.wrap.toggleClass('has-value', !!e.target.value);
     };
 
+    // Avoid falsy value to be returned
     SearchAutocomplete.prototype.onSearchInputClick = function(e) {
+      // Prevents closing the dropdown menu
       return e.stopImmediatePropagation();
     };
 
@@ -267,6 +287,7 @@
     SearchAutocomplete.prototype.onSearchInputBlur = function(e) {
       this.isFocused = false;
       this.wrap.removeClass('search-active');
+      // If input is blank then restore state
       if (this.searchInput.val() === '') {
         return this.restoreOriginalState();
       }
@@ -311,6 +332,7 @@
       results = [];
       for (i = 0, len = inputs.length; i < len; i++) {
         input = inputs[i];
+        // _location isnt a input
         if (input === '_location') {
           break;
         }
diff --git a/app/assets/javascripts/shortcuts.js b/app/assets/javascripts/shortcuts.js
index 3b28332854a0ad0b2651e730c6bac236bab59314..3aa8536d40a5e01a7624de4ab5f7d9649763c321 100644
--- a/app/assets/javascripts/shortcuts.js
+++ b/app/assets/javascripts/shortcuts.js
@@ -86,6 +86,7 @@
     var defaultStopCallback;
     defaultStopCallback = Mousetrap.stopCallback;
     return function(e, element, combo) {
+      // allowed shortcuts if textarea, input, contenteditable are focused
       if (['ctrl+shift+p', 'command+shift+p'].indexOf(combo) !== -1) {
         return false;
       } else {
diff --git a/app/assets/javascripts/shortcuts_find_file.js b/app/assets/javascripts/shortcuts_find_file.js
index 6c78914d3386dd56159fafa8232cf89d10f77d0b..92ce31969e3023eeeac7b02210e9c0bce858a579 100644
--- a/app/assets/javascripts/shortcuts_find_file.js
+++ b/app/assets/javascripts/shortcuts_find_file.js
@@ -14,8 +14,10 @@
       ShortcutsFindFile.__super__.constructor.call(this);
       _oldStopCallback = Mousetrap.stopCallback;
       Mousetrap.stopCallback = (function(_this) {
+        // override to fire shortcuts action when focus in textbox
         return function(event, element, combo) {
           if (element === _this.projectFindFile.inputElement[0] && (combo === 'up' || combo === 'down' || combo === 'esc' || combo === 'enter')) {
+            // when press up/down key in textbox, cusor prevent to move to home/end
             event.preventDefault();
             return false;
           }
diff --git a/app/assets/javascripts/shortcuts_issuable.js b/app/assets/javascripts/shortcuts_issuable.js
index 3f3a8a9dfd9cbf70573499436c6aa135c5f2bc67..235bf4f95ec7206d7e521b77a27f80ae2d636261 100644
--- a/app/assets/javascripts/shortcuts_issuable.js
+++ b/app/assets/javascripts/shortcuts_issuable.js
@@ -1,7 +1,5 @@
 
 /*= require mousetrap */
-
-
 /*= require shortcuts_navigation */
 
 (function() {
@@ -43,16 +41,20 @@
         if (selected.trim() === "") {
           return;
         }
+        // Put a '>' character before each non-empty line in the selection
         quote = _.map(selected.split("\n"), function(val) {
           if (val.trim() !== '') {
             return "> " + val + "\n";
           }
         });
+        // If replyField already has some content, add a newline before our quote
         separator = replyField.val().trim() !== "" && "\n" || '';
         replyField.val(function(_, current) {
           return current + separator + quote.join('') + "\n";
         });
+        // Trigger autosave for the added text
         replyField.trigger('input');
+        // Focus the input field
         return replyField.focus();
       }
     };
diff --git a/app/assets/javascripts/syntax_highlight.js b/app/assets/javascripts/syntax_highlight.js
index dba62638c78143bb71f79eb7fd3a468ae4a219fb..2ae7bf5fc156f032aa38ff609a84d7914d0a7d79 100644
--- a/app/assets/javascripts/syntax_highlight.js
+++ b/app/assets/javascripts/syntax_highlight.js
@@ -1,9 +1,20 @@
+// Syntax Highlighter
+//
+// Applies a syntax highlighting color scheme CSS class to any element with the
+// `js-syntax-highlight` class
+//
+// ### Example Markup
+//
+//   <div class="js-syntax-highlight"></div>
+//
 (function() {
   $.fn.syntaxHighlight = function() {
     var $children;
     if ($(this).hasClass('js-syntax-highlight')) {
+      // Given the element itself, apply highlighting
       return $(this).addClass(gon.user_color_scheme);
     } else {
+      // Given a parent element, recurse to any of its applicable children
       $children = $(this).find('.js-syntax-highlight');
       if ($children.length) {
         return $children.syntaxHighlight();
diff --git a/app/assets/javascripts/todos.js b/app/assets/javascripts/todos.js
index 23eda7d44ca5ecb2b96d9baa20ed7f14a1fc5566..93421649ac7b247103f600725bc239c7c47050e4 100644
--- a/app/assets/javascripts/todos.js
+++ b/app/assets/javascripts/todos.js
@@ -129,16 +129,21 @@
       var currPage, currPages, newPages, pageParams, url;
       currPages = this.getTotalPages();
       currPage = this.getCurrentPage();
+      // Refresh if no remaining Todos
       if (!total) {
         location.reload();
         return;
       }
+      // Do nothing if no pagination
       if (!currPages) {
         return;
       }
       newPages = Math.ceil(total / this.getTodosPerPage());
+      // Includes query strings
       url = location.href;
+      // If new total of pages is different than we have now
       if (newPages !== currPages) {
+        // Redirect to previous page if there's one available
         if (currPages > 1 && currPage === currPages) {
           pageParams = {
             page: currPages - 1
@@ -155,6 +160,7 @@
       if (!todoLink) {
         return;
       }
+      // Allow Meta-Click or Mouse3-click to open in a new tab
       if (e.metaKey || e.which === 2) {
         e.preventDefault();
         return window.open(todoLink, '_blank');
diff --git a/app/assets/javascripts/tree.js b/app/assets/javascripts/tree.js
index 78e159a7ed97c3c397a31a224e23f4da57ccd975..9b7be17c4fe9bc34c5685c7361126c65cc9178cd 100644
--- a/app/assets/javascripts/tree.js
+++ b/app/assets/javascripts/tree.js
@@ -2,6 +2,8 @@
   this.TreeView = (function() {
     function TreeView() {
       this.initKeyNav();
+      // Code browser tree slider
+      // Make the entire tree-item row clickable, but not if clicking another link (like a commit message)
       $(".tree-content-holder .tree-item").on('click', function(e) {
         var $clickedEl, path;
         $clickedEl = $(e.target);
@@ -15,6 +17,7 @@
           }
         }
       });
+      // Show the "Loading commit data" for only the first element
       $('span.log_loading:first').removeClass('hide');
     }
 
diff --git a/app/assets/javascripts/u2f/authenticate.js b/app/assets/javascripts/u2f/authenticate.js
index 9ba847fb0c2c782199845235ed4477d88049ec85..ce2930c7fc727fd7ce6c870479f12002e827d273 100644
--- a/app/assets/javascripts/u2f/authenticate.js
+++ b/app/assets/javascripts/u2f/authenticate.js
@@ -1,3 +1,7 @@
+// Authenticate U2F (universal 2nd factor) devices for users to authenticate with.
+//
+// State Flow #1: setup -> in_progress -> authenticated -> POST to server
+// State Flow #2: setup -> in_progress -> error -> setup
 (function() {
   var bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
 
@@ -15,6 +19,17 @@
       this.appId = u2fParams.app_id;
       this.challenge = u2fParams.challenge;
       this.signRequests = u2fParams.sign_requests.map(function(request) {
+        // The U2F Javascript API v1.1 requires a single challenge, with
+        // _no challenges per-request_. The U2F Javascript API v1.0 requires a
+        // challenge per-request, which is done by copying the single challenge
+        // into every request.
+        //
+        // In either case, we don't need the per-request challenges that the server
+        // has generated, so we can remove them.
+        //
+        // Note: The server library fixes this behaviour in (unreleased) version 1.0.0.
+        // This can be removed once we upgrade.
+        // https://github.com/castle/ruby-u2f/commit/103f428071a81cd3d5f80c2e77d522d5029946a4
         return _(request).omit('challenge');
       });
     }
@@ -41,6 +56,7 @@
       })(this), 10);
     };
 
+    // Rendering #
     U2FAuthenticate.prototype.templates = {
       "notSupported": "#js-authenticate-u2f-not-supported",
       "setup": '#js-authenticate-u2f-setup',
@@ -75,6 +91,8 @@
 
     U2FAuthenticate.prototype.renderAuthenticated = function(deviceResponse) {
       this.renderTemplate('authenticated');
+      // Prefer to do this instead of interpolating using Underscore templates
+      // because of JSON escaping issues.
       return this.container.find("#js-device-response").val(deviceResponse);
     };
 
diff --git a/app/assets/javascripts/u2f/register.js b/app/assets/javascripts/u2f/register.js
index c87e0840df33feaab53ddf79faf4e2f419f62d64..926912fa9881e11619f2d8eb705f90043c46f5e7 100644
--- a/app/assets/javascripts/u2f/register.js
+++ b/app/assets/javascripts/u2f/register.js
@@ -1,3 +1,7 @@
+// Register U2F (universal 2nd factor) devices for users to authenticate with.
+//
+// State Flow #1: setup -> in_progress -> registered -> POST to server
+// State Flow #2: setup -> in_progress -> error -> setup
 (function() {
   var bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
 
@@ -39,6 +43,7 @@
       })(this), 10);
     };
 
+    // Rendering #
     U2FRegister.prototype.templates = {
       "notSupported": "#js-register-u2f-not-supported",
       "setup": '#js-register-u2f-setup',
@@ -73,6 +78,8 @@
 
     U2FRegister.prototype.renderRegistered = function(deviceResponse) {
       this.renderTemplate('registered');
+      // Prefer to do this instead of interpolating using Underscore templates
+      // because of JSON escaping issues.
       return this.container.find("#js-device-response").val(deviceResponse);
     };
 
diff --git a/app/assets/javascripts/user_tabs.js b/app/assets/javascripts/user_tabs.js
index e5e75701feecf9b663649dac086ae9470a64d85b..8a657780eb6590bd875af29441b3f18a24a46310 100644
--- a/app/assets/javascripts/user_tabs.js
+++ b/app/assets/javascripts/user_tabs.js
@@ -1,3 +1,61 @@
+// UserTabs
+//
+// Handles persisting and restoring the current tab selection and lazily-loading
+// content on the Users#show page.
+//
+// ### Example Markup
+//
+//   <ul class="nav-links">
+//     <li class="activity-tab active">
+//       <a data-action="activity" data-target="#activity" data-toggle="tab" href="/u/username">
+//         Activity
+//       </a>
+//     </li>
+//     <li class="groups-tab">
+//       <a data-action="groups" data-target="#groups" data-toggle="tab" href="/u/username/groups">
+//         Groups
+//       </a>
+//     </li>
+//     <li class="contributed-tab">
+//       <a data-action="contributed" data-target="#contributed" data-toggle="tab" href="/u/username/contributed">
+//         Contributed projects
+//       </a>
+//     </li>
+//     <li class="projects-tab">
+//       <a data-action="projects" data-target="#projects" data-toggle="tab" href="/u/username/projects">
+//         Personal projects
+//       </a>
+//     </li>
+//    <li class="snippets-tab">
+//       <a data-action="snippets" data-target="#snippets" data-toggle="tab" href="/u/username/snippets">
+//       </a>
+//     </li>
+//   </ul>
+//
+//   <div class="tab-content">
+//     <div class="tab-pane" id="activity">
+//       Activity Content
+//     </div>
+//     <div class="tab-pane" id="groups">
+//       Groups Content
+//     </div>
+//     <div class="tab-pane" id="contributed">
+//       Contributed projects content
+//     </div>
+//     <div class="tab-pane" id="projects">
+//       Projects content
+//     </div>
+//     <div class="tab-pane" id="snippets">
+//       Snippets content
+//     </div>
+//   </div>
+//
+//   <div class="loading-status">
+//     <div class="loading">
+//       Loading Animation
+//     </div>
+//   </div>
+//
 (function() {
   var bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
 
@@ -6,18 +64,23 @@
       this.tabShown = bind(this.tabShown, this);
       var i, item, len, ref, ref1, ref2, ref3;
       this.action = (ref = opts.action) != null ? ref : 'activity', this.defaultAction = (ref1 = opts.defaultAction) != null ? ref1 : 'activity', this.parentEl = (ref2 = opts.parentEl) != null ? ref2 : $(document);
+      // Make jQuery object if selector is provided
       if (typeof this.parentEl === 'string') {
         this.parentEl = $(this.parentEl);
       }
+      // Store the `location` object, allowing for easier stubbing in tests
       this._location = location;
+      // Set tab states
       this.loaded = {};
       ref3 = this.parentEl.find('.nav-links a');
       for (i = 0, len = ref3.length; i < len; i++) {
         item = ref3[i];
         this.loaded[$(item).attr('data-action')] = false;
       }
+      // Actions
       this.actions = Object.keys(this.loaded);
       this.bindEvents();
+      // Set active tab
       if (this.action === 'show') {
         this.action = this.defaultAction;
       }
@@ -25,6 +88,7 @@
     }
 
     UserTabs.prototype.bindEvents = function() {
+      // Toggle event listeners
       return this.parentEl.off('shown.bs.tab', '.nav-links a[data-toggle="tab"]').on('shown.bs.tab', '.nav-links a[data-toggle="tab"]', this.tabShown);
     };
 
@@ -74,6 +138,7 @@
             tabSelector = 'div#' + action;
             _this.parentEl.find(tabSelector).html(data.html);
             _this.loaded[action] = true;
+            // Fix tooltips
             return gl.utils.localTimeAgo($('.js-timeago', tabSelector));
           };
         })(this)
@@ -97,13 +162,17 @@
 
     UserTabs.prototype.setCurrentAction = function(action) {
       var new_state, regExp;
+      // Remove possible actions from URL
       regExp = new RegExp('\/(' + this.actions.join('|') + ')(\.html)?\/?$');
       new_state = this._location.pathname;
+      // remove trailing slashes
       new_state = new_state.replace(/\/+$/, "");
       new_state = new_state.replace(regExp, '');
+      // Append the new action if we're on a tab other than 'activity'
       if (action !== this.defaultAction) {
         new_state += "/" + action;
       }
+      // Ensure parameters and hash come along for the ride
       new_state += this._location.search + this._location.hash;
       history.replaceState({
         turbolinks: true,
diff --git a/app/assets/javascripts/users/calendar.js b/app/assets/javascripts/users/calendar.js
index 90cf551b32eb7da965db9268beea6ffdd575ca7e..b8da7c4f297cd81cac21bf559dc38ad91df55b8e 100644
--- a/app/assets/javascripts/users/calendar.js
+++ b/app/assets/javascripts/users/calendar.js
@@ -11,6 +11,8 @@
       this.daySizeWithSpace = this.daySize + (this.daySpace * 2);
       this.monthNames = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
       this.months = [];
+      // Loop through the timestamps to create a group of objects
+      // The group of objects will be grouped based on the day of the week they are
       this.timestampsTmp = [];
       var group = 0;
 
@@ -29,12 +31,15 @@
         var day = date.getDay();
         var count = timestamps[date.getTime() * 0.001];
 
+        // Create a new group array if this is the first day of the week
+        // or if is first object
         if ((day === 0 && i !== 0) || i === 0) {
           this.timestampsTmp.push([]);
           group++;
         }
 
         var innerArray = this.timestampsTmp[group - 1];
+        // Push to the inner array the values that will be used to render map
         innerArray.push({
           count: count || 0,
           date: date,
@@ -42,8 +47,10 @@
         });
       }
 
+      // Init color functions
       this.colorKey = this.initColorKey();
       this.color = this.initColor();
+      // Init the svg element
       this.renderSvg(group);
       this.renderDays();
       this.renderMonths();
diff --git a/app/assets/javascripts/users/users_bundle.js b/app/assets/javascripts/users/users_bundle.js
index b95faadc8e72f17e7cdb90eab9203622916bee02..d6e4d9f7ad82e841360ab4ab8d46a8738dcdcc51 100644
--- a/app/assets/javascripts/users/users_bundle.js
+++ b/app/assets/javascripts/users/users_bundle.js
@@ -3,5 +3,4 @@
 
 (function() {
 
-
 }).call(this);
diff --git a/app/assets/javascripts/users_select.js b/app/assets/javascripts/users_select.js
index bad82868ab045dbdcd18e83ee6610336757c917a..9c277998db4ac466b3e9f42e3c577356eeac16f9 100644
--- a/app/assets/javascripts/users_select.js
+++ b/app/assets/javascripts/users_select.js
@@ -81,6 +81,7 @@
                 if (term.length === 0) {
                   showDivider = 0;
                   if (firstUser) {
+                    // Move current user to the front of the list
                     for (index = j = 0, len = users.length; j < len; index = ++j) {
                       obj = users[index];
                       if (obj.username === firstUser) {
@@ -115,6 +116,7 @@
                 if (showDivider) {
                   users.splice(showDivider, 0, "divider");
                 }
+                // Send the data back
                 return callback(users);
               });
             },
@@ -139,6 +141,7 @@
             inputId: 'issue_assignee_id',
             hidden: function(e) {
               $selectbox.hide();
+              // display:block overrides the hide-collapse rule
               return $value.css('display', '');
             },
             clicked: function(user, $el, e) {
@@ -177,6 +180,7 @@
                   img = "<img src='" + avatar + "' class='avatar avatar-inline' width='30' />";
                 }
               }
+              // split into three parts so we can remove the username section if nessesary
               listWithName = "<li> <a href='#' class='dropdown-menu-user-link " + selected + "'> " + img + " <strong class='dropdown-menu-user-full-name'> " + user.name + " </strong>";
               listWithUserName = "<span class='dropdown-menu-user-username'> " + username + " </span>";
               listClosingTags = "</a> </li>";
@@ -215,6 +219,7 @@
                 };
                 if (query.term.length === 0) {
                   if (firstUser) {
+                    // Move current user to the front of the list
                     ref = data.results;
                     for (index = j = 0, len = ref.length; j < len; index = ++j) {
                       obj = ref[index];
@@ -271,6 +276,7 @@
               return _this.formatSelection.apply(_this, args);
             },
             dropdownCssClass: "ajax-users-dropdown",
+            // we do not want to escape markup since we are displaying html in results
             escapeMarkup: function(m) {
               return m;
             }
@@ -318,6 +324,8 @@
       });
     };
 
+    // Return users list. Filtered by query
+    // Only active users retrieved
     UsersSelect.prototype.users = function(query, options, callback) {
       var url;
       url = this.buildUrl(this.usersPath);
diff --git a/app/assets/javascripts/zen_mode.js b/app/assets/javascripts/zen_mode.js
index 71236c6a27d1c552a83d1b0f6b34d94d6f186bfd..777b32b41c9bb19d90f00b7a63ba90cf1397db26 100644
--- a/app/assets/javascripts/zen_mode.js
+++ b/app/assets/javascripts/zen_mode.js
@@ -1,21 +1,34 @@
-
+// Zen Mode (full screen) textarea
+//
 /*= provides zen_mode:enter */
-
-
 /*= provides zen_mode:leave */
-
-
+//
 /*= require jquery.scrollTo */
-
-
 /*= require dropzone */
-
-
 /*= require mousetrap */
-
-
 /*= require mousetrap/pause */
 
+//
+// ### Events
+//
+// `zen_mode:enter`
+//
+// Fired when the "Edit in fullscreen" link is clicked.
+//
+// **Synchronicity** Sync
+// **Bubbles** Yes
+// **Cancelable** No
+// **Target** a.js-zen-enter
+//
+// `zen_mode:leave`
+//
+// Fired when the "Leave Fullscreen" link is clicked.
+//
+// **Synchronicity** Sync
+// **Bubbles** Yes
+// **Cancelable** No
+// **Target** a.js-zen-leave
+//
 (function() {
   this.ZenMode = (function() {
     function ZenMode() {
@@ -40,6 +53,7 @@
         };
       })(this));
       $(document).on('keydown', function(e) {
+        // Esc
         if (e.keyCode === 27) {
           e.preventDefault();
           return $(document).trigger('zen_mode:leave');
@@ -52,6 +66,7 @@
       this.active_backdrop = $(backdrop);
       this.active_backdrop.addClass('fullscreen');
       this.active_textarea = this.active_backdrop.find('textarea');
+      // Prevent a user-resized textarea from persisting to fullscreen
       this.active_textarea.removeAttr('style');
       return this.active_textarea.focus();
     };
diff --git a/spec/javascripts/awards_handler_spec.js b/spec/javascripts/awards_handler_spec.js
index c1c12b57b532bbc91f3865ab002bcbbe6aa3e6a1..019ce3b07020b45223dd7bc3a7b9eb4a2000bc19 100644
--- a/spec/javascripts/awards_handler_spec.js
+++ b/spec/javascripts/awards_handler_spec.js
@@ -1,13 +1,7 @@
 
 /*= require awards_handler */
-
-
 /*= require jquery */
-
-
 /*= require jquery.cookie */
-
-
 /*= require ./fixtures/emoji_menu */
 
 (function() {
@@ -33,6 +27,7 @@
     return setTimeout(function() {
       assertFn();
       return done();
+    // Maybe jasmine.clock here?
     }, 333);
   };
 
diff --git a/spec/javascripts/behaviors/quick_submit_spec.js b/spec/javascripts/behaviors/quick_submit_spec.js
index 4c52ecd903d6c1b9431423b10003682650972999..13babb5bfdbd5080020a9b33f429a9b7a6c9df49 100644
--- a/spec/javascripts/behaviors/quick_submit_spec.js
+++ b/spec/javascripts/behaviors/quick_submit_spec.js
@@ -8,6 +8,7 @@
     beforeEach(function() {
       fixture.load('behaviors/quick_submit.html');
       $('form').submit(function(e) {
+        // Prevent a form submit from moving us off the testing page
         return e.preventDefault();
       });
       return this.spies = {
@@ -38,6 +39,8 @@
       expect($('input[type=submit]')).toBeDisabled();
       return expect($('button[type=submit]')).toBeDisabled();
     });
+    // We cannot stub `navigator.userAgent` for CI's `rake teaspoon` task, so we'll
+    // only run the tests that apply to the current platform
     if (navigator.userAgent.match(/Macintosh/)) {
       it('responds to Meta+Enter', function() {
         $('input.quick-submit-input').trigger(keydownEvent());
diff --git a/spec/javascripts/graphs/stat_graph_contributors_graph_spec.js b/spec/javascripts/graphs/stat_graph_contributors_graph_spec.js
index 82ee1954a597e44a337c68e50ae398b08acf889b..d5401fbb0d1aba8c35577542c0b3291023e5bee4 100644
--- a/spec/javascripts/graphs/stat_graph_contributors_graph_spec.js
+++ b/spec/javascripts/graphs/stat_graph_contributors_graph_spec.js
@@ -7,7 +7,7 @@ describe("ContributorsGraph", function () {
      expect(ContributorsGraph.prototype.x_domain).toEqual(20)
     })
   })
-  
+
   describe("#set_y_domain", function () {
     it("sets the y_domain", function () {
       ContributorsGraph.set_y_domain([{commits: 30}])
@@ -89,7 +89,7 @@ describe("ContributorsGraph", function () {
 })
 
 describe("ContributorsMasterGraph", function () {
-  
+
   // TODO: fix or remove
   //describe("#process_dates", function () {
     //it("gets and parses dates", function () {
@@ -103,7 +103,7 @@ describe("ContributorsMasterGraph", function () {
       //expect(graph.get_dates).toHaveBeenCalledWith(data)
       //expect(ContributorsGraph.set_dates).toHaveBeenCalledWith("get")
     //})
-  //}) 
+  //})
 
   describe("#get_dates", function () {
     it("plucks the date field from data collection", function () {
@@ -124,5 +124,5 @@ describe("ContributorsMasterGraph", function () {
     })
   })
 
-  
+
 })
diff --git a/spec/javascripts/issue_spec.js b/spec/javascripts/issue_spec.js
index dc6231ebb38469ab22b38d64057775ad5ab469e5..33690c7a5f31371b8a91a62e98fa0708b46b53be 100644
--- a/spec/javascripts/issue_spec.js
+++ b/spec/javascripts/issue_spec.js
@@ -1,7 +1,5 @@
 
 /*= require lib/utils/text_utility */
-
-
 /*= require issue */
 
 (function() {
diff --git a/spec/javascripts/new_branch_spec.js b/spec/javascripts/new_branch_spec.js
index 25d3f5b6c04d73fa0bc4499d1e166b0e1173784f..f09596bd36d30f55c3cca13e8fda2e504b8eb790 100644
--- a/spec/javascripts/new_branch_spec.js
+++ b/spec/javascripts/new_branch_spec.js
@@ -1,7 +1,5 @@
 
 /*= require jquery-ui/autocomplete */
-
-
 /*= require new_branch_form */
 
 (function() {
diff --git a/spec/javascripts/project_title_spec.js b/spec/javascripts/project_title_spec.js
index ffe49828492f2f649e60f67544e54631f7217e64..51eb12b41d4a8bab0160028d4a64a59e619ab001 100644
--- a/spec/javascripts/project_title_spec.js
+++ b/spec/javascripts/project_title_spec.js
@@ -1,22 +1,10 @@
 
 /*= require bootstrap */
-
-
 /*= require select2 */
-
-
 /*= require lib/utils/type_utility */
-
-
 /*= require gl_dropdown */
-
-
 /*= require api */
-
-
 /*= require project_select */
-
-
 /*= require project */
 
 (function() {
diff --git a/spec/javascripts/right_sidebar_spec.js b/spec/javascripts/right_sidebar_spec.js
index 38b3b2653ecaa4e38e84900af291f61b806de949..c937a4706f7d9f7d16d9382a54763163b8d55564 100644
--- a/spec/javascripts/right_sidebar_spec.js
+++ b/spec/javascripts/right_sidebar_spec.js
@@ -1,10 +1,6 @@
 
 /*= require right_sidebar */
-
-
 /*= require jquery */
-
-
 /*= require jquery.cookie */
 
 (function() {
diff --git a/spec/javascripts/search_autocomplete_spec.js b/spec/javascripts/search_autocomplete_spec.js
index 324f5152780af71348dd786b931e8e60e6da5b8f..00d9fc1302af24a72c2980bc78f0a87e2dda5fa5 100644
--- a/spec/javascripts/search_autocomplete_spec.js
+++ b/spec/javascripts/search_autocomplete_spec.js
@@ -1,19 +1,9 @@
 
 /*= require gl_dropdown */
-
-
 /*= require search_autocomplete */
-
-
 /*= require jquery */
-
-
 /*= require lib/utils/common_utils */
-
-
 /*= require lib/utils/type_utility */
-
-
 /*= require fuzzaldrin-plus */
 
 (function() {
@@ -43,6 +33,8 @@
 
   groupName = 'Gitlab Org';
 
+  // Add required attributes to body before starting the test.
+  // section would be dashboard|group|project
   addBodyAttributes = function(section) {
     var $body;
     if (section == null) {
@@ -64,6 +56,7 @@
     }
   };
 
+  // Mock `gl` object in window for dashboard specific page. App code will need it.
   mockDashboardOptions = function() {
     window.gl || (window.gl = {});
     return window.gl.dashboardOptions = {
@@ -72,6 +65,7 @@
     };
   };
 
+  // Mock `gl` object in window for project specific page. App code will need it.
   mockProjectOptions = function() {
     window.gl || (window.gl = {});
     return window.gl.projectOptions = {
diff --git a/spec/javascripts/shortcuts_issuable_spec.js b/spec/javascripts/shortcuts_issuable_spec.js
index 7b6b55fe545c385fc2e71a862dd4bbc677732412..04ccf246052843d62e20842349ca1781e5f38cff 100644
--- a/spec/javascripts/shortcuts_issuable_spec.js
+++ b/spec/javascripts/shortcuts_issuable_spec.js
@@ -10,6 +10,7 @@
     });
     return describe('#replyWithSelectedText', function() {
       var stubSelection;
+      // Stub window.getSelection to return the provided String.
       stubSelection = function(text) {
         return window.getSelection = function() {
           return text;
diff --git a/spec/javascripts/spec_helper.js b/spec/javascripts/spec_helper.js
index 7d91ed0f85582d114558f4b077a54fd710188a07..8801c29788700419fc6d254c65a1e8f17f95fae7 100644
--- a/spec/javascripts/spec_helper.js
+++ b/spec/javascripts/spec_helper.js
@@ -1,21 +1,41 @@
-
+// PhantomJS (Teaspoons default driver) doesn't have support for
+// Function.prototype.bind, which has caused confusion.  Use this polyfill to
+// avoid the confusion.
 /*= require support/bind-poly */
 
-
+// You can require your own javascript files here. By default this will include
+// everything in application, however you may get better load performance if you
+// require the specific files that are being used in the spec that tests them.
 /*= require jquery */
-
-
 /*= require jquery.turbolinks */
-
-
 /*= require bootstrap */
-
-
 /*= require underscore */
 
-
+// Teaspoon includes some support files, but you can use anything from your own
+// support path too.
+// require support/jasmine-jquery-1.7.0
+// require support/jasmine-jquery-2.0.0
 /*= require support/jasmine-jquery-2.1.0 */
 
+// require support/sinon
+// require support/your-support-file
+// Deferring execution
+// If you're using CommonJS, RequireJS or some other asynchronous library you can
+// defer execution. Call Teaspoon.execute() after everything has been loaded.
+// Simple example of a timeout:
+// Teaspoon.defer = true
+// setTimeout(Teaspoon.execute, 1000)
+// Matching files
+// By default Teaspoon will look for files that match
+// _spec.{js,js.coffee,.coffee}. Add a filename_spec.js file in your spec path
+// and it'll be included in the default suite automatically. If you want to
+// customize suites, check out the configuration in teaspoon_env.rb
+// Manifest
+// If you'd rather require your spec files manually (to control order for
+// instance) you can disable the suite matcher in the configuration and use this
+// file as a manifest.
+// For more information: http://github.com/modeset/teaspoon
+
 (function() {
 
 
diff --git a/spec/javascripts/u2f/authenticate_spec.js b/spec/javascripts/u2f/authenticate_spec.js
index e008ce956adb5ad65a247c329eb0534e336485fe..7ce3884f8443f24d697bf47087d220e4e3253ee3 100644
--- a/spec/javascripts/u2f/authenticate_spec.js
+++ b/spec/javascripts/u2f/authenticate_spec.js
@@ -1,16 +1,8 @@
 
 /*= require u2f/authenticate */
-
-
 /*= require u2f/util */
-
-
 /*= require u2f/error */
-
-
 /*= require u2f */
-
-
 /*= require ./mock_u2f_device */
 
 (function() {
diff --git a/spec/javascripts/u2f/register_spec.js b/spec/javascripts/u2f/register_spec.js
index 21c5266c60e72f1c0ddd9265e04161cf5127a4ac..01d6b7a8961f847ed437b2a60472553fdb766bf6 100644
--- a/spec/javascripts/u2f/register_spec.js
+++ b/spec/javascripts/u2f/register_spec.js
@@ -1,16 +1,8 @@
 
 /*= require u2f/register */
-
-
 /*= require u2f/util */
-
-
 /*= require u2f/error */
-
-
 /*= require u2f */
-
-
 /*= require ./mock_u2f_device */
 
 (function() {
diff --git a/spec/javascripts/zen_mode_spec.js b/spec/javascripts/zen_mode_spec.js
index 3d680ec8ea3f49da8e083f057db5d37bfdcbb339..0c1266800d78477bcc059cb38e3ddd0354d28b5b 100644
--- a/spec/javascripts/zen_mode_spec.js
+++ b/spec/javascripts/zen_mode_spec.js
@@ -14,8 +14,10 @@
             return true;
           }
         };
+      // Stub Dropzone.forElement(...).enable()
       });
       this.zen = new ZenMode();
+      // Set this manually because we can't actually scroll the window
       return this.zen.scroll_position = 456;
     });
     describe('on enter', function() {
@@ -60,7 +62,7 @@
     return $('a.js-zen-enter').click();
   };
 
-  exitZen = function() {
+  exitZen = function() { // Ohmmmmmmm
     return $('a.js-zen-leave').click();
   };
 
diff --git a/vendor/assets/javascripts/task_list.js b/vendor/assets/javascripts/task_list.js
index bc451506b6a71eab728b3480efdcac00ec2d9334..9fbfef03f6d61ac874c4aa8ad286e55f6d1fa0eb 100644
--- a/vendor/assets/javascripts/task_list.js
+++ b/vendor/assets/javascripts/task_list.js
@@ -1,15 +1,118 @@
-
+// The MIT License (MIT)
+//
+// Copyright (c) 2014 GitHub, Inc.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+// SOFTWARE.
+// TaskList Behavior
+//
 /*= provides tasklist:enabled */
-
-
 /*= provides tasklist:disabled */
-
-
 /*= provides tasklist:change */
-
-
 /*= provides tasklist:changed */
-
+//
+//
+// Enables Task List update behavior.
+//
+// ### Example Markup
+//
+//   <div class="js-task-list-container">
+//     <ul class="task-list">
+//       <li class="task-list-item">
+//         <input type="checkbox" class="js-task-list-item-checkbox" disabled />
+//         text
+//       </li>
+//     </ul>
+//     <form>
+//       <textarea class="js-task-list-field">- [ ] text</textarea>
+//     </form>
+//   </div>
+//
+// ### Specification
+//
+// TaskLists MUST be contained in a `(div).js-task-list-container`.
+//
+// TaskList Items SHOULD be an a list (`UL`/`OL`) element.
+//
+// Task list items MUST match `(input).task-list-item-checkbox` and MUST be
+// `disabled` by default.
+//
+// TaskLists MUST have a `(textarea).js-task-list-field` form element whose
+// `value` attribute is the source (Markdown) to be udpated. The source MUST
+// follow the syntax guidelines.
+//
+// TaskList updates trigger `tasklist:change` events. If the change is
+// successful, `tasklist:changed` is fired. The change can be canceled.
+//
+// jQuery is required.
+//
+// ### Methods
+//
+// `.taskList('enable')` or `.taskList()`
+//
+// Enables TaskList updates for the container.
+//
+// `.taskList('disable')`
+//
+// Disables TaskList updates for the container.
+//
+//# ### Events
+//
+// `tasklist:enabled`
+//
+// Fired when the TaskList is enabled.
+//
+// * **Synchronicity** Sync
+// * **Bubbles** Yes
+// * **Cancelable** No
+// * **Target** `.js-task-list-container`
+//
+// `tasklist:disabled`
+//
+// Fired when the TaskList is disabled.
+//
+// * **Synchronicity** Sync
+// * **Bubbles** Yes
+// * **Cancelable** No
+// * **Target** `.js-task-list-container`
+//
+// `tasklist:change`
+//
+// Fired before the TaskList item change takes affect.
+//
+// * **Synchronicity** Sync
+// * **Bubbles** Yes
+// * **Cancelable** Yes
+// * **Target** `.js-task-list-field`
+//
+// `tasklist:changed`
+//
+// Fired once the TaskList item change has taken affect.
+//
+// * **Synchronicity** Sync
+// * **Bubbles** Yes
+// * **Cancelable** No
+// * **Target** `.js-task-list-field`
+//
+// ### NOTE
+//
+// Task list checkboxes are rendered as disabled by default because rendered
+// user content is cached without regard for the viewer.
 (function() {
   var codeFencesPattern, complete, completePattern, disableTaskList, disableTaskLists, enableTaskList, enableTaskLists, escapePattern, incomplete, incompletePattern, itemPattern, itemsInParasPattern, updateTaskList, updateTaskListItem,
     indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };
@@ -18,20 +121,48 @@
 
   complete = "[x]";
 
+  // Escapes the String for regular expression matching.
   escapePattern = function(str) {
     return str.replace(/([\[\]])/g, "\\$1").replace(/\s/, "\\s").replace("x", "[xX]");
   };
 
-  incompletePattern = RegExp("" + (escapePattern(incomplete)));
-
-  completePattern = RegExp("" + (escapePattern(complete)));
+  incompletePattern = RegExp("" + (escapePattern(incomplete))); // escape square brackets
+ // match all white space
+  completePattern = RegExp("" + (escapePattern(complete))); // match all cases
 
+  // Pattern used to identify all task list items.
+  // Useful when you need iterate over all items.
   itemPattern = RegExp("^(?:\\s*(?:>\\s*)*(?:[-+*]|(?:\\d+\\.)))\\s*(" + (escapePattern(complete)) + "|" + (escapePattern(incomplete)) + ")\\s+(?!\\(.*?\\))(?=(?:\\[.*?\\]\\s*(?:\\[.*?\\]|\\(.*?\\))\\s*)*(?:[^\\[]|$))");
 
+  // prefix, consisting of
+  // optional leading whitespace
+  // zero or more blockquotes
+  // list item indicator
+  // optional whitespace prefix
+  // checkbox
+  // is followed by whitespace
+  // is not part of a [foo](url) link
+  // and is followed by zero or more links
+  // and either a non-link or the end of the string
+  // Used to filter out code fences from the source for comparison only.
+  // http://rubular.com/r/x5EwZVrloI
+  // Modified slightly due to issues with JS
   codeFencesPattern = /^`{3}(?:\s*\w+)?[\S\s].*[\S\s]^`{3}$/mg;
 
+  // ```
+  // followed by optional language
+  // whitespace
+  // code
+  // whitespace
+  // ```
+  // Used to filter out potential mismatches (items not in lists).
+  // http://rubular.com/r/OInl6CiePy
   itemsInParasPattern = RegExp("^(" + (escapePattern(complete)) + "|" + (escapePattern(incomplete)) + ").+$", "g");
 
+  // Given the source text, updates the appropriate task list item to match the
+  // given checked value.
+  //
+  // Returns the updated String text.
   updateTaskListItem = function(source, itemIndex, checked) {
     var clean, index, line, result;
     clean = source.replace(/\r/g, '').replace(codeFencesPattern, '').replace(itemsInParasPattern, '').split("\n");
@@ -55,6 +186,9 @@
     return result.join("\n");
   };
 
+  // Updates the $field value to reflect the state of $item.
+  // Triggers the `tasklist:change` event before the value has changed, and fires
+  // a `tasklist:changed` event once the value has changed.
   updateTaskList = function($item) {
     var $container, $field, checked, event, index;
     $container = $item.closest('.js-task-list-container');
@@ -70,10 +204,12 @@
     }
   };
 
+  // When the task list item checkbox is updated, submit the change
   $(document).on('change', '.task-list-item-checkbox', function() {
     return updateTaskList($(this));
   });
 
+  // Enables TaskList item changes.
   enableTaskList = function($container) {
     if ($container.find('.js-task-list-field').length > 0) {
       $container.find('.task-list-item').addClass('enabled').find('.task-list-item-checkbox').attr('disabled', null);
@@ -81,6 +217,7 @@
     }
   };
 
+  // Enables a collection of TaskList containers.
   enableTaskLists = function($containers) {
     var container, i, len, results;
     results = [];
@@ -91,11 +228,13 @@
     return results;
   };
 
+  // Disable TaskList item changes.
   disableTaskList = function($container) {
     $container.find('.task-list-item').removeClass('enabled').find('.task-list-item-checkbox').attr('disabled', 'disabled');
     return $container.removeClass('is-task-list-enabled').trigger('tasklist:disabled');
   };
 
+  // Disables a collection of TaskList containers.
   disableTaskLists = function($containers) {
     var container, i, len, results;
     results = [];