summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlfredo Sumaran <a.sumaran@gmail.com>2017-07-14 19:53:00 +0000
committerMike Greiling <mike@pixelcog.com>2017-08-10 22:28:24 -0500
commitd60a863d287f50dce058a748ddb34505b0088ec0 (patch)
tree96048cd3eb2a762508c4f7596faf0da21b4c9614
parentd9ed329b8c4282e8b722034df22dc1949e46c732 (diff)
downloadgitlab-ce-as-remove-iifes.tar.gz
Remove IIFE from various JS filesas-remove-iifes
-rw-r--r--app/assets/javascripts/admin.js116
-rw-r--r--app/assets/javascripts/aside.js40
-rw-r--r--app/assets/javascripts/autosave.js72
-rw-r--r--app/assets/javascripts/breakpoints.js111
-rw-r--r--app/assets/javascripts/build.js516
-rw-r--r--app/assets/javascripts/build_artifacts.js38
-rw-r--r--app/assets/javascripts/commit.js14
-rw-r--r--app/assets/javascripts/commit/file.js16
-rw-r--r--app/assets/javascripts/commit/image_file.js406
-rw-r--r--app/assets/javascripts/commits.js156
-rw-r--r--app/assets/javascripts/compare.js156
-rw-r--r--app/assets/javascripts/compare_autocomplete.js118
-rw-r--r--app/assets/javascripts/confirm_danger_modal.js48
-rw-r--r--app/assets/javascripts/dropzone_input.js556
-rw-r--r--app/assets/javascripts/flash.js120
-rw-r--r--app/assets/javascripts/group_avatar.js30
-rw-r--r--app/assets/javascripts/groups_select.js186
-rw-r--r--app/assets/javascripts/importer_status.js142
-rw-r--r--app/assets/javascripts/issuable_context.js134
-rw-r--r--app/assets/javascripts/issuable_form.js284
-rw-r--r--app/assets/javascripts/issuable_index.js312
-rw-r--r--app/assets/javascripts/issue_status_select.js59
-rw-r--r--app/assets/javascripts/label_manager.js209
-rw-r--r--app/assets/javascripts/labels.js73
-rw-r--r--app/assets/javascripts/labels_select.js884
-rw-r--r--app/assets/javascripts/layout_nav.js100
-rw-r--r--app/assets/javascripts/lib/utils/animate.js84
-rw-r--r--app/assets/javascripts/lib/utils/common_utils.js829
-rw-r--r--app/assets/javascripts/lib/utils/datetime_utility.js205
-rw-r--r--app/assets/javascripts/lib/utils/pretty_time.js122
-rw-r--r--app/assets/javascripts/logo.js8
-rw-r--r--app/assets/javascripts/member_expiration_date.js88
-rw-r--r--app/assets/javascripts/members.js124
-rw-r--r--app/assets/javascripts/merge_request.js232
-rw-r--r--app/assets/javascripts/merge_request_tabs.js616
-rw-r--r--app/assets/javascripts/milestone.js94
-rw-r--r--app/assets/javascripts/milestone_select.js416
-rw-r--r--app/assets/javascripts/namespace_select.js147
-rw-r--r--app/assets/javascripts/new_branch_form.js168
-rw-r--r--app/assets/javascripts/new_commit_form.js55
-rw-r--r--app/assets/javascripts/notifications_dropdown.js48
-rw-r--r--app/assets/javascripts/notifications_form.js92
-rw-r--r--app/assets/javascripts/pager.js134
-rw-r--r--app/assets/javascripts/preview_markdown.js350
-rw-r--r--app/assets/javascripts/project.js220
-rw-r--r--app/assets/javascripts/project_avatar.js32
-rw-r--r--app/assets/javascripts/project_find_file.js288
-rw-r--r--app/assets/javascripts/project_fork.js18
-rw-r--r--app/assets/javascripts/project_import.js16
-rw-r--r--app/assets/javascripts/project_label_subscription.js77
-rw-r--r--app/assets/javascripts/project_new.js272
-rw-r--r--app/assets/javascripts/project_select.js200
-rw-r--r--app/assets/javascripts/project_show.js11
-rw-r--r--app/assets/javascripts/project_variables.js60
-rw-r--r--app/assets/javascripts/render_gfm.js18
-rw-r--r--app/assets/javascripts/render_math.js78
-rw-r--r--app/assets/javascripts/right_sidebar.js404
-rw-r--r--app/assets/javascripts/search.js208
-rw-r--r--app/assets/javascripts/search_autocomplete.js739
-rw-r--r--app/assets/javascripts/shortcuts.js254
-rw-r--r--app/assets/javascripts/shortcuts_find_file.js52
-rw-r--r--app/assets/javascripts/shortcuts_issuable.js138
-rw-r--r--app/assets/javascripts/shortcuts_navigation.js50
-rw-r--r--app/assets/javascripts/shortcuts_network.js36
-rw-r--r--app/assets/javascripts/templates/issuable_template_selector.js100
-rw-r--r--app/assets/javascripts/templates/issuable_template_selectors.js48
-rw-r--r--app/assets/javascripts/u2f/authenticate.js186
-rw-r--r--app/assets/javascripts/u2f/error.js36
-rw-r--r--app/assets/javascripts/u2f/register.js148
-rw-r--r--app/assets/javascripts/u2f/util.js14
-rw-r--r--spec/javascripts/abuse_reports_spec.js78
-rw-r--r--spec/javascripts/activities_spec.js106
-rw-r--r--spec/javascripts/behaviors/autosize_spec.js28
-rw-r--r--spec/javascripts/behaviors/quick_submit_spec.js196
-rw-r--r--spec/javascripts/behaviors/requires_input_spec.js66
-rw-r--r--spec/javascripts/commits_spec.js104
-rw-r--r--spec/javascripts/copy_as_gfm_spec.js72
-rw-r--r--spec/javascripts/datetime_utility_spec.js172
-rw-r--r--spec/javascripts/extensions/array_spec.js28
-rw-r--r--spec/javascripts/lib/utils/common_utils_spec.js624
-rw-r--r--spec/javascripts/merge_request_spec.js86
-rw-r--r--spec/javascripts/merge_request_tabs_spec.js610
-rw-r--r--spec/javascripts/notes_spec.js1302
-rw-r--r--spec/javascripts/pretty_time_spec.js209
-rw-r--r--spec/javascripts/right_sidebar_spec.js146
-rw-r--r--spec/javascripts/search_autocomplete_spec.js328
-rw-r--r--spec/javascripts/shortcuts_issuable_spec.js120
-rw-r--r--spec/javascripts/smart_interval_spec.js277
-rw-r--r--spec/javascripts/syntax_highlight_spec.js72
-rw-r--r--spec/javascripts/u2f/authenticate_spec.js100
-rw-r--r--spec/javascripts/u2f/register_spec.js108
-rw-r--r--spec/javascripts/zen_mode_spec.js122
92 files changed, 8543 insertions, 8822 deletions
diff --git a/app/assets/javascripts/admin.js b/app/assets/javascripts/admin.js
index 34669dd13d6..a564643199c 100644
--- a/app/assets/javascripts/admin.js
+++ b/app/assets/javascripts/admin.js
@@ -1,62 +1,60 @@
/* eslint-disable func-names, space-before-function-paren, wrap-iife, one-var, no-var, one-var-declaration-per-line, no-unused-vars, no-else-return, prefer-arrow-callback, camelcase, quotes, comma-dangle, max-len */
-window.Admin = (function() {
- function Admin() {
- var modal, showBlacklistType;
- $('input#user_force_random_password').on('change', function(elem) {
- var elems;
- elems = $('#user_password, #user_password_confirmation');
- if ($(this).attr('checked')) {
- return elems.val('').attr('disabled', true);
- } else {
- return elems.removeAttr('disabled');
- }
- });
- $('body').on('click', '.js-toggle-colors-link', function(e) {
- e.preventDefault();
- return $('.js-toggle-colors-container').toggle();
- });
- $('.log-tabs a').click(function(e) {
- e.preventDefault();
- return $(this).tab('show');
- });
- $('.log-bottom').click(function(e) {
- var visible_log;
- e.preventDefault();
- visible_log = $(".file-content:visible");
- return visible_log.animate({
- scrollTop: visible_log.find('ol').height()
- }, "fast");
- });
- modal = $('.change-owner-holder');
- $('.change-owner-link').bind("click", function(e) {
- e.preventDefault();
- $(this).hide();
- return modal.show();
- });
- $('.change-owner-cancel-link').bind("click", function(e) {
- e.preventDefault();
- modal.hide();
- return $('.change-owner-link').show();
- });
- $('li.project_member').bind('ajax:success', function() {
- return gl.utils.refreshCurrentPage();
- });
- $('li.group_member').bind('ajax:success', function() {
- return gl.utils.refreshCurrentPage();
- });
- showBlacklistType = function() {
- if ($("input[name='blacklist_type']:checked").val() === 'file') {
- $('.blacklist-file').show();
- return $('.blacklist-raw').hide();
- } else {
- $('.blacklist-file').hide();
- return $('.blacklist-raw').show();
- }
- };
- $("input[name='blacklist_type']").click(showBlacklistType);
- showBlacklistType();
- }
+function Admin() {
+ var modal, showBlacklistType;
+ $('input#user_force_random_password').on('change', function(elem) {
+ var elems;
+ elems = $('#user_password, #user_password_confirmation');
+ if ($(this).attr('checked')) {
+ return elems.val('').attr('disabled', true);
+ } else {
+ return elems.removeAttr('disabled');
+ }
+ });
+ $('body').on('click', '.js-toggle-colors-link', function(e) {
+ e.preventDefault();
+ return $('.js-toggle-colors-container').toggle();
+ });
+ $('.log-tabs a').click(function(e) {
+ e.preventDefault();
+ return $(this).tab('show');
+ });
+ $('.log-bottom').click(function(e) {
+ var visible_log;
+ e.preventDefault();
+ visible_log = $(".file-content:visible");
+ return visible_log.animate({
+ scrollTop: visible_log.find('ol').height()
+ }, "fast");
+ });
+ modal = $('.change-owner-holder');
+ $('.change-owner-link').bind("click", function(e) {
+ e.preventDefault();
+ $(this).hide();
+ return modal.show();
+ });
+ $('.change-owner-cancel-link').bind("click", function(e) {
+ e.preventDefault();
+ modal.hide();
+ return $('.change-owner-link').show();
+ });
+ $('li.project_member').bind('ajax:success', function() {
+ return gl.utils.refreshCurrentPage();
+ });
+ $('li.group_member').bind('ajax:success', function() {
+ return gl.utils.refreshCurrentPage();
+ });
+ showBlacklistType = function() {
+ if ($("input[name='blacklist_type']:checked").val() === 'file') {
+ $('.blacklist-file').show();
+ return $('.blacklist-raw').hide();
+ } else {
+ $('.blacklist-file').hide();
+ return $('.blacklist-raw').show();
+ }
+ };
+ $("input[name='blacklist_type']").click(showBlacklistType);
+ showBlacklistType();
+}
- return Admin;
-})();
+window.Admin = Admin;
diff --git a/app/assets/javascripts/aside.js b/app/assets/javascripts/aside.js
index 88756884d16..bb45aa04ef8 100644
--- a/app/assets/javascripts/aside.js
+++ b/app/assets/javascripts/aside.js
@@ -1,24 +1,22 @@
/* eslint-disable func-names, space-before-function-paren, wrap-iife, quotes, prefer-arrow-callback, no-var, one-var, one-var-declaration-per-line, no-else-return, max-len */
-window.Aside = (function() {
- function Aside() {
- $(document).off("click", "a.show-aside");
- $(document).on("click", 'a.show-aside', function(e) {
- var btn, icon;
- e.preventDefault();
- btn = $(e.currentTarget);
- icon = btn.find('i');
- if (icon.hasClass('fa-angle-left')) {
- btn.parent().find('section').hide();
- btn.parent().find('aside').fadeIn();
- return icon.removeClass('fa-angle-left').addClass('fa-angle-right');
- } else {
- btn.parent().find('aside').hide();
- btn.parent().find('section').fadeIn();
- return icon.removeClass('fa-angle-right').addClass('fa-angle-left');
- }
- });
- }
+function Aside() {
+ $(document).off("click", "a.show-aside");
+ $(document).on("click", 'a.show-aside', function(e) {
+ var btn, icon;
+ e.preventDefault();
+ btn = $(e.currentTarget);
+ icon = btn.find('i');
+ if (icon.hasClass('fa-angle-left')) {
+ btn.parent().find('section').hide();
+ btn.parent().find('aside').fadeIn();
+ return icon.removeClass('fa-angle-left').addClass('fa-angle-right');
+ } else {
+ btn.parent().find('aside').hide();
+ btn.parent().find('section').fadeIn();
+ return icon.removeClass('fa-angle-right').addClass('fa-angle-left');
+ }
+ });
+}
- return Aside;
-})();
+window.Aside = Aside;
diff --git a/app/assets/javascripts/autosave.js b/app/assets/javascripts/autosave.js
index cfab6c40b34..a9fad9c64b0 100644
--- a/app/assets/javascripts/autosave.js
+++ b/app/assets/javascripts/autosave.js
@@ -1,55 +1,49 @@
/* eslint-disable func-names, space-before-function-paren, wrap-iife, no-param-reassign, quotes, prefer-template, no-var, one-var, no-unused-vars, one-var-declaration-per-line, no-void, consistent-return, no-empty, max-len */
import AccessorUtilities from './lib/utils/accessor';
-window.Autosave = (function() {
- function Autosave(field, key) {
- this.field = field;
- this.isLocalStorageAvailable = AccessorUtilities.isLocalStorageAccessSafe();
-
- if (key.join != null) {
- key = key.join("/");
- }
- this.key = "autosave/" + key;
- this.field.data("autosave", this);
- this.restore();
- this.field.on("input", (function(_this) {
- return function() {
- return _this.save();
- };
- })(this));
+function Autosave(field, key) {
+ this.field = field;
+ this.isLocalStorageAvailable = AccessorUtilities.isLocalStorageAccessSafe();
+
+ if (key.join != null) {
+ key = key.join("/");
}
+ this.key = "autosave/" + key;
+ this.field.data("autosave", this);
+ this.restore();
+ this.field.on("input", () => this.save());
+}
- Autosave.prototype.restore = function() {
- var text;
+Autosave.prototype.restore = function() {
+ var text;
- if (!this.isLocalStorageAvailable) return;
+ if (!this.isLocalStorageAvailable) return;
- text = window.localStorage.getItem(this.key);
+ text = window.localStorage.getItem(this.key);
- if ((text != null ? text.length : void 0) > 0) {
- this.field.val(text);
- }
- return this.field.trigger("input");
- };
+ if ((text != null ? text.length : void 0) > 0) {
+ this.field.val(text);
+ }
+ return this.field.trigger("input");
+};
- Autosave.prototype.save = function() {
- var text;
- text = this.field.val();
+Autosave.prototype.save = function() {
+ var text;
+ text = this.field.val();
- if (this.isLocalStorageAvailable && (text != null ? text.length : void 0) > 0) {
- return window.localStorage.setItem(this.key, text);
- }
+ if (this.isLocalStorageAvailable && (text != null ? text.length : void 0) > 0) {
+ return window.localStorage.setItem(this.key, text);
+ }
- return this.reset();
- };
+ return this.reset();
+};
- Autosave.prototype.reset = function() {
- if (!this.isLocalStorageAvailable) return;
+Autosave.prototype.reset = function() {
+ if (!this.isLocalStorageAvailable) return;
- return window.localStorage.removeItem(this.key);
- };
+ return window.localStorage.removeItem(this.key);
+};
- return Autosave;
-})();
+window.Autosave = Autosave;
export default window.Autosave;
diff --git a/app/assets/javascripts/breakpoints.js b/app/assets/javascripts/breakpoints.js
index 2c1f988d987..8b28462e851 100644
--- a/app/assets/javascripts/breakpoints.js
+++ b/app/assets/javascripts/breakpoints.js
@@ -1,65 +1,56 @@
/* eslint-disable func-names, space-before-function-paren, wrap-iife, one-var, no-var, one-var-declaration-per-line, quotes, no-shadow, prefer-arrow-callback, prefer-template, consistent-return, no-return-assign, new-parens, no-param-reassign, max-len */
-var Breakpoints = (function() {
- var BreakpointInstance, instance;
-
- function Breakpoints() {}
-
- instance = null;
-
- BreakpointInstance = (function() {
- var BREAKPOINTS;
-
- BREAKPOINTS = ["xs", "sm", "md", "lg"];
-
- function BreakpointInstance() {
- this.setup();
- }
-
- BreakpointInstance.prototype.setup = function() {
- var allDeviceSelector, els;
- allDeviceSelector = BREAKPOINTS.map(function(breakpoint) {
- return ".device-" + breakpoint;
- });
- if ($(allDeviceSelector.join(",")).length) {
- return;
- }
- // Create all the elements
- els = $.map(BREAKPOINTS, function(breakpoint) {
- return "<div class='device-" + breakpoint + " visible-" + breakpoint + "'></div>";
- });
- return $("body").append(els.join(''));
- };
-
- BreakpointInstance.prototype.visibleDevice = function() {
- var allDeviceSelector;
- allDeviceSelector = BREAKPOINTS.map(function(breakpoint) {
- return ".device-" + breakpoint;
- });
- return $(allDeviceSelector.join(",")).filter(":visible");
- };
-
- BreakpointInstance.prototype.getBreakpointSize = function() {
- var $visibleDevice;
- $visibleDevice = this.visibleDevice;
- // TODO: Consider refactoring in light of turbolinks removal.
- // the page refreshed via turbolinks
- if (!$visibleDevice().length) {
- this.setup();
- }
- $visibleDevice = this.visibleDevice();
- return $visibleDevice.attr("class").split("visible-")[1];
- };
-
- return BreakpointInstance;
- })();
-
- Breakpoints.get = function() {
- return instance != null ? instance : instance = new BreakpointInstance;
- };
-
- return Breakpoints;
-})();
+var instance, BREAKPOINTS;
+
+instance = null;
+BREAKPOINTS = ["xs", "sm", "md", "lg"];
+
+// BreakpointInstance
+function BreakpointInstance() {
+ this.setup();
+}
+
+BreakpointInstance.prototype.setup = function() {
+ var allDeviceSelector, els;
+ allDeviceSelector = BREAKPOINTS.map(function(breakpoint) {
+ return ".device-" + breakpoint;
+ });
+ if ($(allDeviceSelector.join(",")).length) {
+ return;
+ }
+ // Create all the elements
+ els = $.map(BREAKPOINTS, function(breakpoint) {
+ return "<div class='device-" + breakpoint + " visible-" + breakpoint + "'></div>";
+ });
+ return $("body").append(els.join(''));
+};
+
+BreakpointInstance.prototype.visibleDevice = function() {
+ var allDeviceSelector;
+ allDeviceSelector = BREAKPOINTS.map(function(breakpoint) {
+ return ".device-" + breakpoint;
+ });
+ return $(allDeviceSelector.join(",")).filter(":visible");
+};
+
+BreakpointInstance.prototype.getBreakpointSize = function() {
+ var $visibleDevice;
+ $visibleDevice = this.visibleDevice;
+ // TODO: Consider refactoring in light of turbolinks removal.
+ // the page refreshed via turbolinks
+ if (!$visibleDevice().length) {
+ this.setup();
+ }
+ $visibleDevice = this.visibleDevice();
+ return $visibleDevice.attr("class").split("visible-")[1];
+};
+
+// Breakpoints
+function Breakpoints() {}
+
+Breakpoints.get = function() {
+ return instance != null ? instance : instance = new BreakpointInstance;
+};
$(() => { window.bp = Breakpoints.get(); });
diff --git a/app/assets/javascripts/build.js b/app/assets/javascripts/build.js
index 1dfa064acfd..85a967180e1 100644
--- a/app/assets/javascripts/build.js
+++ b/app/assets/javascripts/build.js
@@ -5,287 +5,285 @@ consistent-return, prefer-rest-params */
import _ from 'underscore';
import { bytesToKiB } from './lib/utils/number_utils';
-window.Build = (function () {
- Build.timeout = null;
- Build.state = null;
-
- function Build(options) {
- this.options = options || $('.js-build-options').data();
-
- this.pageUrl = this.options.pageUrl;
- this.buildStatus = this.options.buildStatus;
- this.state = this.options.logState;
- this.buildStage = this.options.buildStage;
- this.$document = $(document);
- this.logBytes = 0;
- this.hasBeenScrolled = false;
-
- this.updateDropdown = this.updateDropdown.bind(this);
- this.getBuildTrace = this.getBuildTrace.bind(this);
-
- this.$buildTrace = $('#build-trace');
- this.$buildRefreshAnimation = $('.js-build-refresh');
- this.$truncatedInfo = $('.js-truncated-info');
- this.$buildTraceOutput = $('.js-build-output');
- this.$topBar = $('.js-top-bar');
-
- // Scroll controllers
- this.$scrollTopBtn = $('.js-scroll-up');
- this.$scrollBottomBtn = $('.js-scroll-down');
-
- clearTimeout(Build.timeout);
- // Init breakpoint checker
- this.bp = Breakpoints.get();
-
- this.initSidebar();
- this.populateJobs(this.buildStage);
- this.updateStageDropdownText(this.buildStage);
- this.sidebarOnResize();
-
- this.$document
- .off('click', '.js-sidebar-build-toggle')
- .on('click', '.js-sidebar-build-toggle', this.sidebarOnClick.bind(this));
-
- this.$document
- .off('click', '.stage-item')
- .on('click', '.stage-item', this.updateDropdown);
-
- // add event listeners to the scroll buttons
- this.$scrollTopBtn
- .off('click')
- .on('click', this.scrollToTop.bind(this));
-
- this.$scrollBottomBtn
- .off('click')
- .on('click', this.scrollToBottom.bind(this));
-
- this.scrollThrottled = _.throttle(this.toggleScroll.bind(this), 100);
-
- $(window)
- .off('scroll')
- .on('scroll', () => {
- const contentHeight = this.$buildTraceOutput.prop('scrollHeight');
- if (contentHeight > this.windowSize) {
- // means the user did not scroll, the content was updated.
- this.windowSize = contentHeight;
- } else {
- // User scrolled
- this.hasBeenScrolled = true;
- this.toggleScrollAnimation(false);
- }
+function Build(options) {
+ this.options = options || $('.js-build-options').data();
+
+ this.pageUrl = this.options.pageUrl;
+ this.buildStatus = this.options.buildStatus;
+ this.state = this.options.logState;
+ this.buildStage = this.options.buildStage;
+ this.$document = $(document);
+ this.logBytes = 0;
+ this.hasBeenScrolled = false;
+
+ this.updateDropdown = this.updateDropdown.bind(this);
+ this.getBuildTrace = this.getBuildTrace.bind(this);
+
+ this.$buildTrace = $('#build-trace');
+ this.$buildRefreshAnimation = $('.js-build-refresh');
+ this.$truncatedInfo = $('.js-truncated-info');
+ this.$buildTraceOutput = $('.js-build-output');
+ this.$topBar = $('.js-top-bar');
+
+ // Scroll controllers
+ this.$scrollTopBtn = $('.js-scroll-up');
+ this.$scrollBottomBtn = $('.js-scroll-down');
+
+ clearTimeout(Build.timeout);
+ // Init breakpoint checker
+ this.bp = Breakpoints.get();
+
+ this.initSidebar();
+ this.populateJobs(this.buildStage);
+ this.updateStageDropdownText(this.buildStage);
+ this.sidebarOnResize();
+
+ this.$document
+ .off('click', '.js-sidebar-build-toggle')
+ .on('click', '.js-sidebar-build-toggle', this.sidebarOnClick.bind(this));
+
+ this.$document
+ .off('click', '.stage-item')
+ .on('click', '.stage-item', this.updateDropdown);
+
+ // add event listeners to the scroll buttons
+ this.$scrollTopBtn
+ .off('click')
+ .on('click', this.scrollToTop.bind(this));
+
+ this.$scrollBottomBtn
+ .off('click')
+ .on('click', this.scrollToBottom.bind(this));
+
+ this.scrollThrottled = _.throttle(this.toggleScroll.bind(this), 100);
+
+ $(window)
+ .off('scroll')
+ .on('scroll', () => {
+ const contentHeight = this.$buildTraceOutput.prop('scrollHeight');
+ if (contentHeight > this.windowSize) {
+ // means the user did not scroll, the content was updated.
+ this.windowSize = contentHeight;
+ } else {
+ // User scrolled
+ this.hasBeenScrolled = true;
+ this.toggleScrollAnimation(false);
+ }
- this.scrollThrottled();
- });
+ this.scrollThrottled();
+ });
- $(window)
- .off('resize.build')
- .on('resize.build', _.throttle(this.sidebarOnResize.bind(this), 100));
+ $(window)
+ .off('resize.build')
+ .on('resize.build', _.throttle(this.sidebarOnResize.bind(this), 100));
- this.updateArtifactRemoveDate();
- this.initAffixTopArea();
+ this.updateArtifactRemoveDate();
+ this.initAffixTopArea();
- this.getBuildTrace();
- }
+ this.getBuildTrace();
+}
- Build.prototype.initAffixTopArea = function () {
- /**
- If the browser does not support position sticky, it returns the position as static.
- If the browser does support sticky, then we allow the browser to handle it, if not
- then we default back to Bootstraps affix
- **/
- if (this.$topBar.css('position') !== 'static') return;
+Build.timeout = null;
+Build.state = null;
- const offsetTop = this.$buildTrace.offset().top;
+Build.prototype.initAffixTopArea = function () {
+ /**
+ If the browser does not support position sticky, it returns the position as static.
+ If the browser does support sticky, then we allow the browser to handle it, if not
+ then we default back to Bootstraps affix
+ **/
+ if (this.$topBar.css('position') !== 'static') return;
- this.$topBar.affix({
- offset: {
- top: offsetTop,
- },
- });
- };
+ const offsetTop = this.$buildTrace.offset().top;
- Build.prototype.canScroll = function () {
- return document.body.scrollHeight > window.innerHeight;
- };
+ this.$topBar.affix({
+ offset: {
+ top: offsetTop,
+ },
+ });
+};
- Build.prototype.toggleScroll = function () {
- const currentPosition = document.body.scrollTop;
- const windowHeight = window.innerHeight;
+Build.prototype.canScroll = function () {
+ return document.body.scrollHeight > window.innerHeight;
+};
- if (this.canScroll()) {
- if (currentPosition > 0 &&
- (document.body.scrollHeight - currentPosition !== windowHeight)) {
- // User is in the middle of the log
+Build.prototype.toggleScroll = function () {
+ const currentPosition = document.body.scrollTop;
+ const windowHeight = window.innerHeight;
- this.toggleDisableButton(this.$scrollTopBtn, false);
- this.toggleDisableButton(this.$scrollBottomBtn, false);
- } else if (currentPosition === 0) {
- // User is at Top of Build Log
+ if (this.canScroll()) {
+ if (currentPosition > 0 &&
+ (document.body.scrollHeight - currentPosition !== windowHeight)) {
+ // User is in the middle of the log
- this.toggleDisableButton(this.$scrollTopBtn, true);
- this.toggleDisableButton(this.$scrollBottomBtn, false);
- } else if (document.body.scrollHeight - currentPosition === windowHeight) {
- // User is at the bottom of the build log.
+ this.toggleDisableButton(this.$scrollTopBtn, false);
+ this.toggleDisableButton(this.$scrollBottomBtn, false);
+ } else if (currentPosition === 0) {
+ // User is at Top of Build Log
- this.toggleDisableButton(this.$scrollTopBtn, false);
- this.toggleDisableButton(this.$scrollBottomBtn, true);
- }
- } else {
this.toggleDisableButton(this.$scrollTopBtn, true);
+ this.toggleDisableButton(this.$scrollBottomBtn, false);
+ } else if (document.body.scrollHeight - currentPosition === windowHeight) {
+ // User is at the bottom of the build log.
+
+ this.toggleDisableButton(this.$scrollTopBtn, false);
this.toggleDisableButton(this.$scrollBottomBtn, true);
}
- };
-
- Build.prototype.scrollDown = function () {
- document.body.scrollTop = document.body.scrollHeight;
- };
-
- Build.prototype.scrollToBottom = function () {
- this.scrollDown();
- this.hasBeenScrolled = true;
- this.toggleScroll();
- };
-
- Build.prototype.scrollToTop = function () {
- document.body.scrollTop = 0;
- this.hasBeenScrolled = true;
- this.toggleScroll();
- };
-
- Build.prototype.toggleDisableButton = function ($button, disable) {
- if (disable && $button.prop('disabled')) return;
- $button.prop('disabled', disable);
- };
-
- Build.prototype.toggleScrollAnimation = function (toggle) {
- this.$scrollBottomBtn.toggleClass('animate', toggle);
- };
-
- Build.prototype.initSidebar = function () {
- this.$sidebar = $('.js-build-sidebar');
- this.$sidebar.niceScroll();
- };
-
- Build.prototype.getBuildTrace = function () {
- return $.ajax({
- url: `${this.pageUrl}/trace.json`,
- data: this.state,
- })
- .done((log) => {
- gl.utils.setCiStatusFavicon(`${this.pageUrl}/status.json`);
-
- if (log.state) {
- this.state = log.state;
- }
-
- this.windowSize = this.$buildTraceOutput.prop('scrollHeight');
+ } else {
+ this.toggleDisableButton(this.$scrollTopBtn, true);
+ this.toggleDisableButton(this.$scrollBottomBtn, true);
+ }
+};
+
+Build.prototype.scrollDown = function () {
+ document.body.scrollTop = document.body.scrollHeight;
+};
+
+Build.prototype.scrollToBottom = function () {
+ this.scrollDown();
+ this.hasBeenScrolled = true;
+ this.toggleScroll();
+};
+
+Build.prototype.scrollToTop = function () {
+ document.body.scrollTop = 0;
+ this.hasBeenScrolled = true;
+ this.toggleScroll();
+};
+
+Build.prototype.toggleDisableButton = function ($button, disable) {
+ if (disable && $button.prop('disabled')) return;
+ $button.prop('disabled', disable);
+};
+
+Build.prototype.toggleScrollAnimation = function (toggle) {
+ this.$scrollBottomBtn.toggleClass('animate', toggle);
+};
+
+Build.prototype.initSidebar = function () {
+ this.$sidebar = $('.js-build-sidebar');
+ this.$sidebar.niceScroll();
+};
+
+Build.prototype.getBuildTrace = function () {
+ return $.ajax({
+ url: `${this.pageUrl}/trace.json`,
+ data: this.state,
+ })
+ .done((log) => {
+ gl.utils.setCiStatusFavicon(`${this.pageUrl}/status.json`);
+
+ if (log.state) {
+ this.state = log.state;
+ }
- if (log.append) {
- this.$buildTraceOutput.append(log.html);
- this.logBytes += log.size;
- } else {
- this.$buildTraceOutput.html(log.html);
- this.logBytes = log.size;
- }
+ this.windowSize = this.$buildTraceOutput.prop('scrollHeight');
- // if the incremental sum of logBytes we received is less than the total
- // we need to show a message warning the user about that.
- if (this.logBytes < log.total) {
- // size is in bytes, we need to calculate KiB
- const size = bytesToKiB(this.logBytes);
- $('.js-truncated-info-size').html(`${size}`);
- this.$truncatedInfo.removeClass('hidden');
- } else {
- this.$truncatedInfo.addClass('hidden');
- }
+ if (log.append) {
+ this.$buildTraceOutput.append(log.html);
+ this.logBytes += log.size;
+ } else {
+ this.$buildTraceOutput.html(log.html);
+ this.logBytes = log.size;
+ }
- if (!log.complete) {
- if (!this.hasBeenScrolled) {
- this.toggleScrollAnimation(true);
- } else {
- this.toggleScrollAnimation(false);
- }
+ // if the incremental sum of logBytes we received is less than the total
+ // we need to show a message warning the user about that.
+ if (this.logBytes < log.total) {
+ // size is in bytes, we need to calculate KiB
+ const size = bytesToKiB(this.logBytes);
+ $('.js-truncated-info-size').html(`${size}`);
+ this.$truncatedInfo.removeClass('hidden');
+ } else {
+ this.$truncatedInfo.addClass('hidden');
+ }
- Build.timeout = setTimeout(() => {
- this.getBuildTrace();
- }, 4000);
+ if (!log.complete) {
+ if (!this.hasBeenScrolled) {
+ this.toggleScrollAnimation(true);
} else {
- this.$buildRefreshAnimation.remove();
this.toggleScrollAnimation(false);
}
- if (log.status !== this.buildStatus) {
- gl.utils.visitUrl(this.pageUrl);
- }
- })
- .fail(() => {
+ Build.timeout = setTimeout(() => {
+ this.getBuildTrace();
+ }, 4000);
+ } else {
this.$buildRefreshAnimation.remove();
- })
- .then(() => {
- if (!this.hasBeenScrolled) {
- this.scrollDown();
- }
- })
- .then(() => this.toggleScroll());
- };
-
- Build.prototype.shouldHideSidebarForViewport = function () {
- const bootstrapBreakpoint = this.bp.getBreakpointSize();
- return bootstrapBreakpoint === 'xs' || bootstrapBreakpoint === 'sm';
- };
-
- Build.prototype.toggleSidebar = function (shouldHide) {
- const shouldShow = typeof shouldHide === 'boolean' ? !shouldHide : undefined;
- const $toggleButton = $('.js-sidebar-build-toggle-header');
-
- this.$sidebar
- .toggleClass('right-sidebar-expanded', shouldShow)
- .toggleClass('right-sidebar-collapsed', shouldHide);
-
- this.$topBar
- .toggleClass('sidebar-expanded', shouldShow)
- .toggleClass('sidebar-collapsed', shouldHide);
-
- if (this.$sidebar.hasClass('right-sidebar-expanded')) {
- $toggleButton.addClass('hidden');
- } else {
- $toggleButton.removeClass('hidden');
- }
- };
-
- Build.prototype.sidebarOnResize = function () {
- this.toggleSidebar(this.shouldHideSidebarForViewport());
- };
-
- Build.prototype.sidebarOnClick = function () {
- if (this.shouldHideSidebarForViewport()) this.toggleSidebar();
- };
-
- Build.prototype.updateArtifactRemoveDate = function () {
- const $date = $('.js-artifacts-remove');
- if ($date.length) {
- const date = $date.text();
- return $date.text(
- gl.utils.timeFor(new Date(date.replace(/([0-9]+)-([0-9]+)-([0-9]+)/g, '$1/$2/$3')), ' '),
- );
- }
- };
-
- Build.prototype.populateJobs = function (stage) {
- $('.build-job').hide();
- $(`.build-job[data-stage="${stage}"]`).show();
- };
-
- Build.prototype.updateStageDropdownText = function (stage) {
- $('.stage-selection').text(stage);
- };
-
- Build.prototype.updateDropdown = function (e) {
- e.preventDefault();
- const stage = e.currentTarget.text;
- this.updateStageDropdownText(stage);
- this.populateJobs(stage);
- };
-
- return Build;
-})();
+ this.toggleScrollAnimation(false);
+ }
+
+ if (log.status !== this.buildStatus) {
+ gl.utils.visitUrl(this.pageUrl);
+ }
+ })
+ .fail(() => {
+ this.$buildRefreshAnimation.remove();
+ })
+ .then(() => {
+ if (!this.hasBeenScrolled) {
+ this.scrollDown();
+ }
+ })
+ .then(() => this.toggleScroll());
+};
+
+Build.prototype.shouldHideSidebarForViewport = function () {
+ const bootstrapBreakpoint = this.bp.getBreakpointSize();
+ return bootstrapBreakpoint === 'xs' || bootstrapBreakpoint === 'sm';
+};
+
+Build.prototype.toggleSidebar = function (shouldHide) {
+ const shouldShow = typeof shouldHide === 'boolean' ? !shouldHide : undefined;
+ const $toggleButton = $('.js-sidebar-build-toggle-header');
+
+ this.$sidebar
+ .toggleClass('right-sidebar-expanded', shouldShow)
+ .toggleClass('right-sidebar-collapsed', shouldHide);
+
+ this.$topBar
+ .toggleClass('sidebar-expanded', shouldShow)
+ .toggleClass('sidebar-collapsed', shouldHide);
+
+ if (this.$sidebar.hasClass('right-sidebar-expanded')) {
+ $toggleButton.addClass('hidden');
+ } else {
+ $toggleButton.removeClass('hidden');
+ }
+};
+
+Build.prototype.sidebarOnResize = function () {
+ this.toggleSidebar(this.shouldHideSidebarForViewport());
+};
+
+Build.prototype.sidebarOnClick = function () {
+ if (this.shouldHideSidebarForViewport()) this.toggleSidebar();
+};
+
+Build.prototype.updateArtifactRemoveDate = function () {
+ const $date = $('.js-artifacts-remove');
+ if ($date.length) {
+ const date = $date.text();
+ return $date.text(
+ gl.utils.timeFor(new Date(date.replace(/([0-9]+)-([0-9]+)-([0-9]+)/g, '$1/$2/$3')), ' '),
+ );
+ }
+};
+
+Build.prototype.populateJobs = function (stage) {
+ $('.build-job').hide();
+ $(`.build-job[data-stage="${stage}"]`).show();
+};
+
+Build.prototype.updateStageDropdownText = function (stage) {
+ $('.stage-selection').text(stage);
+};
+
+Build.prototype.updateDropdown = function (e) {
+ e.preventDefault();
+ const stage = e.currentTarget.text;
+ this.updateStageDropdownText(stage);
+ this.populateJobs(stage);
+};
+
+window.Build = Build;
diff --git a/app/assets/javascripts/build_artifacts.js b/app/assets/javascripts/build_artifacts.js
index bd479700fd3..ed9ad3c6c57 100644
--- a/app/assets/javascripts/build_artifacts.js
+++ b/app/assets/javascripts/build_artifacts.js
@@ -1,25 +1,23 @@
/* eslint-disable func-names, space-before-function-paren, wrap-iife, prefer-arrow-callback, no-unused-vars, no-return-assign, max-len */
-window.BuildArtifacts = (function() {
- function BuildArtifacts() {
- this.disablePropagation();
- this.setupEntryClick();
- }
+function BuildArtifacts() {
+ this.disablePropagation();
+ this.setupEntryClick();
+}
- BuildArtifacts.prototype.disablePropagation = function() {
- $('.top-block').on('click', '.download', function(e) {
- return e.stopPropagation();
- });
- return $('.tree-holder').on('click', 'tr[data-link] a', function(e) {
- return e.stopImmediatePropagation();
- });
- };
+BuildArtifacts.prototype.disablePropagation = function() {
+ $('.top-block').on('click', '.download', function(e) {
+ return e.stopPropagation();
+ });
+ return $('.tree-holder').on('click', 'tr[data-link] a', function(e) {
+ return e.stopImmediatePropagation();
+ });
+};
- BuildArtifacts.prototype.setupEntryClick = function() {
- return $('.tree-holder').on('click', 'tr[data-link]', function(e) {
- return window.location = this.dataset.link;
- });
- };
+BuildArtifacts.prototype.setupEntryClick = function() {
+ return $('.tree-holder').on('click', 'tr[data-link]', function(e) {
+ return window.location = this.dataset.link;
+ });
+};
- return BuildArtifacts;
-})();
+window.BuildArtifacts = BuildArtifacts;
diff --git a/app/assets/javascripts/commit.js b/app/assets/javascripts/commit.js
index 5f637524e30..e3f8355915a 100644
--- a/app/assets/javascripts/commit.js
+++ b/app/assets/javascripts/commit.js
@@ -1,12 +1,10 @@
/* eslint-disable func-names, space-before-function-paren, wrap-iife */
/* global CommitFile */
-window.Commit = (function() {
- function Commit() {
- $('.files .diff-file').each(function() {
- return new CommitFile(this);
- });
- }
+function Commit() {
+ $('.files .diff-file').each(function() {
+ return new CommitFile(this);
+ });
+}
- return Commit;
-})();
+window.Commit = Commit;
diff --git a/app/assets/javascripts/commit/file.js b/app/assets/javascripts/commit/file.js
index ee087c978dd..28e5e06b155 100644
--- a/app/assets/javascripts/commit/file.js
+++ b/app/assets/javascripts/commit/file.js
@@ -1,14 +1,10 @@
/* eslint-disable func-names, space-before-function-paren, wrap-iife, no-new */
/* global ImageFile */
-(function() {
- this.CommitFile = (function() {
- function CommitFile(file) {
- if ($('.image', file).length) {
- new gl.ImageFile(file);
- }
- }
+function CommitFile(file) {
+ if ($('.image', file).length) {
+ new gl.ImageFile(file);
+ }
+}
- return CommitFile;
- })();
-}).call(window);
+window.CommitFile = CommitFile;
diff --git a/app/assets/javascripts/commit/image_file.js b/app/assets/javascripts/commit/image_file.js
index 17d14dc1e79..b768ba5b17b 100644
--- a/app/assets/javascripts/commit/image_file.js
+++ b/app/assets/javascripts/commit/image_file.js
@@ -1,211 +1,209 @@
/* eslint-disable func-names, space-before-function-paren, wrap-iife, no-var, no-use-before-define, prefer-arrow-callback, no-else-return, consistent-return, prefer-template, quotes, one-var, one-var-declaration-per-line, no-unused-vars, no-return-assign, comma-dangle, quote-props, no-unused-expressions, no-sequences, object-shorthand, max-len */
-(function() {
- gl.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'];
-
- 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) {
- return _this.initViewModes();
- } else {
- return _this.initView('two-up');
- }
- });
- };
- })(this));
- }
-
- ImageFile.prototype.initViewModes = function() {
- var viewMode;
- viewMode = ImageFile.viewModes[0];
- $('.view-modes', this.file).removeClass('hide');
- $('.view-modes-menu', this.file).on('click', 'li', (function(_this) {
- return function(event) {
- if (!$(event.currentTarget).hasClass('active')) {
- return _this.activateViewMode(event.currentTarget.className);
- }
- };
- })(this));
- return this.activateViewMode(viewMode);
- };
-
- ImageFile.prototype.activateViewMode = function(viewMode) {
- $('.view-modes-menu li', this.file).removeClass('active').filter("." + viewMode).addClass('active');
- return $(".view:visible:not(." + viewMode + ")", this.file).fadeOut(200, (function(_this) {
- return function() {
- $(".view." + viewMode, _this.file).fadeIn(200);
- return _this.initView(viewMode);
- };
- })(this));
- };
-
- ImageFile.prototype.initView = function(viewMode) {
- return this.views[viewMode].call(this);
- };
-
- ImageFile.prototype.initDraggable = function($el, padding, callback) {
- var dragging = false;
- var $body = $('body');
- var $offsetEl = $el.parent();
-
- $el.off('mousedown').on('mousedown', function() {
- dragging = true;
- $body.css('user-select', 'none');
- });
-
- $body.off('mouseup').off('mousemove').on('mouseup', function() {
- dragging = false;
- $body.css('user-select', '');
- })
- .on('mousemove', function(e) {
- var left;
- if (!dragging) return;
-
- left = e.pageX - ($offsetEl.offset().left + padding);
-
- callback(e, left);
- });
- };
-
- prepareFrames = function(view) {
- var maxHeight, maxWidth;
- maxWidth = 0;
- maxHeight = 0;
- $('.frame', view).each((function(_this) {
- return function(index, frame) {
- var height, width;
- width = $(frame).width();
- height = $(frame).height();
- maxWidth = width > maxWidth ? width : maxWidth;
- return maxHeight = height > maxHeight ? height : maxHeight;
- };
- })(this)).css({
- width: maxWidth,
- height: maxHeight
+var prepareFrames;
+
+const global = window.gl || (window.gl = {});
+
+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) {
+ return _this.initViewModes();
+ } else {
+ return _this.initView('two-up');
+ }
});
- return [maxWidth, maxHeight];
};
-
- ImageFile.prototype.views = {
- 'two-up': function() {
- return $('.two-up.view .wrap', this.file).each((function(_this) {
- return function(index, wrap) {
- $('img', wrap).each(function() {
- var currentWidth;
- currentWidth = $(this).width();
- if (currentWidth > ImageFile.availWidth / 2) {
- return $(this).width(ImageFile.availWidth / 2);
- }
- });
- return _this.requestImageInfo($('img', wrap), function(width, height) {
- $('.image-info .meta-width', wrap).text(width + "px");
- $('.image-info .meta-height', wrap).text(height + "px");
- return $('.image-info', wrap).removeClass('hide');
- });
- };
- })(this));
- },
- 'swipe': function() {
- var maxHeight, maxWidth;
- maxWidth = 0;
- maxHeight = 0;
- return $('.swipe.view', this.file).each((function(_this) {
- return function(index, view) {
- var $swipeWrap, $swipeBar, $swipeFrame, wrapPadding, ref;
- ref = prepareFrames(view), maxWidth = ref[0], maxHeight = ref[1];
- $swipeFrame = $('.swipe-frame', view);
- $swipeWrap = $('.swipe-wrap', view);
- $swipeBar = $('.swipe-bar', view);
-
- $swipeFrame.css({
- width: maxWidth + 16,
- height: maxHeight + 28
- });
- $swipeWrap.css({
- width: maxWidth + 1,
- height: maxHeight + 2
- });
- $swipeBar.css({
- left: 0
- });
-
- wrapPadding = parseInt($swipeWrap.css('right').replace('px', ''), 10);
-
- _this.initDraggable($swipeBar, wrapPadding, function(e, left) {
- if (left > 0 && left < $swipeFrame.width() - (wrapPadding * 2)) {
- $swipeWrap.width((maxWidth + 1) - left);
- $swipeBar.css('left', left);
- }
- });
- };
- })(this));
- },
- 'onion-skin': function() {
- var dragTrackWidth, maxHeight, maxWidth;
- maxWidth = 0;
- maxHeight = 0;
- dragTrackWidth = $('.drag-track', this.file).width() - $('.dragger', this.file).width();
- return $('.onion-skin.view', this.file).each((function(_this) {
- return function(index, view) {
- var $frame, $track, $dragger, $frameAdded, framePadding, ref, dragging = false;
- ref = prepareFrames(view), maxWidth = ref[0], maxHeight = ref[1];
- $frame = $('.onion-skin-frame', view);
- $frameAdded = $('.frame.added', view);
- $track = $('.drag-track', view);
- $dragger = $('.dragger', $track);
-
- $frame.css({
- width: maxWidth + 16,
- height: maxHeight + 28
- });
- $('.swipe-wrap', view).css({
- width: maxWidth + 1,
- height: maxHeight + 2
- });
- $dragger.css({
- left: dragTrackWidth
- });
-
- framePadding = parseInt($frameAdded.css('right').replace('px', ''), 10);
-
- _this.initDraggable($dragger, framePadding, function(e, left) {
- var opacity = left / dragTrackWidth;
-
- if (opacity >= 0 && opacity <= 1) {
- $dragger.css('left', left);
- $frameAdded.css('opacity', opacity);
- }
- });
- };
- })(this));
+ })(this));
+}
+
+// Width where images must fits in, for 2-up this gets divided by 2
+ImageFile.availWidth = 900;
+
+ImageFile.viewModes = ['two-up', 'swipe'];
+
+ImageFile.prototype.initViewModes = function() {
+ var viewMode;
+ viewMode = ImageFile.viewModes[0];
+ $('.view-modes', this.file).removeClass('hide');
+ $('.view-modes-menu', this.file).on('click', 'li', (function(_this) {
+ return function(event) {
+ if (!$(event.currentTarget).hasClass('active')) {
+ return _this.activateViewMode(event.currentTarget.className);
}
};
-
- ImageFile.prototype.requestImageInfo = function(img, callback) {
- var domImg;
- domImg = img.get(0);
- if (domImg) {
- if (domImg.complete) {
- return callback.call(this, domImg.naturalWidth, domImg.naturalHeight);
- } else {
- return img.on('load', (function(_this) {
- return function() {
- return callback.call(_this, domImg.naturalWidth, domImg.naturalHeight);
- };
- })(this));
- }
- }
+ })(this));
+ return this.activateViewMode(viewMode);
+};
+
+ImageFile.prototype.activateViewMode = function(viewMode) {
+ $('.view-modes-menu li', this.file).removeClass('active').filter("." + viewMode).addClass('active');
+ return $(".view:visible:not(." + viewMode + ")", this.file).fadeOut(200, (function(_this) {
+ return function() {
+ $(".view." + viewMode, _this.file).fadeIn(200);
+ return _this.initView(viewMode);
+ };
+ })(this));
+};
+
+ImageFile.prototype.initView = function(viewMode) {
+ return this.views[viewMode].call(this);
+};
+
+ImageFile.prototype.initDraggable = function($el, padding, callback) {
+ var dragging = false;
+ var $body = $('body');
+ var $offsetEl = $el.parent();
+
+ $el.off('mousedown').on('mousedown', function() {
+ dragging = true;
+ $body.css('user-select', 'none');
+ });
+
+ $body.off('mouseup').off('mousemove').on('mouseup', function() {
+ dragging = false;
+ $body.css('user-select', '');
+ })
+ .on('mousemove', function(e) {
+ var left;
+ if (!dragging) return;
+
+ left = e.pageX - ($offsetEl.offset().left + padding);
+
+ callback(e, left);
+ });
+};
+
+prepareFrames = function(view) {
+ var maxHeight, maxWidth;
+ maxWidth = 0;
+ maxHeight = 0;
+ $('.frame', view).each((function(_this) {
+ return function(index, frame) {
+ var height, width;
+ width = $(frame).width();
+ height = $(frame).height();
+ maxWidth = width > maxWidth ? width : maxWidth;
+ return maxHeight = height > maxHeight ? height : maxHeight;
};
+ })(this)).css({
+ width: maxWidth,
+ height: maxHeight
+ });
+ return [maxWidth, maxHeight];
+};
+
+ImageFile.prototype.views = {
+ 'two-up': function() {
+ return $('.two-up.view .wrap', this.file).each((function(_this) {
+ return function(index, wrap) {
+ $('img', wrap).each(function() {
+ var currentWidth;
+ currentWidth = $(this).width();
+ if (currentWidth > ImageFile.availWidth / 2) {
+ return $(this).width(ImageFile.availWidth / 2);
+ }
+ });
+ return _this.requestImageInfo($('img', wrap), function(width, height) {
+ $('.image-info .meta-width', wrap).text(width + "px");
+ $('.image-info .meta-height', wrap).text(height + "px");
+ return $('.image-info', wrap).removeClass('hide');
+ });
+ };
+ })(this));
+ },
+ 'swipe': function() {
+ var maxHeight, maxWidth;
+ maxWidth = 0;
+ maxHeight = 0;
+ return $('.swipe.view', this.file).each((function(_this) {
+ return function(index, view) {
+ var $swipeWrap, $swipeBar, $swipeFrame, wrapPadding, ref;
+ ref = prepareFrames(view), maxWidth = ref[0], maxHeight = ref[1];
+ $swipeFrame = $('.swipe-frame', view);
+ $swipeWrap = $('.swipe-wrap', view);
+ $swipeBar = $('.swipe-bar', view);
+
+ $swipeFrame.css({
+ width: maxWidth + 16,
+ height: maxHeight + 28
+ });
+ $swipeWrap.css({
+ width: maxWidth + 1,
+ height: maxHeight + 2
+ });
+ $swipeBar.css({
+ left: 0
+ });
+
+ wrapPadding = parseInt($swipeWrap.css('right').replace('px', ''), 10);
+
+ _this.initDraggable($swipeBar, wrapPadding, function(e, left) {
+ if (left > 0 && left < $swipeFrame.width() - (wrapPadding * 2)) {
+ $swipeWrap.width((maxWidth + 1) - left);
+ $swipeBar.css('left', left);
+ }
+ });
+ };
+ })(this));
+ },
+ 'onion-skin': function() {
+ var dragTrackWidth, maxHeight, maxWidth;
+ maxWidth = 0;
+ maxHeight = 0;
+ dragTrackWidth = $('.drag-track', this.file).width() - $('.dragger', this.file).width();
+ return $('.onion-skin.view', this.file).each((function(_this) {
+ return function(index, view) {
+ var $frame, $track, $dragger, $frameAdded, framePadding, ref, dragging = false;
+ ref = prepareFrames(view), maxWidth = ref[0], maxHeight = ref[1];
+ $frame = $('.onion-skin-frame', view);
+ $frameAdded = $('.frame.added', view);
+ $track = $('.drag-track', view);
+ $dragger = $('.dragger', $track);
+
+ $frame.css({
+ width: maxWidth + 16,
+ height: maxHeight + 28
+ });
+ $('.swipe-wrap', view).css({
+ width: maxWidth + 1,
+ height: maxHeight + 2
+ });
+ $dragger.css({
+ left: dragTrackWidth
+ });
+
+ framePadding = parseInt($frameAdded.css('right').replace('px', ''), 10);
+
+ _this.initDraggable($dragger, framePadding, function(e, left) {
+ var opacity = left / dragTrackWidth;
+
+ if (opacity >= 0 && opacity <= 1) {
+ $dragger.css('left', left);
+ $frameAdded.css('opacity', opacity);
+ }
+ });
+ };
+ })(this));
+ }
+};
+
+ImageFile.prototype.requestImageInfo = function(img, callback) {
+ var domImg;
+ domImg = img.get(0);
+ if (domImg) {
+ if (domImg.complete) {
+ return callback.call(this, domImg.naturalWidth, domImg.naturalHeight);
+ } else {
+ return img.on('load', (function(_this) {
+ return function() {
+ return callback.call(_this, domImg.naturalWidth, domImg.naturalHeight);
+ };
+ })(this));
+ }
+ }
+};
- return ImageFile;
- })();
-}).call(window);
+global.ImageFile = ImageFile;
diff --git a/app/assets/javascripts/commits.js b/app/assets/javascripts/commits.js
index 2b0bf49cf92..b7db5ded846 100644
--- a/app/assets/javascripts/commits.js
+++ b/app/assets/javascripts/commits.js
@@ -1,97 +1,93 @@
/* eslint-disable func-names, space-before-function-paren, wrap-iife, quotes, consistent-return, no-return-assign, no-param-reassign, one-var, no-var, one-var-declaration-per-line, no-unused-vars, prefer-template, object-shorthand, comma-dangle, max-len, prefer-arrow-callback */
/* global Pager */
-window.CommitsList = (function() {
- var CommitsList = {};
+var CommitsList = {};
- CommitsList.timer = null;
+CommitsList.timer = null;
- CommitsList.init = function(limit) {
- this.$contentList = $('.content_list');
+CommitsList.init = function(limit) {
+ this.$contentList = $('.content_list');
- $("body").on("click", ".day-commits-table li.commit", function(e) {
- if (e.target.nodeName !== "A") {
- location.href = $(this).attr("url");
- e.stopPropagation();
- return false;
- }
- });
+ $("body").on("click", ".day-commits-table li.commit", function(e) {
+ if (e.target.nodeName !== "A") {
+ location.href = $(this).attr("url");
+ e.stopPropagation();
+ return false;
+ }
+ });
- Pager.init(limit, false, false, this.processCommits);
+ Pager.init(limit, false, false, this.processCommits);
- this.content = $("#commits-list");
- this.searchField = $("#commits-search");
- this.lastSearch = this.searchField.val();
- return this.initSearch();
- };
+ this.content = $("#commits-list");
+ this.searchField = $("#commits-search");
+ this.lastSearch = this.searchField.val();
+ return this.initSearch();
+};
- CommitsList.initSearch = function() {
- this.timer = null;
- return this.searchField.keyup((function(_this) {
- return function() {
- clearTimeout(_this.timer);
- return _this.timer = setTimeout(_this.filterResults, 500);
- };
- })(this));
- };
+CommitsList.initSearch = function() {
+ this.timer = null;
+ return this.searchField.keyup(() => {
+ clearTimeout(this.timer);
+ return this.timer = setTimeout(this.filterResults, 500);
+ });
+};
- CommitsList.filterResults = function() {
- var commitsUrl, form, search;
- form = $(".commits-search-form");
- search = CommitsList.searchField.val();
- if (search === CommitsList.lastSearch) return;
- commitsUrl = form.attr("action") + '?' + form.serialize();
- CommitsList.content.fadeTo('fast', 0.5);
- return $.ajax({
- type: "GET",
- url: form.attr("action"),
- data: form.serialize(),
- complete: function() {
- return CommitsList.content.fadeTo('fast', 1.0);
- },
- success: function(data) {
- CommitsList.lastSearch = search;
- 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);
- },
- error: function() {
- CommitsList.lastSearch = null;
- },
- dataType: "json"
- });
- };
+CommitsList.filterResults = function() {
+ var commitsUrl, form, search;
+ form = $(".commits-search-form");
+ search = CommitsList.searchField.val();
+ if (search === CommitsList.lastSearch) return;
+ commitsUrl = form.attr("action") + '?' + form.serialize();
+ CommitsList.content.fadeTo('fast', 0.5);
+ return $.ajax({
+ type: "GET",
+ url: form.attr("action"),
+ data: form.serialize(),
+ complete: function() {
+ return CommitsList.content.fadeTo('fast', 1.0);
+ },
+ success: function(data) {
+ CommitsList.lastSearch = search;
+ 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);
+ },
+ error: function() {
+ CommitsList.lastSearch = null;
+ },
+ dataType: "json"
+ });
+};
- // Prepare loaded data.
- CommitsList.processCommits = (data) => {
- let processedData = data;
- const $processedData = $(processedData);
- const $commitsHeadersLast = CommitsList.$contentList.find('li.js-commit-header').last();
- const lastShownDay = $commitsHeadersLast.data('day');
- const $loadedCommitsHeadersFirst = $processedData.filter('li.js-commit-header').first();
- const loadedShownDayFirst = $loadedCommitsHeadersFirst.data('day');
- let commitsCount;
+// Prepare loaded data.
+CommitsList.processCommits = (data) => {
+ let processedData = data;
+ const $processedData = $(processedData);
+ const $commitsHeadersLast = CommitsList.$contentList.find('li.js-commit-header').last();
+ const lastShownDay = $commitsHeadersLast.data('day');
+ const $loadedCommitsHeadersFirst = $processedData.filter('li.js-commit-header').first();
+ const loadedShownDayFirst = $loadedCommitsHeadersFirst.data('day');
+ let commitsCount;
- // If commits headers show the same date,
- // remove the last header and change the previous one.
- if (lastShownDay === loadedShownDayFirst) {
- // Last shown commits count under the last commits header.
- commitsCount = $commitsHeadersLast.nextUntil('li.js-commit-header').find('li.commit').length;
+ // If commits headers show the same date,
+ // remove the last header and change the previous one.
+ if (lastShownDay === loadedShownDayFirst) {
+ // Last shown commits count under the last commits header.
+ commitsCount = $commitsHeadersLast.nextUntil('li.js-commit-header').find('li.commit').length;
- // Remove duplicate of commits header.
- processedData = $processedData.not(`li.js-commit-header[data-day="${loadedShownDayFirst}"]`);
+ // Remove duplicate of commits header.
+ processedData = $processedData.not(`li.js-commit-header[data-day="${loadedShownDayFirst}"]`);
- // Update commits count in the previous commits header.
- commitsCount += Number($(processedData).nextUntil('li.js-commit-header').first().find('li.commit').length);
- $commitsHeadersLast.find('span.commits-count').text(`${commitsCount} ${gl.text.pluralize('commit', commitsCount)}`);
- }
+ // Update commits count in the previous commits header.
+ commitsCount += Number($(processedData).nextUntil('li.js-commit-header').first().find('li.commit').length);
+ $commitsHeadersLast.find('span.commits-count').text(`${commitsCount} ${gl.text.pluralize('commit', commitsCount)}`);
+ }
- gl.utils.localTimeAgo($processedData.find('.js-timeago'));
+ gl.utils.localTimeAgo($processedData.find('.js-timeago'));
- return processedData;
- };
+ return processedData;
+};
- return CommitsList;
-})();
+window.CommitsList = CommitsList;
diff --git a/app/assets/javascripts/compare.js b/app/assets/javascripts/compare.js
index 9e5dbd64a7e..e5321ef9cc6 100644
--- a/app/assets/javascripts/compare.js
+++ b/app/assets/javascripts/compare.js
@@ -1,90 +1,86 @@
/* eslint-disable func-names, space-before-function-paren, wrap-iife, quotes, no-var, object-shorthand, consistent-return, no-unused-vars, comma-dangle, vars-on-top, prefer-template, max-len */
-window.Compare = (function() {
- function Compare(opts) {
- this.opts = opts;
- this.source_loading = $(".js-source-loading");
- this.target_loading = $(".js-target-loading");
- $('.js-compare-dropdown').each((function(_this) {
- return function(i, dropdown) {
- var $dropdown;
- $dropdown = $(dropdown);
- return $dropdown.glDropdown({
- selectable: true,
- fieldName: $dropdown.data('field-name'),
- filterable: true,
- id: function(obj, $el) {
- return $el.data('id');
- },
- toggleLabel: function(obj, $el) {
- return $el.text().trim();
- },
- clicked: function(e, el) {
- if ($dropdown.is('.js-target-branch')) {
- return _this.getTargetHtml();
- } else if ($dropdown.is('.js-source-branch')) {
- return _this.getSourceHtml();
- } else if ($dropdown.is('.js-target-project')) {
- return _this.getTargetProject();
- }
- }
- });
- };
- })(this));
- this.initialState();
- }
-
- Compare.prototype.initialState = function() {
- this.getSourceHtml();
- return this.getTargetHtml();
- };
-
- Compare.prototype.getTargetProject = function() {
- return $.ajax({
- url: this.opts.targetProjectUrl,
- data: {
- target_project_id: $("input[name='merge_request[target_project_id]']").val()
+function Compare(opts) {
+ this.opts = opts;
+ this.source_loading = $(".js-source-loading");
+ this.target_loading = $(".js-target-loading");
+ $('.js-compare-dropdown').each((i, dropdown) => {
+ var $dropdown;
+ $dropdown = $(dropdown);
+ return $dropdown.glDropdown({
+ selectable: true,
+ fieldName: $dropdown.data('field-name'),
+ filterable: true,
+ id: function(obj, $el) {
+ return $el.data('id');
},
- beforeSend: function() {
- return $('.mr_target_commit').empty();
+ toggleLabel: function(obj, $el) {
+ return $el.text().trim();
},
- success: function(html) {
- return $('.js-target-branch-dropdown .dropdown-content').html(html);
+ clicked: function(e, el) {
+ if ($dropdown.is('.js-target-branch')) {
+ return this.getTargetHtml();
+ } else if ($dropdown.is('.js-source-branch')) {
+ return this.getSourceHtml();
+ } else if ($dropdown.is('.js-target-project')) {
+ return this.getTargetProject();
+ }
}
});
- };
+ });
+ this.initialState();
+}
- Compare.prototype.getSourceHtml = function() {
- return this.sendAjax(this.opts.sourceBranchUrl, this.source_loading, '.mr_source_commit', {
- ref: $("input[name='merge_request[source_branch]']").val()
- });
- };
+Compare.prototype.initialState = function() {
+ this.getSourceHtml();
+ return this.getTargetHtml();
+};
- Compare.prototype.getTargetHtml = function() {
- return this.sendAjax(this.opts.targetBranchUrl, this.target_loading, '.mr_target_commit', {
- target_project_id: $("input[name='merge_request[target_project_id]']").val(),
- ref: $("input[name='merge_request[target_branch]']").val()
- });
- };
+Compare.prototype.getTargetProject = function() {
+ return $.ajax({
+ url: this.opts.targetProjectUrl,
+ data: {
+ target_project_id: $("input[name='merge_request[target_project_id]']").val()
+ },
+ beforeSend: function() {
+ return $('.mr_target_commit').empty();
+ },
+ success: function(html) {
+ return $('.js-target-branch-dropdown .dropdown-content').html(html);
+ }
+ });
+};
- Compare.prototype.sendAjax = function(url, loading, target, data) {
- var $target;
- $target = $(target);
- return $.ajax({
- url: url,
- data: data,
- beforeSend: function() {
- loading.show();
- return $target.empty();
- },
- success: function(html) {
- loading.hide();
- $target.html(html);
- var className = '.' + $target[0].className.replace(' ', '.');
- gl.utils.localTimeAgo($('.js-timeago', className));
- }
- });
- };
+Compare.prototype.getSourceHtml = function() {
+ return this.sendAjax(this.opts.sourceBranchUrl, this.source_loading, '.mr_source_commit', {
+ ref: $("input[name='merge_request[source_branch]']").val()
+ });
+};
+
+Compare.prototype.getTargetHtml = function() {
+ return this.sendAjax(this.opts.targetBranchUrl, this.target_loading, '.mr_target_commit', {
+ target_project_id: $("input[name='merge_request[target_project_id]']").val(),
+ ref: $("input[name='merge_request[target_branch]']").val()
+ });
+};
+
+Compare.prototype.sendAjax = function(url, loading, target, data) {
+ var $target;
+ $target = $(target);
+ return $.ajax({
+ url: url,
+ data: data,
+ beforeSend: function() {
+ loading.show();
+ return $target.empty();
+ },
+ success: function(html) {
+ loading.hide();
+ $target.html(html);
+ var className = '.' + $target[0].className.replace(' ', '.');
+ gl.utils.localTimeAgo($('.js-timeago', className));
+ }
+ });
+};
- return Compare;
-})();
+window.Compare = Compare;
diff --git a/app/assets/javascripts/compare_autocomplete.js b/app/assets/javascripts/compare_autocomplete.js
index 72c0d98d47c..e70f78d16a8 100644
--- a/app/assets/javascripts/compare_autocomplete.js
+++ b/app/assets/javascripts/compare_autocomplete.js
@@ -1,68 +1,66 @@
/* eslint-disable func-names, space-before-function-paren, one-var, no-var, one-var-declaration-per-line, object-shorthand, comma-dangle, prefer-arrow-callback, no-else-return, newline-per-chained-call, wrap-iife, max-len */
-window.CompareAutocomplete = (function() {
- function CompareAutocomplete() {
- this.initDropdown();
- }
+function CompareAutocomplete() {
+ this.initDropdown();
+}
- CompareAutocomplete.prototype.initDropdown = function() {
- return $('.js-compare-dropdown').each(function() {
- var $dropdown, selected;
- $dropdown = $(this);
- selected = $dropdown.data('selected');
- const $dropdownContainer = $dropdown.closest('.dropdown');
- const $fieldInput = $(`input[name="${$dropdown.data('field-name')}"]`, $dropdownContainer);
- const $filterInput = $('input[type="search"]', $dropdownContainer);
- $dropdown.glDropdown({
- data: function(term, callback) {
- return $.ajax({
- url: $dropdown.data('refs-url'),
- data: {
- ref: $dropdown.data('ref'),
- search: term,
- }
- }).done(function(refs) {
- return callback(refs);
- });
- },
- selectable: true,
- filterable: true,
- filterRemote: true,
- fieldName: $dropdown.data('field-name'),
- filterInput: 'input[type="search"]',
- renderRow: function(ref) {
- var link;
- if (ref.header != null) {
- return $('<li />').addClass('dropdown-header').text(ref.header);
- } else {
- link = $('<a />').attr('href', '#').addClass(ref === selected ? 'is-active' : '').text(ref).attr('data-ref', escape(ref));
- return $('<li />').append(link);
+CompareAutocomplete.prototype.initDropdown = function() {
+ return $('.js-compare-dropdown').each(function() {
+ var $dropdown, selected;
+ $dropdown = $(this);
+ selected = $dropdown.data('selected');
+ const $dropdownContainer = $dropdown.closest('.dropdown');
+ const $fieldInput = $(`input[name="${$dropdown.data('field-name')}"]`, $dropdownContainer);
+ const $filterInput = $('input[type="search"]', $dropdownContainer);
+ $dropdown.glDropdown({
+ data: function(term, callback) {
+ return $.ajax({
+ url: $dropdown.data('refs-url'),
+ data: {
+ ref: $dropdown.data('ref'),
+ search: term,
}
- },
- id: function(obj, $el) {
- return $el.attr('data-ref');
- },
- toggleLabel: function(obj, $el) {
- return $el.text().trim();
+ }).done(function(refs) {
+ return callback(refs);
+ });
+ },
+ selectable: true,
+ filterable: true,
+ filterRemote: true,
+ fieldName: $dropdown.data('field-name'),
+ filterInput: 'input[type="search"]',
+ renderRow: function(ref) {
+ var link;
+ if (ref.header != null) {
+ return $('<li />').addClass('dropdown-header').text(ref.header);
+ } else {
+ link = $('<a />').attr('href', '#').addClass(ref === selected ? 'is-active' : '').text(ref).attr('data-ref', escape(ref));
+ return $('<li />').append(link);
}
- });
- $filterInput.on('keyup', (e) => {
- const keyCode = e.keyCode || e.which;
- if (keyCode !== 13) return;
- const text = $filterInput.val();
- $fieldInput.val(text);
- $('.dropdown-toggle-text', $dropdown).text(text);
- $dropdownContainer.removeClass('open');
- });
+ },
+ id: function(obj, $el) {
+ return $el.attr('data-ref');
+ },
+ toggleLabel: function(obj, $el) {
+ return $el.text().trim();
+ }
+ });
+ $filterInput.on('keyup', (e) => {
+ const keyCode = e.keyCode || e.which;
+ if (keyCode !== 13) return;
+ const text = $filterInput.val();
+ $fieldInput.val(text);
+ $('.dropdown-toggle-text', $dropdown).text(text);
+ $dropdownContainer.removeClass('open');
+ });
- $dropdownContainer.on('click', '.dropdown-content a', (e) => {
- $dropdown.prop('title', e.target.text.replace(/_+?/g, '-'));
- if ($dropdown.hasClass('has-tooltip')) {
- $dropdown.tooltip('fixTitle');
- }
- });
+ $dropdownContainer.on('click', '.dropdown-content a', (e) => {
+ $dropdown.prop('title', e.target.text.replace(/_+?/g, '-'));
+ if ($dropdown.hasClass('has-tooltip')) {
+ $dropdown.tooltip('fixTitle');
+ }
});
- };
+ });
+};
- return CompareAutocomplete;
-})();
+window.CompareAutocomplete = CompareAutocomplete;
diff --git a/app/assets/javascripts/confirm_danger_modal.js b/app/assets/javascripts/confirm_danger_modal.js
index b375b61202e..14bbc170699 100644
--- a/app/assets/javascripts/confirm_danger_modal.js
+++ b/app/assets/javascripts/confirm_danger_modal.js
@@ -1,30 +1,24 @@
/* eslint-disable func-names, space-before-function-paren, wrap-iife, one-var, no-var, camelcase, one-var-declaration-per-line, no-else-return, max-len */
-window.ConfirmDangerModal = (function() {
- function ConfirmDangerModal(form, text) {
- var project_path, submit;
- this.form = form;
- $('.js-confirm-text').text(text || '');
- $('.js-confirm-danger-input').val('');
- $('#modal-confirm-danger').modal('show');
- project_path = $('.js-confirm-danger-match').text();
- submit = $('.js-confirm-danger-submit');
- submit.disable();
- $('.js-confirm-danger-input').off('input');
- $('.js-confirm-danger-input').on('input', function() {
- if (gl.utils.rstrip($(this).val()) === project_path) {
- return submit.enable();
- } else {
- return submit.disable();
- }
- });
- $('.js-confirm-danger-submit').off('click');
- $('.js-confirm-danger-submit').on('click', (function(_this) {
- return function() {
- return _this.form.submit();
- };
- })(this));
- }
+function ConfirmDangerModal(form, text) {
+ var project_path, submit;
+ this.form = form;
+ $('.js-confirm-text').text(text || '');
+ $('.js-confirm-danger-input').val('');
+ $('#modal-confirm-danger').modal('show');
+ project_path = $('.js-confirm-danger-match').text();
+ submit = $('.js-confirm-danger-submit');
+ submit.disable();
+ $('.js-confirm-danger-input').off('input');
+ $('.js-confirm-danger-input').on('input', function() {
+ if (gl.utils.rstrip($(this).val()) === project_path) {
+ return submit.enable();
+ } else {
+ return submit.disable();
+ }
+ });
+ $('.js-confirm-danger-submit').off('click');
+ $('.js-confirm-danger-submit').on('click', () => this.form.submit());
+}
- return ConfirmDangerModal;
-})();
+window.ConfirmDangerModal = ConfirmDangerModal;
diff --git a/app/assets/javascripts/dropzone_input.js b/app/assets/javascripts/dropzone_input.js
index 73675d300be..6fd567c76bb 100644
--- a/app/assets/javascripts/dropzone_input.js
+++ b/app/assets/javascripts/dropzone_input.js
@@ -3,300 +3,298 @@
import './preview_markdown';
-window.DropzoneInput = (function() {
- function DropzoneInput(form) {
- var updateAttachingMessage, $attachingFileMessage, $mdArea, $attachButton, $cancelButton, $retryLink, $uploadingErrorContainer, $uploadingErrorMessage, $uploadProgress, $uploadingProgressContainer, appendToTextArea, btnAlert, child, closeAlertMessage, closeSpinner, divHover, divSpinner, dropzone, $formDropzone, formTextarea, getFilename, handlePaste, iconPaperclip, iconSpinner, insertToTextArea, isImage, maxFileSize, pasteText, uploadsPath, showError, showSpinner, uploadFile, addFileToForm;
- Dropzone.autoDiscover = false;
- divHover = '<div class="div-dropzone-hover"></div>';
- iconPaperclip = '<i class="fa fa-paperclip div-dropzone-icon"></i>';
- $attachButton = form.find('.button-attach-file');
- $attachingFileMessage = form.find('.attaching-file-message');
- $cancelButton = form.find('.button-cancel-uploading-files');
- $retryLink = form.find('.retry-uploading-link');
- $uploadProgress = form.find('.uploading-progress');
- $uploadingErrorContainer = form.find('.uploading-error-container');
- $uploadingErrorMessage = form.find('.uploading-error-message');
- $uploadingProgressContainer = form.find('.uploading-progress-container');
- uploadsPath = window.uploads_path || null;
- maxFileSize = gon.max_file_size || 10;
- formTextarea = form.find('.js-gfm-input');
- formTextarea.wrap('<div class="div-dropzone"></div>');
- formTextarea.on('paste', (function(_this) {
- return function(event) {
- return handlePaste(event);
- };
- })(this));
-
- // Add dropzone area to the form.
- $mdArea = formTextarea.closest('.md-area');
- form.setupMarkdownPreview();
- $formDropzone = form.find('.div-dropzone');
- $formDropzone.parent().addClass('div-dropzone-wrapper');
- $formDropzone.append(divHover);
- $formDropzone.find('.div-dropzone-hover').append(iconPaperclip);
-
- if (!uploadsPath) return;
-
- dropzone = $formDropzone.dropzone({
+function DropzoneInput(form) {
+ var updateAttachingMessage, $attachingFileMessage, $mdArea, $attachButton, $cancelButton, $retryLink, $uploadingErrorContainer, $uploadingErrorMessage, $uploadProgress, $uploadingProgressContainer, appendToTextArea, btnAlert, child, closeAlertMessage, closeSpinner, divHover, divSpinner, dropzone, $formDropzone, formTextarea, getFilename, handlePaste, iconPaperclip, iconSpinner, insertToTextArea, isImage, maxFileSize, pasteText, uploadsPath, showError, showSpinner, uploadFile, addFileToForm;
+ Dropzone.autoDiscover = false;
+ divHover = '<div class="div-dropzone-hover"></div>';
+ iconPaperclip = '<i class="fa fa-paperclip div-dropzone-icon"></i>';
+ $attachButton = form.find('.button-attach-file');
+ $attachingFileMessage = form.find('.attaching-file-message');
+ $cancelButton = form.find('.button-cancel-uploading-files');
+ $retryLink = form.find('.retry-uploading-link');
+ $uploadProgress = form.find('.uploading-progress');
+ $uploadingErrorContainer = form.find('.uploading-error-container');
+ $uploadingErrorMessage = form.find('.uploading-error-message');
+ $uploadingProgressContainer = form.find('.uploading-progress-container');
+ uploadsPath = window.uploads_path || null;
+ maxFileSize = gon.max_file_size || 10;
+ formTextarea = form.find('.js-gfm-input');
+ formTextarea.wrap('<div class="div-dropzone"></div>');
+ formTextarea.on('paste', (function(_this) {
+ return function(event) {
+ return handlePaste(event);
+ };
+ })(this));
+
+ // Add dropzone area to the form.
+ $mdArea = formTextarea.closest('.md-area');
+ form.setupMarkdownPreview();
+ $formDropzone = form.find('.div-dropzone');
+ $formDropzone.parent().addClass('div-dropzone-wrapper');
+ $formDropzone.append(divHover);
+ $formDropzone.find('.div-dropzone-hover').append(iconPaperclip);
+
+ if (!uploadsPath) return;
+
+ dropzone = $formDropzone.dropzone({
+ url: uploadsPath,
+ dictDefaultMessage: '',
+ clickable: true,
+ paramName: 'file',
+ maxFilesize: maxFileSize,
+ uploadMultiple: false,
+ headers: {
+ 'X-CSRF-Token': $('meta[name="csrf-token"]').attr('content')
+ },
+ previewContainer: false,
+ processing: function() {
+ return $('.div-dropzone-alert').alert('close');
+ },
+ dragover: function() {
+ $mdArea.addClass('is-dropzone-hover');
+ form.find('.div-dropzone-hover').css('opacity', 0.7);
+ },
+ dragleave: function() {
+ $mdArea.removeClass('is-dropzone-hover');
+ form.find('.div-dropzone-hover').css('opacity', 0);
+ },
+ drop: function() {
+ $mdArea.removeClass('is-dropzone-hover');
+ form.find('.div-dropzone-hover').css('opacity', 0);
+ formTextarea.focus();
+ },
+ success: function(header, response) {
+ const processingFileCount = this.getQueuedFiles().length + this.getUploadingFiles().length;
+ const shouldPad = processingFileCount >= 1;
+
+ pasteText(response.link.markdown, shouldPad);
+ // Show 'Attach a file' link only when all files have been uploaded.
+ if (!processingFileCount) $attachButton.removeClass('hide');
+ addFileToForm(response.link.url);
+ },
+ error: function(file, errorMessage = 'Attaching the file failed.', xhr) {
+ // If 'error' event is fired by dropzone, the second parameter is error message.
+ // If the 'errorMessage' parameter is empty, the default error message is set.
+ // If the 'error' event is fired by backend (xhr) error response, the third parameter is
+ // xhr object (xhr.responseText is error message).
+ // On error we hide the 'Attach' and 'Cancel' buttons
+ // and show an error.
+
+ // If there's xhr error message, let's show it instead of dropzone's one.
+ const message = xhr ? xhr.responseText : errorMessage;
+
+ $uploadingErrorContainer.removeClass('hide');
+ $uploadingErrorMessage.html(message);
+ $attachButton.addClass('hide');
+ $cancelButton.addClass('hide');
+ },
+ totaluploadprogress: function(totalUploadProgress) {
+ updateAttachingMessage(this.files, $attachingFileMessage);
+ $uploadProgress.text(Math.round(totalUploadProgress) + '%');
+ },
+ sending: function(file) {
+ // DOM elements already exist.
+ // Instead of dynamically generating them,
+ // we just either hide or show them.
+ $attachButton.addClass('hide');
+ $uploadingErrorContainer.addClass('hide');
+ $uploadingProgressContainer.removeClass('hide');
+ $cancelButton.removeClass('hide');
+ },
+ removedfile: function() {
+ $attachButton.removeClass('hide');
+ $cancelButton.addClass('hide');
+ $uploadingProgressContainer.addClass('hide');
+ $uploadingErrorContainer.addClass('hide');
+ },
+ queuecomplete: function() {
+ $('.dz-preview').remove();
+ $('.markdown-area').trigger('input');
+
+ $uploadingProgressContainer.addClass('hide');
+ $cancelButton.addClass('hide');
+ }
+ });
+
+ child = $(dropzone[0]).children('textarea');
+
+ // removeAllFiles(true) stops uploading files (if any)
+ // and remove them from dropzone files queue.
+ $cancelButton.on('click', (e) => {
+ const target = e.target.closest('form').querySelector('.div-dropzone');
+
+ e.preventDefault();
+ e.stopPropagation();
+ Dropzone.forElement(target).removeAllFiles(true);
+ });
+
+ // If 'error' event is fired, we store a failed files,
+ // clear dropzone files queue, change status of failed files to undefined,
+ // and add that files to the dropzone files queue again.
+ // addFile() adds file to dropzone files queue and upload it.
+ $retryLink.on('click', (e) => {
+ const dropzoneInstance = Dropzone.forElement(e.target.closest('form').querySelector('.div-dropzone'));
+ const failedFiles = dropzoneInstance.files;
+
+ e.preventDefault();
+
+ // 'true' parameter of removeAllFiles() cancels uploading of files that are being uploaded at the moment.
+ dropzoneInstance.removeAllFiles(true);
+
+ failedFiles.map((failedFile, i) => {
+ const file = failedFile;
+
+ if (file.status === Dropzone.ERROR) {
+ file.status = undefined;
+ file.accepted = undefined;
+ }
+
+ return dropzoneInstance.addFile(file);
+ });
+ });
+
+ handlePaste = function(event) {
+ var filename, image, pasteEvent, text;
+ pasteEvent = event.originalEvent;
+ if (pasteEvent.clipboardData && pasteEvent.clipboardData.items) {
+ image = isImage(pasteEvent);
+ if (image) {
+ event.preventDefault();
+ filename = getFilename(pasteEvent) || 'image.png';
+ text = `{{${filename}}}`;
+ pasteText(text);
+ return uploadFile(image.getAsFile(), filename);
+ }
+ }
+ };
+
+ isImage = function(data) {
+ var i, item;
+ i = 0;
+ while (i < data.clipboardData.items.length) {
+ item = data.clipboardData.items[i];
+ if (item.type.indexOf('image') !== -1) {
+ return item;
+ }
+ i += 1;
+ }
+ return false;
+ };
+
+ pasteText = function(text, shouldPad) {
+ var afterSelection, beforeSelection, caretEnd, caretStart, textEnd;
+ var formattedText = text;
+ if (shouldPad) formattedText += "\n\n";
+ const textarea = child.get(0);
+ caretStart = textarea.selectionStart;
+ caretEnd = textarea.selectionEnd;
+ textEnd = $(child).val().length;
+ beforeSelection = $(child).val().substring(0, caretStart);
+ afterSelection = $(child).val().substring(caretEnd, textEnd);
+ $(child).val(beforeSelection + formattedText + afterSelection);
+ textarea.setSelectionRange(caretStart + formattedText.length, caretEnd + formattedText.length);
+ textarea.style.height = `${textarea.scrollHeight}px`;
+ formTextarea.get(0).dispatchEvent(new Event('input'));
+ return formTextarea.trigger('input');
+ };
+
+ addFileToForm = function(path) {
+ $(form).append('<input type="hidden" name="files[]" value="' + _.escape(path) + '">');
+ };
+
+ getFilename = function(e) {
+ var value;
+ if (window.clipboardData && window.clipboardData.getData) {
+ value = window.clipboardData.getData('Text');
+ } else if (e.clipboardData && e.clipboardData.getData) {
+ value = e.clipboardData.getData('text/plain');
+ }
+ value = value.split("\r");
+ return value.first();
+ };
+
+ uploadFile = function(item, filename) {
+ var formData;
+ formData = new FormData();
+ formData.append('file', item, filename);
+ return $.ajax({
url: uploadsPath,
- dictDefaultMessage: '',
- clickable: true,
- paramName: 'file',
- maxFilesize: maxFileSize,
- uploadMultiple: false,
+ type: 'POST',
+ data: formData,
+ dataType: 'json',
+ processData: false,
+ contentType: false,
headers: {
'X-CSRF-Token': $('meta[name="csrf-token"]').attr('content')
},
- previewContainer: false,
- processing: function() {
- return $('.div-dropzone-alert').alert('close');
- },
- dragover: function() {
- $mdArea.addClass('is-dropzone-hover');
- form.find('.div-dropzone-hover').css('opacity', 0.7);
- },
- dragleave: function() {
- $mdArea.removeClass('is-dropzone-hover');
- form.find('.div-dropzone-hover').css('opacity', 0);
- },
- drop: function() {
- $mdArea.removeClass('is-dropzone-hover');
- form.find('.div-dropzone-hover').css('opacity', 0);
- formTextarea.focus();
- },
- success: function(header, response) {
- const processingFileCount = this.getQueuedFiles().length + this.getUploadingFiles().length;
- const shouldPad = processingFileCount >= 1;
-
- pasteText(response.link.markdown, shouldPad);
- // Show 'Attach a file' link only when all files have been uploaded.
- if (!processingFileCount) $attachButton.removeClass('hide');
- addFileToForm(response.link.url);
+ beforeSend: function() {
+ showSpinner();
+ return closeAlertMessage();
},
- error: function(file, errorMessage = 'Attaching the file failed.', xhr) {
- // If 'error' event is fired by dropzone, the second parameter is error message.
- // If the 'errorMessage' parameter is empty, the default error message is set.
- // If the 'error' event is fired by backend (xhr) error response, the third parameter is
- // xhr object (xhr.responseText is error message).
- // On error we hide the 'Attach' and 'Cancel' buttons
- // and show an error.
-
- // If there's xhr error message, let's show it instead of dropzone's one.
- const message = xhr ? xhr.responseText : errorMessage;
-
- $uploadingErrorContainer.removeClass('hide');
- $uploadingErrorMessage.html(message);
- $attachButton.addClass('hide');
- $cancelButton.addClass('hide');
+ success: function(e, textStatus, response) {
+ return insertToTextArea(filename, response.responseJSON.link.markdown);
},
- totaluploadprogress: function(totalUploadProgress) {
- updateAttachingMessage(this.files, $attachingFileMessage);
- $uploadProgress.text(Math.round(totalUploadProgress) + '%');
+ error: function(response) {
+ return showError(response.responseJSON.message);
},
- sending: function(file) {
- // DOM elements already exist.
- // Instead of dynamically generating them,
- // we just either hide or show them.
- $attachButton.addClass('hide');
- $uploadingErrorContainer.addClass('hide');
- $uploadingProgressContainer.removeClass('hide');
- $cancelButton.removeClass('hide');
- },
- removedfile: function() {
- $attachButton.removeClass('hide');
- $cancelButton.addClass('hide');
- $uploadingProgressContainer.addClass('hide');
- $uploadingErrorContainer.addClass('hide');
- },
- queuecomplete: function() {
- $('.dz-preview').remove();
- $('.markdown-area').trigger('input');
-
- $uploadingProgressContainer.addClass('hide');
- $cancelButton.addClass('hide');
+ complete: function() {
+ return closeSpinner();
}
});
-
- child = $(dropzone[0]).children('textarea');
-
- // removeAllFiles(true) stops uploading files (if any)
- // and remove them from dropzone files queue.
- $cancelButton.on('click', (e) => {
- const target = e.target.closest('form').querySelector('.div-dropzone');
-
- e.preventDefault();
- e.stopPropagation();
- Dropzone.forElement(target).removeAllFiles(true);
+ };
+
+ updateAttachingMessage = (files, messageContainer) => {
+ let attachingMessage;
+ const filesCount = files.filter(function(file) {
+ return file.status === 'uploading' ||
+ file.status === 'queued';
+ }).length;
+
+ // Dinamycally change uploading files text depending on files number in
+ // dropzone files queue.
+ if (filesCount > 1) {
+ attachingMessage = 'Attaching ' + filesCount + ' files -';
+ } else {
+ attachingMessage = 'Attaching a file -';
+ }
+
+ messageContainer.text(attachingMessage);
+ };
+
+ insertToTextArea = function(filename, url) {
+ return $(child).val(function(index, val) {
+ return val.replace(`{{${filename}}}`, url);
});
+ };
- // If 'error' event is fired, we store a failed files,
- // clear dropzone files queue, change status of failed files to undefined,
- // and add that files to the dropzone files queue again.
- // addFile() adds file to dropzone files queue and upload it.
- $retryLink.on('click', (e) => {
- const dropzoneInstance = Dropzone.forElement(e.target.closest('form').querySelector('.div-dropzone'));
- const failedFiles = dropzoneInstance.files;
-
- e.preventDefault();
-
- // 'true' parameter of removeAllFiles() cancels uploading of files that are being uploaded at the moment.
- dropzoneInstance.removeAllFiles(true);
-
- failedFiles.map((failedFile, i) => {
- const file = failedFile;
-
- if (file.status === Dropzone.ERROR) {
- file.status = undefined;
- file.accepted = undefined;
- }
-
- return dropzoneInstance.addFile(file);
- });
+ appendToTextArea = function(url) {
+ return $(child).val(function(index, val) {
+ return val + url + "\n";
});
+ };
- handlePaste = function(event) {
- var filename, image, pasteEvent, text;
- pasteEvent = event.originalEvent;
- if (pasteEvent.clipboardData && pasteEvent.clipboardData.items) {
- image = isImage(pasteEvent);
- if (image) {
- event.preventDefault();
- filename = getFilename(pasteEvent) || 'image.png';
- text = `{{${filename}}}`;
- pasteText(text);
- return uploadFile(image.getAsFile(), filename);
- }
- }
- };
-
- isImage = function(data) {
- var i, item;
- i = 0;
- while (i < data.clipboardData.items.length) {
- item = data.clipboardData.items[i];
- if (item.type.indexOf('image') !== -1) {
- return item;
- }
- i += 1;
- }
- return false;
- };
-
- pasteText = function(text, shouldPad) {
- var afterSelection, beforeSelection, caretEnd, caretStart, textEnd;
- var formattedText = text;
- if (shouldPad) formattedText += "\n\n";
- const textarea = child.get(0);
- caretStart = textarea.selectionStart;
- caretEnd = textarea.selectionEnd;
- textEnd = $(child).val().length;
- beforeSelection = $(child).val().substring(0, caretStart);
- afterSelection = $(child).val().substring(caretEnd, textEnd);
- $(child).val(beforeSelection + formattedText + afterSelection);
- textarea.setSelectionRange(caretStart + formattedText.length, caretEnd + formattedText.length);
- textarea.style.height = `${textarea.scrollHeight}px`;
- formTextarea.get(0).dispatchEvent(new Event('input'));
- return formTextarea.trigger('input');
- };
-
- addFileToForm = function(path) {
- $(form).append('<input type="hidden" name="files[]" value="' + _.escape(path) + '">');
- };
-
- getFilename = function(e) {
- var value;
- if (window.clipboardData && window.clipboardData.getData) {
- value = window.clipboardData.getData('Text');
- } else if (e.clipboardData && e.clipboardData.getData) {
- value = e.clipboardData.getData('text/plain');
- }
- value = value.split("\r");
- return value.first();
- };
-
- uploadFile = function(item, filename) {
- var formData;
- formData = new FormData();
- formData.append('file', item, filename);
- return $.ajax({
- url: uploadsPath,
- type: 'POST',
- data: formData,
- dataType: 'json',
- processData: false,
- contentType: false,
- headers: {
- 'X-CSRF-Token': $('meta[name="csrf-token"]').attr('content')
- },
- beforeSend: function() {
- showSpinner();
- return closeAlertMessage();
- },
- success: function(e, textStatus, response) {
- return insertToTextArea(filename, response.responseJSON.link.markdown);
- },
- error: function(response) {
- return showError(response.responseJSON.message);
- },
- complete: function() {
- return closeSpinner();
- }
- });
- };
-
- updateAttachingMessage = (files, messageContainer) => {
- let attachingMessage;
- const filesCount = files.filter(function(file) {
- return file.status === 'uploading' ||
- file.status === 'queued';
- }).length;
-
- // Dinamycally change uploading files text depending on files number in
- // dropzone files queue.
- if (filesCount > 1) {
- attachingMessage = 'Attaching ' + filesCount + ' files -';
- } else {
- attachingMessage = 'Attaching a file -';
- }
-
- messageContainer.text(attachingMessage);
- };
-
- insertToTextArea = function(filename, url) {
- return $(child).val(function(index, val) {
- return val.replace(`{{${filename}}}`, url);
- });
- };
-
- appendToTextArea = function(url) {
- return $(child).val(function(index, val) {
- return val + url + "\n";
- });
- };
-
- showSpinner = function(e) {
- return $uploadingProgressContainer.removeClass('hide');
- };
+ showSpinner = function(e) {
+ return $uploadingProgressContainer.removeClass('hide');
+ };
- closeSpinner = function() {
- return $uploadingProgressContainer.addClass('hide');
- };
+ closeSpinner = function() {
+ return $uploadingProgressContainer.addClass('hide');
+ };
- showError = function(message) {
- $uploadingErrorContainer.removeClass('hide');
- $uploadingErrorMessage.html(message);
- };
+ showError = function(message) {
+ $uploadingErrorContainer.removeClass('hide');
+ $uploadingErrorMessage.html(message);
+ };
- closeAlertMessage = function() {
- return form.find('.div-dropzone-alert').alert('close');
- };
+ closeAlertMessage = function() {
+ return form.find('.div-dropzone-alert').alert('close');
+ };
- form.find('.markdown-selector').click(function(e) {
- e.preventDefault();
- $(this).closest('.gfm-form').find('.div-dropzone').click();
- formTextarea.focus();
- });
- }
+ form.find('.markdown-selector').click(function(e) {
+ e.preventDefault();
+ $(this).closest('.gfm-form').find('.div-dropzone').click();
+ formTextarea.focus();
+ });
+}
- return DropzoneInput;
-})();
+window.DropzoneInput = DropzoneInput;
diff --git a/app/assets/javascripts/flash.js b/app/assets/javascripts/flash.js
index ccff8f0ace7..5152b0f27a3 100644
--- a/app/assets/javascripts/flash.js
+++ b/app/assets/javascripts/flash.js
@@ -1,71 +1,69 @@
/* eslint-disable func-names, space-before-function-paren, wrap-iife, no-var, one-var, one-var-declaration-per-line, no-param-reassign, quotes, quote-props, prefer-template, comma-dangle, max-len */
-window.Flash = (function() {
- var hideFlash;
+var hideFlash;
- hideFlash = function() {
- return $(this).fadeOut();
- };
+hideFlash = function() {
+ return $(this).fadeOut();
+};
- /**
- * Flash banner supports different types of Flash configurations
- * along with ability to provide actionConfig which can be used to show
- * additional action or link on banner next to message
- *
- * @param {String} message Flash message
- * @param {String} type Type of Flash, it can be `notice` or `alert` (default)
- * @param {Object} parent Reference to Parent element under which Flash needs to appear
- * @param {Object} actionConfig Map of config to show action on banner
- * @param {String} href URL to which action link should point (default '#')
- * @param {String} title Title of action
- * @param {Function} clickHandler Method to call when action is clicked on
- */
- function Flash(message, type, parent, actionConfig) {
- var flash, textDiv, actionLink;
- if (type == null) {
- type = 'alert';
- }
- if (parent == null) {
- parent = null;
- }
- if (parent) {
- this.flashContainer = parent.find('.flash-container');
- } else {
- this.flashContainer = $('.flash-container-page');
- }
- this.flashContainer.html('');
- flash = $('<div/>', {
- "class": "flash-" + type
- });
- flash.on('click', hideFlash);
- textDiv = $('<div/>', {
- "class": 'flash-text',
- text: message
- });
- textDiv.appendTo(flash);
+/**
+ * Flash banner supports different types of Flash configurations
+ * along with ability to provide actionConfig which can be used to show
+ * additional action or link on banner next to message
+ *
+ * @param {String} message Flash message
+ * @param {String} type Type of Flash, it can be `notice` or `alert` (default)
+ * @param {Object} parent Reference to Parent element under which Flash needs to appear
+ * @param {Object} actionConfig Map of config to show action on banner
+ * @param {String} href URL to which action link should point (default '#')
+ * @param {String} title Title of action
+ * @param {Function} clickHandler Method to call when action is clicked on
+ */
+function Flash(message, type, parent, actionConfig) {
+ var flash, textDiv, actionLink;
+ if (type == null) {
+ type = 'alert';
+ }
+ if (parent == null) {
+ parent = null;
+ }
+ if (parent) {
+ this.flashContainer = parent.find('.flash-container');
+ } else {
+ this.flashContainer = $('.flash-container-page');
+ }
+ this.flashContainer.html('');
+ flash = $('<div/>', {
+ "class": "flash-" + type
+ });
+ flash.on('click', hideFlash);
+ textDiv = $('<div/>', {
+ "class": 'flash-text',
+ text: message
+ });
+ textDiv.appendTo(flash);
- if (actionConfig) {
- const actionLinkConfig = {
- class: 'flash-action',
- href: actionConfig.href || '#',
- text: actionConfig.title
- };
+ if (actionConfig) {
+ const actionLinkConfig = {
+ class: 'flash-action',
+ href: actionConfig.href || '#',
+ text: actionConfig.title
+ };
- if (!actionConfig.href) {
- actionLinkConfig.role = 'button';
- }
+ if (!actionConfig.href) {
+ actionLinkConfig.role = 'button';
+ }
- actionLink = $('<a/>', actionLinkConfig);
+ actionLink = $('<a/>', actionLinkConfig);
- actionLink.appendTo(flash);
- this.flashContainer.on('click', '.flash-action', actionConfig.clickHandler);
- }
- if (this.flashContainer.parent().hasClass('content-wrapper')) {
- textDiv.addClass('container-fluid container-limited');
- }
- flash.appendTo(this.flashContainer);
- this.flashContainer.show();
+ actionLink.appendTo(flash);
+ this.flashContainer.on('click', '.flash-action', actionConfig.clickHandler);
+ }
+ if (this.flashContainer.parent().hasClass('content-wrapper')) {
+ textDiv.addClass('container-fluid container-limited');
}
+ flash.appendTo(this.flashContainer);
+ this.flashContainer.show();
+}
- return Flash;
-})();
+window.Flash = Flash;
diff --git a/app/assets/javascripts/group_avatar.js b/app/assets/javascripts/group_avatar.js
index f03b47b1c1d..e60a33fbf4a 100644
--- a/app/assets/javascripts/group_avatar.js
+++ b/app/assets/javascripts/group_avatar.js
@@ -1,19 +1,17 @@
/* eslint-disable func-names, space-before-function-paren, wrap-iife, quotes, no-var, one-var, one-var-declaration-per-line, no-useless-escape, max-len */
-window.GroupAvatar = (function() {
- function GroupAvatar() {
- $('.js-choose-group-avatar-button').on("click", function() {
- var form;
- form = $(this).closest("form");
- return form.find(".js-group-avatar-input").click();
- });
- $('.js-group-avatar-input').on("change", function() {
- var filename, form;
- form = $(this).closest("form");
- filename = $(this).val().replace(/^.*[\\\/]/, '');
- return form.find(".js-avatar-filename").text(filename);
- });
- }
+function GroupAvatar() {
+ $('.js-choose-group-avatar-button').on("click", function() {
+ var form;
+ form = $(this).closest("form");
+ return form.find(".js-group-avatar-input").click();
+ });
+ $('.js-group-avatar-input').on("change", function() {
+ var filename, form;
+ form = $(this).closest("form");
+ filename = $(this).val().replace(/^.*[\\\/]/, '');
+ return form.find(".js-avatar-filename").text(filename);
+ });
+}
- return GroupAvatar;
-})();
+window.GroupAvatar = GroupAvatar;
diff --git a/app/assets/javascripts/groups_select.js b/app/assets/javascripts/groups_select.js
index b5975295329..d7d8e403542 100644
--- a/app/assets/javascripts/groups_select.js
+++ b/app/assets/javascripts/groups_select.js
@@ -7,115 +7,113 @@ import Api from './api';
var slice = [].slice;
-window.GroupsSelect = (function() {
- function GroupsSelect() {
- $('.ajax-groups-select').each((function(_this) {
- const self = _this;
+function GroupsSelect() {
+ $('.ajax-groups-select').each((function(_this) {
+ const self = _this;
- return function(i, select) {
- var all_available, skip_groups;
- const $select = $(select);
- all_available = $select.data('all-available');
- skip_groups = $select.data('skip-groups') || [];
+ return function(i, select) {
+ var all_available, skip_groups;
+ const $select = $(select);
+ all_available = $select.data('all-available');
+ skip_groups = $select.data('skip-groups') || [];
- $select.select2({
- placeholder: "Search for a group",
- multiple: $select.hasClass('multiselect'),
- minimumInputLength: 0,
- ajax: {
- url: Api.buildUrl(Api.groupsPath),
- dataType: 'json',
- quietMillis: 250,
- transport: function (params) {
- $.ajax(params).then((data, status, xhr) => {
- const results = data || [];
+ $select.select2({
+ placeholder: "Search for a group",
+ multiple: $select.hasClass('multiselect'),
+ minimumInputLength: 0,
+ ajax: {
+ url: Api.buildUrl(Api.groupsPath),
+ dataType: 'json',
+ quietMillis: 250,
+ transport: function (params) {
+ $.ajax(params).then((data, status, xhr) => {
+ const results = data || [];
- const headers = gl.utils.normalizeCRLFHeaders(xhr.getAllResponseHeaders());
- const currentPage = parseInt(headers['X-PAGE'], 10) || 0;
- const totalPages = parseInt(headers['X-TOTAL-PAGES'], 10) || 0;
- const more = currentPage < totalPages;
-
- return {
- results,
- pagination: {
- more,
- },
- };
- }).then(params.success).fail(params.error);
- },
- data: function (search, page) {
- return {
- search,
- page,
- per_page: GroupsSelect.PER_PAGE,
- all_available,
- };
- },
- results: function (data, page) {
- if (data.length) return { results: [] };
-
- const groups = data.length ? data : data.results || [];
- const more = data.pagination ? data.pagination.more : false;
- const results = groups.filter(group => skip_groups.indexOf(group.id) === -1);
+ const headers = gl.utils.normalizeCRLFHeaders(xhr.getAllResponseHeaders());
+ const currentPage = parseInt(headers['X-PAGE'], 10) || 0;
+ const totalPages = parseInt(headers['X-TOTAL-PAGES'], 10) || 0;
+ const more = currentPage < totalPages;
return {
results,
- page,
- more,
+ pagination: {
+ more,
+ },
};
- },
- },
- initSelection: function(element, callback) {
- var id;
- id = $(element).val();
- if (id !== "") {
- return Api.group(id, callback);
- }
+ }).then(params.success).fail(params.error);
},
- formatResult: function() {
- var args;
- args = 1 <= arguments.length ? slice.call(arguments, 0) : [];
- return self.formatResult.apply(self, args);
+ data: function (search, page) {
+ return {
+ search,
+ page,
+ per_page: GroupsSelect.PER_PAGE,
+ all_available,
+ };
},
- formatSelection: function() {
- var args;
- args = 1 <= arguments.length ? slice.call(arguments, 0) : [];
- return self.formatSelection.apply(self, args);
+ results: function (data, page) {
+ if (data.length) return { results: [] };
+
+ const groups = data.length ? data : data.results || [];
+ const more = data.pagination ? data.pagination.more : false;
+ const results = groups.filter(group => skip_groups.indexOf(group.id) === -1);
+
+ return {
+ results,
+ page,
+ more,
+ };
},
- dropdownCssClass: "ajax-groups-dropdown select2-infinite",
- // we do not want to escape markup since we are displaying html in results
- escapeMarkup: function(m) {
- return m;
+ },
+ initSelection: function(element, callback) {
+ var id;
+ id = $(element).val();
+ if (id !== "") {
+ return Api.group(id, callback);
}
- });
+ },
+ formatResult: function() {
+ var args;
+ args = 1 <= arguments.length ? slice.call(arguments, 0) : [];
+ return self.formatResult.apply(self, args);
+ },
+ formatSelection: function() {
+ var args;
+ args = 1 <= arguments.length ? slice.call(arguments, 0) : [];
+ return self.formatSelection.apply(self, args);
+ },
+ dropdownCssClass: "ajax-groups-dropdown select2-infinite",
+ // we do not want to escape markup since we are displaying html in results
+ escapeMarkup: function(m) {
+ return m;
+ }
+ });
- self.dropdown = document.querySelector('.select2-infinite .select2-results');
+ self.dropdown = document.querySelector('.select2-infinite .select2-results');
- $select.on('select2-loaded', self.forceOverflow.bind(self));
- };
- })(this));
- }
+ $select.on('select2-loaded', self.forceOverflow.bind(self));
+ };
+ })(this));
+}
- GroupsSelect.prototype.formatResult = function(group) {
- var avatar;
- if (group.avatar_url) {
- avatar = group.avatar_url;
- } else {
- avatar = gon.default_avatar_url;
- }
- return "<div class='group-result'> <div class='group-name'>" + group.full_name + "</div> <div class='group-path'>" + group.full_path + "</div> </div>";
- };
+GroupsSelect.prototype.formatResult = function(group) {
+ var avatar;
+ if (group.avatar_url) {
+ avatar = group.avatar_url;
+ } else {
+ avatar = gon.default_avatar_url;
+ }
+ return "<div class='group-result'> <div class='group-name'>" + group.full_name + "</div> <div class='group-path'>" + group.full_path + "</div> </div>";
+};
- GroupsSelect.prototype.formatSelection = function(group) {
- return group.full_name;
- };
+GroupsSelect.prototype.formatSelection = function(group) {
+ return group.full_name;
+};
- GroupsSelect.prototype.forceOverflow = function (e) {
- const itemHeight = this.dropdown.querySelector('.select2-result:first-child').clientHeight;
- this.dropdown.style.height = `${Math.floor(this.dropdown.scrollHeight - (itemHeight * 0.9))}px`;
- };
+GroupsSelect.prototype.forceOverflow = function (e) {
+ const itemHeight = this.dropdown.querySelector('.select2-result:first-child').clientHeight;
+ this.dropdown.style.height = `${Math.floor(this.dropdown.scrollHeight - (itemHeight * 0.9))}px`;
+};
- GroupsSelect.PER_PAGE = 20;
+GroupsSelect.PER_PAGE = 20;
- return GroupsSelect;
-})();
+window.GroupsSelect = GroupsSelect;
diff --git a/app/assets/javascripts/importer_status.js b/app/assets/javascripts/importer_status.js
index 5b4ca94ed30..3d97938c0f3 100644
--- a/app/assets/javascripts/importer_status.js
+++ b/app/assets/javascripts/importer_status.js
@@ -1,83 +1,79 @@
/* eslint-disable func-names, space-before-function-paren, wrap-iife, camelcase, no-var, one-var, one-var-declaration-per-line, prefer-template, quotes, object-shorthand, comma-dangle, no-unused-vars, prefer-arrow-callback, no-else-return, vars-on-top, no-new, max-len */
-(function() {
- window.ImporterStatus = (function() {
- function ImporterStatus(jobs_url, import_url) {
- this.jobs_url = jobs_url;
- this.import_url = import_url;
- this.initStatusPage();
- this.setAutoUpdate();
- }
+function ImporterStatus(jobs_url, import_url) {
+ this.jobs_url = jobs_url;
+ this.import_url = import_url;
+ this.initStatusPage();
+ this.setAutoUpdate();
+}
- ImporterStatus.prototype.initStatusPage = function() {
- $('.js-add-to-import').off('click').on('click', (function(_this) {
- return function(e) {
- var $btn, $namespace_input, $target_field, $tr, id, target_namespace, newName;
- $btn = $(e.currentTarget);
- $tr = $btn.closest('tr');
- $target_field = $tr.find('.import-target');
- $namespace_input = $target_field.find('.js-select-namespace option:selected');
- id = $tr.attr('id').replace('repo_', '');
- target_namespace = null;
- newName = null;
- if ($namespace_input.length > 0) {
- target_namespace = $namespace_input[0].innerHTML;
- newName = $target_field.find('#path').prop('value');
- $target_field.empty().append(target_namespace + "/" + newName);
- }
- $btn.disable().addClass('is-loading');
- return $.post(_this.import_url, {
- repo_id: id,
- target_namespace: target_namespace,
- new_name: newName
- }, {
- dataType: 'script'
- });
- };
- })(this));
- return $('.js-import-all').off('click').on('click', function(e) {
- var $btn;
- $btn = $(this);
- $btn.disable().addClass('is-loading');
- return $('.js-add-to-import').each(function() {
- return $(this).trigger('click');
- });
+ImporterStatus.prototype.initStatusPage = function() {
+ $('.js-add-to-import').off('click').on('click', (function(_this) {
+ return function(e) {
+ var $btn, $namespace_input, $target_field, $tr, id, target_namespace, newName;
+ $btn = $(e.currentTarget);
+ $tr = $btn.closest('tr');
+ $target_field = $tr.find('.import-target');
+ $namespace_input = $target_field.find('.js-select-namespace option:selected');
+ id = $tr.attr('id').replace('repo_', '');
+ target_namespace = null;
+ newName = null;
+ if ($namespace_input.length > 0) {
+ target_namespace = $namespace_input[0].innerHTML;
+ newName = $target_field.find('#path').prop('value');
+ $target_field.empty().append(target_namespace + "/" + newName);
+ }
+ $btn.disable().addClass('is-loading');
+ return $.post(_this.import_url, {
+ repo_id: id,
+ target_namespace: target_namespace,
+ new_name: newName
+ }, {
+ dataType: 'script'
});
};
+ })(this));
+ return $('.js-import-all').off('click').on('click', function(e) {
+ var $btn;
+ $btn = $(this);
+ $btn.disable().addClass('is-loading');
+ return $('.js-add-to-import').each(function() {
+ return $(this).trigger('click');
+ });
+ });
+};
- ImporterStatus.prototype.setAutoUpdate = function() {
- return setInterval(((function(_this) {
- return function() {
- return $.get(_this.jobs_url, function(data) {
- return $.each(data, function(i, job) {
- var job_item, status_field;
- job_item = $("#project_" + job.id);
- status_field = job_item.find(".job-status");
- if (job.import_status === 'finished') {
- job_item.removeClass("active").addClass("success");
- return status_field.html('<span><i class="fa fa-check"></i> done</span>');
- } else if (job.import_status === 'scheduled') {
- return status_field.html("<i class='fa fa-spinner fa-spin'></i> scheduled");
- } else if (job.import_status === 'started') {
- return status_field.html("<i class='fa fa-spinner fa-spin'></i> started");
- } else {
- return status_field.html(job.import_status);
- }
- });
- });
- };
- })(this)), 4000);
+ImporterStatus.prototype.setAutoUpdate = function() {
+ return setInterval(((function(_this) {
+ return function() {
+ return $.get(_this.jobs_url, function(data) {
+ return $.each(data, function(i, job) {
+ var job_item, status_field;
+ job_item = $("#project_" + job.id);
+ status_field = job_item.find(".job-status");
+ if (job.import_status === 'finished') {
+ job_item.removeClass("active").addClass("success");
+ return status_field.html('<span><i class="fa fa-check"></i> done</span>');
+ } else if (job.import_status === 'scheduled') {
+ return status_field.html("<i class='fa fa-spinner fa-spin'></i> scheduled");
+ } else if (job.import_status === 'started') {
+ return status_field.html("<i class='fa fa-spinner fa-spin'></i> started");
+ } else {
+ return status_field.html(job.import_status);
+ }
+ });
+ });
};
+ })(this)), 4000);
+};
- return ImporterStatus;
- })();
+window.ImporterStatus = ImporterStatus;
- $(function() {
- if ($('.js-importer-status').length) {
- var jobsImportPath = $('.js-importer-status').data('jobs-import-path');
- var importPath = $('.js-importer-status').data('import-path');
+$(function() {
+ if ($('.js-importer-status').length) {
+ var jobsImportPath = $('.js-importer-status').data('jobs-import-path');
+ var importPath = $('.js-importer-status').data('import-path');
- new window.ImporterStatus(jobsImportPath, importPath);
- }
- });
-}).call(window);
+ new window.ImporterStatus(jobsImportPath, importPath);
+ }
+});
diff --git a/app/assets/javascripts/issuable_context.js b/app/assets/javascripts/issuable_context.js
index a4d7bf096ef..e8cfc0241fe 100644
--- a/app/assets/javascripts/issuable_context.js
+++ b/app/assets/javascripts/issuable_context.js
@@ -4,76 +4,72 @@
import Cookies from 'js-cookie';
import UsersSelect from './users_select';
-(function() {
- this.IssuableContext = (function() {
- function IssuableContext(currentUser) {
- this.initParticipants();
- new UsersSelect(currentUser);
- $('select.select2').select2({
- width: 'resolve',
- dropdownAutoWidth: true
- });
- $(".issuable-sidebar .inline-update").on("change", "select", function() {
- return $(this).submit();
- });
- $(".issuable-sidebar .inline-update").on("change", ".js-assignee", function() {
- return $(this).submit();
- });
- $(document).off('click', '.issuable-sidebar .dropdown-content a').on('click', '.issuable-sidebar .dropdown-content a', function(e) {
- return e.preventDefault();
- });
- $(document).off('click', '.edit-link').on('click', '.edit-link', function(e) {
- var $block, $selectbox;
- e.preventDefault();
- $block = $(this).parents('.block');
- $selectbox = $block.find('.selectbox');
- if ($selectbox.is(':visible')) {
- $selectbox.hide();
- $block.find('.value').show();
- } else {
- $selectbox.show();
- $block.find('.value').hide();
- }
- if ($selectbox.is(':visible')) {
- return setTimeout(function() {
- return $block.find('.dropdown-menu-toggle').trigger('click');
- }, 0);
- }
- });
- window.addEventListener('beforeunload', function() {
- // collapsed_gutter cookie hides the sidebar
- var bpBreakpoint = bp.getBreakpointSize();
- if (bpBreakpoint === 'xs' || bpBreakpoint === 'sm') {
- Cookies.set('collapsed_gutter', true);
- }
- });
+function IssuableContext(currentUser) {
+ this.initParticipants();
+ new UsersSelect(currentUser);
+ $('select.select2').select2({
+ width: 'resolve',
+ dropdownAutoWidth: true
+ });
+ $(".issuable-sidebar .inline-update").on("change", "select", function() {
+ return $(this).submit();
+ });
+ $(".issuable-sidebar .inline-update").on("change", ".js-assignee", function() {
+ return $(this).submit();
+ });
+ $(document).off('click', '.issuable-sidebar .dropdown-content a').on('click', '.issuable-sidebar .dropdown-content a', function(e) {
+ return e.preventDefault();
+ });
+ $(document).off('click', '.edit-link').on('click', '.edit-link', function(e) {
+ var $block, $selectbox;
+ e.preventDefault();
+ $block = $(this).parents('.block');
+ $selectbox = $block.find('.selectbox');
+ if ($selectbox.is(':visible')) {
+ $selectbox.hide();
+ $block.find('.value').show();
+ } else {
+ $selectbox.show();
+ $block.find('.value').hide();
}
+ if ($selectbox.is(':visible')) {
+ return setTimeout(function() {
+ return $block.find('.dropdown-menu-toggle').trigger('click');
+ }, 0);
+ }
+ });
+ window.addEventListener('beforeunload', function() {
+ // collapsed_gutter cookie hides the sidebar
+ var bpBreakpoint = bp.getBreakpointSize();
+ if (bpBreakpoint === 'xs' || bpBreakpoint === 'sm') {
+ Cookies.set('collapsed_gutter', true);
+ }
+ });
+}
- IssuableContext.prototype.initParticipants = function() {
- var _this;
- _this = this;
- $(document).on("click", ".js-participants-more", this.toggleHiddenParticipants);
- return $(".js-participants-author").each(function(i) {
- if (i >= _this.PARTICIPANTS_ROW_COUNT) {
- return $(this).addClass("js-participants-hidden").hide();
- }
- });
- };
+IssuableContext.prototype.initParticipants = function() {
+ var _this;
+ _this = this;
+ $(document).on("click", ".js-participants-more", this.toggleHiddenParticipants);
+ return $(".js-participants-author").each(function(i) {
+ if (i >= _this.PARTICIPANTS_ROW_COUNT) {
+ return $(this).addClass("js-participants-hidden").hide();
+ }
+ });
+};
- IssuableContext.prototype.toggleHiddenParticipants = function(e) {
- var currentText, lessText, originalText;
- e.preventDefault();
- currentText = $(this).text().trim();
- lessText = $(this).data("less-text");
- originalText = $(this).data("original-text");
- if (currentText === originalText) {
- $(this).text(lessText);
- } else {
- $(this).text(originalText);
- }
- return $(".js-participants-hidden").toggle();
- };
+IssuableContext.prototype.toggleHiddenParticipants = function(e) {
+ var currentText, lessText, originalText;
+ e.preventDefault();
+ currentText = $(this).text().trim();
+ lessText = $(this).data("less-text");
+ originalText = $(this).data("original-text");
+ if (currentText === originalText) {
+ $(this).text(lessText);
+ } else {
+ $(this).text(originalText);
+ }
+ return $(".js-participants-hidden").toggle();
+};
- return IssuableContext;
- })();
-}).call(window);
+window.IssuableContext = IssuableContext;
diff --git a/app/assets/javascripts/issuable_form.js b/app/assets/javascripts/issuable_form.js
index 9ac1325fc95..b43e60e1de8 100644
--- a/app/assets/javascripts/issuable_form.js
+++ b/app/assets/javascripts/issuable_form.js
@@ -8,153 +8,149 @@ import UsersSelect from './users_select';
import GfmAutoComplete from './gfm_auto_complete';
import ZenMode from './zen_mode';
-(function() {
- this.IssuableForm = (function() {
- IssuableForm.prototype.issueMoveConfirmMsg = 'Are you sure you want to move this issue to another project?';
-
- IssuableForm.prototype.wipRegex = /^\s*(\[WIP\]\s*|WIP:\s*|WIP\s+)+\s*/i;
-
- function IssuableForm(form) {
- var $issuableDueDate, calendar;
- this.form = form;
- this.toggleWip = this.toggleWip.bind(this);
- this.renderWipExplanation = this.renderWipExplanation.bind(this);
- this.resetAutosave = this.resetAutosave.bind(this);
- this.handleSubmit = this.handleSubmit.bind(this);
- new GfmAutoComplete(gl.GfmAutoComplete && gl.GfmAutoComplete.dataSources).setup();
- new UsersSelect();
- new ZenMode();
- this.titleField = this.form.find("input[name*='[title]']");
- this.descriptionField = this.form.find("textarea[name*='[description]']");
- this.issueMoveField = this.form.find("#move_to_project_id");
- if (!(this.titleField.length && this.descriptionField.length)) {
- return;
+function IssuableForm(form) {
+ var $issuableDueDate, calendar;
+ this.form = form;
+ this.toggleWip = this.toggleWip.bind(this);
+ this.renderWipExplanation = this.renderWipExplanation.bind(this);
+ this.resetAutosave = this.resetAutosave.bind(this);
+ this.handleSubmit = this.handleSubmit.bind(this);
+ new GfmAutoComplete(gl.GfmAutoComplete && gl.GfmAutoComplete.dataSources).setup();
+ new UsersSelect();
+ new ZenMode();
+ this.titleField = this.form.find("input[name*='[title]']");
+ this.descriptionField = this.form.find("textarea[name*='[description]']");
+ this.issueMoveField = this.form.find("#move_to_project_id");
+ if (!(this.titleField.length && this.descriptionField.length)) {
+ return;
+ }
+ this.initAutosave();
+ this.form.on("submit", this.handleSubmit);
+ this.form.on("click", ".btn-cancel", this.resetAutosave);
+ this.initWip();
+ this.initMoveDropdown();
+ $issuableDueDate = $('#issuable-due-date');
+ if ($issuableDueDate.length) {
+ calendar = new Pikaday({
+ field: $issuableDueDate.get(0),
+ theme: 'gitlab-theme animate-picker',
+ format: 'yyyy-mm-dd',
+ container: $issuableDueDate.parent().get(0),
+ onSelect: function(dateText) {
+ $issuableDueDate.val(dateFormat(new Date(dateText), 'yyyy-mm-dd'));
}
- this.initAutosave();
- this.form.on("submit", this.handleSubmit);
- this.form.on("click", ".btn-cancel", this.resetAutosave);
- this.initWip();
- this.initMoveDropdown();
- $issuableDueDate = $('#issuable-due-date');
- if ($issuableDueDate.length) {
- calendar = new Pikaday({
- field: $issuableDueDate.get(0),
- theme: 'gitlab-theme animate-picker',
- format: 'yyyy-mm-dd',
- container: $issuableDueDate.parent().get(0),
- onSelect: function(dateText) {
- $issuableDueDate.val(dateFormat(new Date(dateText), 'yyyy-mm-dd'));
- }
- });
- calendar.setDate(new Date($issuableDueDate.val()));
- }
- }
+ });
+ calendar.setDate(new Date($issuableDueDate.val()));
+ }
+}
+
+IssuableForm.prototype.issueMoveConfirmMsg = 'Are you sure you want to move this issue to another project?';
- IssuableForm.prototype.initAutosave = function() {
- new Autosave(this.titleField, [document.location.pathname, document.location.search, "title"]);
- return new Autosave(this.descriptionField, [document.location.pathname, document.location.search, "description"]);
- };
+IssuableForm.prototype.wipRegex = /^\s*(\[WIP\]\s*|WIP:\s*|WIP\s+)+\s*/i;
- IssuableForm.prototype.handleSubmit = function() {
- var fieldId = (this.issueMoveField != null) ? this.issueMoveField.val() : null;
- if ((parseInt(fieldId, 10) || 0) > 0) {
- if (!confirm(this.issueMoveConfirmMsg)) {
- return false;
+IssuableForm.prototype.initAutosave = function() {
+ new Autosave(this.titleField, [document.location.pathname, document.location.search, "title"]);
+ return new Autosave(this.descriptionField, [document.location.pathname, document.location.search, "description"]);
+};
+
+IssuableForm.prototype.handleSubmit = function() {
+ var fieldId = (this.issueMoveField != null) ? this.issueMoveField.val() : null;
+ if ((parseInt(fieldId, 10) || 0) > 0) {
+ if (!confirm(this.issueMoveConfirmMsg)) {
+ return false;
+ }
+ }
+ return this.resetAutosave();
+};
+
+IssuableForm.prototype.resetAutosave = function() {
+ this.titleField.data("autosave").reset();
+ return this.descriptionField.data("autosave").reset();
+};
+
+IssuableForm.prototype.initWip = function() {
+ this.$wipExplanation = this.form.find(".js-wip-explanation");
+ this.$noWipExplanation = this.form.find(".js-no-wip-explanation");
+ if (!(this.$wipExplanation.length && this.$noWipExplanation.length)) {
+ return;
+ }
+ this.form.on("click", ".js-toggle-wip", this.toggleWip);
+ this.titleField.on("keyup blur", this.renderWipExplanation);
+ return this.renderWipExplanation();
+};
+
+IssuableForm.prototype.workInProgress = function() {
+ return this.wipRegex.test(this.titleField.val());
+};
+
+IssuableForm.prototype.renderWipExplanation = function() {
+ if (this.workInProgress()) {
+ this.$wipExplanation.show();
+ return this.$noWipExplanation.hide();
+ } else {
+ this.$wipExplanation.hide();
+ return this.$noWipExplanation.show();
+ }
+};
+
+IssuableForm.prototype.toggleWip = function(event) {
+ event.preventDefault();
+ if (this.workInProgress()) {
+ this.removeWip();
+ } else {
+ this.addWip();
+ }
+ return this.renderWipExplanation();
+};
+
+IssuableForm.prototype.removeWip = function() {
+ return this.titleField.val(this.titleField.val().replace(this.wipRegex, ""));
+};
+
+IssuableForm.prototype.addWip = function() {
+ return this.titleField.val("WIP: " + (this.titleField.val()));
+};
+
+IssuableForm.prototype.initMoveDropdown = function() {
+ var $moveDropdown, pageSize;
+ $moveDropdown = $('.js-move-dropdown');
+ if ($moveDropdown.length) {
+ pageSize = $moveDropdown.data('page-size');
+ return $('.js-move-dropdown').select2({
+ ajax: {
+ url: $moveDropdown.data('projects-url'),
+ quietMillis: 125,
+ data: function(term, page, context) {
+ return {
+ search: term,
+ offset_id: context
+ };
+ },
+ results: function(data) {
+ var context,
+ more;
+
+ if (data.length >= pageSize)
+ more = true;
+
+ if (data[data.length - 1])
+ context = data[data.length - 1].id;
+
+ return {
+ results: data,
+ more: more,
+ context: context
+ };
}
+ },
+ formatResult: function(project) {
+ return project.name_with_namespace;
+ },
+ formatSelection: function(project) {
+ return project.name_with_namespace;
}
- return this.resetAutosave();
- };
-
- IssuableForm.prototype.resetAutosave = function() {
- this.titleField.data("autosave").reset();
- return this.descriptionField.data("autosave").reset();
- };
-
- IssuableForm.prototype.initWip = function() {
- this.$wipExplanation = this.form.find(".js-wip-explanation");
- this.$noWipExplanation = this.form.find(".js-no-wip-explanation");
- if (!(this.$wipExplanation.length && this.$noWipExplanation.length)) {
- return;
- }
- this.form.on("click", ".js-toggle-wip", this.toggleWip);
- this.titleField.on("keyup blur", this.renderWipExplanation);
- return this.renderWipExplanation();
- };
-
- IssuableForm.prototype.workInProgress = function() {
- return this.wipRegex.test(this.titleField.val());
- };
-
- IssuableForm.prototype.renderWipExplanation = function() {
- if (this.workInProgress()) {
- this.$wipExplanation.show();
- return this.$noWipExplanation.hide();
- } else {
- this.$wipExplanation.hide();
- return this.$noWipExplanation.show();
- }
- };
-
- IssuableForm.prototype.toggleWip = function(event) {
- event.preventDefault();
- if (this.workInProgress()) {
- this.removeWip();
- } else {
- this.addWip();
- }
- return this.renderWipExplanation();
- };
-
- IssuableForm.prototype.removeWip = function() {
- return this.titleField.val(this.titleField.val().replace(this.wipRegex, ""));
- };
-
- IssuableForm.prototype.addWip = function() {
- return this.titleField.val("WIP: " + (this.titleField.val()));
- };
-
- IssuableForm.prototype.initMoveDropdown = function() {
- var $moveDropdown, pageSize;
- $moveDropdown = $('.js-move-dropdown');
- if ($moveDropdown.length) {
- pageSize = $moveDropdown.data('page-size');
- return $('.js-move-dropdown').select2({
- ajax: {
- url: $moveDropdown.data('projects-url'),
- quietMillis: 125,
- data: function(term, page, context) {
- return {
- search: term,
- offset_id: context
- };
- },
- results: function(data) {
- var context,
- more;
-
- if (data.length >= pageSize)
- more = true;
-
- if (data[data.length - 1])
- context = data[data.length - 1].id;
-
- return {
- results: data,
- more: more,
- context: context
- };
- }
- },
- formatResult: function(project) {
- return project.name_with_namespace;
- },
- formatSelection: function(project) {
- return project.name_with_namespace;
- }
- });
- }
- };
+ });
+ }
+};
- return IssuableForm;
- })();
-}).call(window);
+window.IssuableForm = IssuableForm;
diff --git a/app/assets/javascripts/issuable_index.js b/app/assets/javascripts/issuable_index.js
index 5c96646def8..4f3f5e0527c 100644
--- a/app/assets/javascripts/issuable_index.js
+++ b/app/assets/javascripts/issuable_index.js
@@ -4,168 +4,166 @@
import IssuableBulkUpdateSidebar from './issuable_bulk_update_sidebar';
import IssuableBulkUpdateActions from './issuable_bulk_update_actions';
-((global) => {
- var issuable_created;
-
- issuable_created = false;
-
- global.IssuableIndex = {
- init: function(pagePrefix) {
- IssuableIndex.initTemplates();
- IssuableIndex.initSearch();
- IssuableIndex.initBulkUpdate(pagePrefix);
- IssuableIndex.initResetFilters();
- IssuableIndex.resetIncomingEmailToken();
- IssuableIndex.initLabelFilterRemove();
- },
- initTemplates: function() {
- return IssuableIndex.labelRow = _.template('<% _.each(labels, function(label){ %> <span class="label-row btn-group" role="group" aria-label="<%- label.title %>" style="color: <%- label.text_color %>;"> <a href="#" class="btn btn-transparent has-tooltip" style="background-color: <%- label.color %>;" title="<%- label.description %>" data-container="body"> <%- label.title %> </a> <button type="button" class="btn btn-transparent label-remove js-label-filter-remove" style="background-color: <%- label.color %>;" data-label="<%- label.title %>"> <i class="fa fa-times"></i> </button> </span> <% }); %>');
- },
- initSearch: function() {
- const $searchInput = $('#issuable_search');
-
- IssuableIndex.initSearchState($searchInput);
-
- // `immediate` param set to false debounces on the `trailing` edge, lets user finish typing
- const debouncedExecSearch = _.debounce(IssuableIndex.executeSearch, 1000, false);
-
- $searchInput.off('keyup').on('keyup', debouncedExecSearch);
-
- // ensures existing filters are preserved when manually submitted
- $('#issuable_search_form').on('submit', (e) => {
- e.preventDefault();
- debouncedExecSearch(e);
- });
- },
- initSearchState: function($searchInput) {
- const currentSearchVal = $searchInput.val();
-
- IssuableIndex.searchState = {
- elem: $searchInput,
- current: currentSearchVal
- };
-
- IssuableIndex.maybeFocusOnSearch();
- },
- accessSearchPristine: function(set) {
- // store reference to previous value to prevent search on non-mutating keyup
- const state = IssuableIndex.searchState;
- const currentSearchVal = state.elem.val();
-
- if (set) {
- state.current = currentSearchVal;
+var issuable_created;
+
+issuable_created = false;
+
+window.IssuableIndex = {
+ init: function(pagePrefix) {
+ IssuableIndex.initTemplates();
+ IssuableIndex.initSearch();
+ IssuableIndex.initBulkUpdate(pagePrefix);
+ IssuableIndex.initResetFilters();
+ IssuableIndex.resetIncomingEmailToken();
+ IssuableIndex.initLabelFilterRemove();
+ },
+ initTemplates: function() {
+ return IssuableIndex.labelRow = _.template('<% _.each(labels, function(label){ %> <span class="label-row btn-group" role="group" aria-label="<%- label.title %>" style="color: <%- label.text_color %>;"> <a href="#" class="btn btn-transparent has-tooltip" style="background-color: <%- label.color %>;" title="<%- label.description %>" data-container="body"> <%- label.title %> </a> <button type="button" class="btn btn-transparent label-remove js-label-filter-remove" style="background-color: <%- label.color %>;" data-label="<%- label.title %>"> <i class="fa fa-times"></i> </button> </span> <% }); %>');
+ },
+ initSearch: function() {
+ const $searchInput = $('#issuable_search');
+
+ IssuableIndex.initSearchState($searchInput);
+
+ // `immediate` param set to false debounces on the `trailing` edge, lets user finish typing
+ const debouncedExecSearch = _.debounce(IssuableIndex.executeSearch, 1000, false);
+
+ $searchInput.off('keyup').on('keyup', debouncedExecSearch);
+
+ // ensures existing filters are preserved when manually submitted
+ $('#issuable_search_form').on('submit', (e) => {
+ e.preventDefault();
+ debouncedExecSearch(e);
+ });
+ },
+ initSearchState: function($searchInput) {
+ const currentSearchVal = $searchInput.val();
+
+ IssuableIndex.searchState = {
+ elem: $searchInput,
+ current: currentSearchVal
+ };
+
+ IssuableIndex.maybeFocusOnSearch();
+ },
+ accessSearchPristine: function(set) {
+ // store reference to previous value to prevent search on non-mutating keyup
+ const state = IssuableIndex.searchState;
+ const currentSearchVal = state.elem.val();
+
+ if (set) {
+ state.current = currentSearchVal;
+ } else {
+ return state.current === currentSearchVal;
+ }
+ },
+ maybeFocusOnSearch: function() {
+ const currentSearchVal = IssuableIndex.searchState.current;
+ if (currentSearchVal && currentSearchVal !== '') {
+ const queryLength = currentSearchVal.length;
+ const $searchInput = IssuableIndex.searchState.elem;
+
+ /* The following ensures that the cursor is initially placed at
+ * the end of search input when focus is applied. It accounts
+ * for differences in browser implementations of `setSelectionRange`
+ * and cursor placement for elements in focus.
+ */
+ $searchInput.focus();
+ if ($searchInput.setSelectionRange) {
+ $searchInput.setSelectionRange(queryLength, queryLength);
} else {
- return state.current === currentSearchVal;
- }
- },
- maybeFocusOnSearch: function() {
- const currentSearchVal = IssuableIndex.searchState.current;
- if (currentSearchVal && currentSearchVal !== '') {
- const queryLength = currentSearchVal.length;
- const $searchInput = IssuableIndex.searchState.elem;
-
- /* The following ensures that the cursor is initially placed at
- * the end of search input when focus is applied. It accounts
- * for differences in browser implementations of `setSelectionRange`
- * and cursor placement for elements in focus.
- */
- $searchInput.focus();
- if ($searchInput.setSelectionRange) {
- $searchInput.setSelectionRange(queryLength, queryLength);
- } else {
- $searchInput.val(currentSearchVal);
- }
- }
- },
- executeSearch: function(e) {
- const $search = $('#issuable_search');
- const $searchName = $search.attr('name');
- const $searchValue = $search.val();
- const $filtersForm = $('.js-filter-form');
- const $input = $(`input[name='${$searchName}']`, $filtersForm);
- const isPristine = IssuableIndex.accessSearchPristine();
-
- if (isPristine) {
- return;
+ $searchInput.val(currentSearchVal);
}
+ }
+ },
+ executeSearch: function(e) {
+ const $search = $('#issuable_search');
+ const $searchName = $search.attr('name');
+ const $searchValue = $search.val();
+ const $filtersForm = $('.js-filter-form');
+ const $input = $(`input[name='${$searchName}']`, $filtersForm);
+ const isPristine = IssuableIndex.accessSearchPristine();
+
+ if (isPristine) {
+ return;
+ }
- if (!$input.length) {
- $filtersForm.append(`<input type='hidden' name='${$searchName}' value='${_.escape($searchValue)}'/>`);
- } else {
- $input.val($searchValue);
- }
+ if (!$input.length) {
+ $filtersForm.append(`<input type='hidden' name='${$searchName}' value='${_.escape($searchValue)}'/>`);
+ } else {
+ $input.val($searchValue);
+ }
- IssuableIndex.filterResults($filtersForm);
- },
- initLabelFilterRemove: function() {
- 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
- IssuableIndex.filterResults($('.filter-form'));
+ IssuableIndex.filterResults($filtersForm);
+ },
+ initLabelFilterRemove: function() {
+ 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
+ IssuableIndex.filterResults($('.filter-form'));
+ });
+ },
+ filterResults: (function(_this) {
+ return function(form) {
+ var formAction, formData, issuesUrl;
+ formData = form.serializeArray();
+ formData = formData.filter(function(data) {
+ return data.value !== '';
});
- },
- filterResults: (function(_this) {
- return function(form) {
- var formAction, formData, issuesUrl;
- formData = form.serializeArray();
- formData = formData.filter(function(data) {
- return data.value !== '';
- });
- formData = $.param(formData);
- formAction = form.attr('action');
- issuesUrl = formAction;
- issuesUrl += "" + (formAction.indexOf('?') === -1 ? '?' : '&');
- issuesUrl += formData;
- return gl.utils.visitUrl(issuesUrl);
- };
- })(this),
- initResetFilters: function() {
- $('.reset-filters').on('click', function(e) {
- e.preventDefault();
- const target = e.target;
- const $form = $(target).parents('.js-filter-form');
- const baseIssuesUrl = target.href;
-
- $form.attr('action', baseIssuesUrl);
- gl.utils.visitUrl(baseIssuesUrl);
+ formData = $.param(formData);
+ formAction = form.attr('action');
+ issuesUrl = formAction;
+ issuesUrl += "" + (formAction.indexOf('?') === -1 ? '?' : '&');
+ issuesUrl += formData;
+ return gl.utils.visitUrl(issuesUrl);
+ };
+ })(this),
+ initResetFilters: function() {
+ $('.reset-filters').on('click', function(e) {
+ e.preventDefault();
+ const target = e.target;
+ const $form = $(target).parents('.js-filter-form');
+ const baseIssuesUrl = target.href;
+
+ $form.attr('action', baseIssuesUrl);
+ gl.utils.visitUrl(baseIssuesUrl);
+ });
+ },
+ initBulkUpdate: function(pagePrefix) {
+ const userCanBulkUpdate = $('.issues-bulk-update').length > 0;
+ const alreadyInitialized = !!this.bulkUpdateSidebar;
+
+ if (userCanBulkUpdate && !alreadyInitialized) {
+ IssuableBulkUpdateActions.init({
+ prefixId: pagePrefix,
});
- },
- initBulkUpdate: function(pagePrefix) {
- const userCanBulkUpdate = $('.issues-bulk-update').length > 0;
- const alreadyInitialized = !!this.bulkUpdateSidebar;
- if (userCanBulkUpdate && !alreadyInitialized) {
- IssuableBulkUpdateActions.init({
- prefixId: pagePrefix,
- });
-
- this.bulkUpdateSidebar = new IssuableBulkUpdateSidebar();
- }
- },
- resetIncomingEmailToken: function() {
- $('.incoming-email-token-reset').on('click', function(e) {
- e.preventDefault();
-
- $.ajax({
- type: 'PUT',
- url: $('.incoming-email-token-reset').attr('href'),
- dataType: 'json',
- success: function(response) {
- $('#issue_email').val(response.new_issue_address).focus();
- },
- beforeSend: function() {
- $('.incoming-email-token-reset').text('resetting...');
- },
- complete: function() {
- $('.incoming-email-token-reset').text('reset it');
- }
- });
- });
+ this.bulkUpdateSidebar = new IssuableBulkUpdateSidebar();
}
- };
-})(window);
+ },
+ resetIncomingEmailToken: function() {
+ $('.incoming-email-token-reset').on('click', function(e) {
+ e.preventDefault();
+
+ $.ajax({
+ type: 'PUT',
+ url: $('.incoming-email-token-reset').attr('href'),
+ dataType: 'json',
+ success: function(response) {
+ $('#issue_email').val(response.new_issue_address).focus();
+ },
+ beforeSend: function() {
+ $('.incoming-email-token-reset').text('resetting...');
+ },
+ complete: function() {
+ $('.incoming-email-token-reset').text('reset it');
+ }
+ });
+ });
+ }
+};
diff --git a/app/assets/javascripts/issue_status_select.js b/app/assets/javascripts/issue_status_select.js
index 56cb536dcde..097939097cf 100644
--- a/app/assets/javascripts/issue_status_select.js
+++ b/app/assets/javascripts/issue_status_select.js
@@ -1,34 +1,31 @@
/* eslint-disable func-names, space-before-function-paren, wrap-iife, no-var, quotes, object-shorthand, no-unused-vars, no-shadow, one-var, one-var-declaration-per-line, comma-dangle, max-len */
-(function() {
- this.IssueStatusSelect = (function() {
- function IssueStatusSelect() {
- $('.js-issue-status').each(function(i, el) {
- var fieldName;
- fieldName = $(el).data("field-name");
- return $(el).glDropdown({
- selectable: true,
- fieldName: fieldName,
- toggleLabel: (function(_this) {
- return function(selected, el, instance) {
- var $item, label;
- label = 'Author';
- $item = instance.dropdown.find('.is-active');
- if ($item.length) {
- label = $item.text();
- }
- return label;
- };
- })(this),
- clicked: function(options) {
- return options.e.preventDefault();
- },
- id: function(obj, el) {
- return $(el).data("id");
+
+function IssueStatusSelect() {
+ $('.js-issue-status').each(function(i, el) {
+ var fieldName;
+ fieldName = $(el).data("field-name");
+ return $(el).glDropdown({
+ selectable: true,
+ fieldName: fieldName,
+ toggleLabel: (function(_this) {
+ return function(selected, el, instance) {
+ var $item, label;
+ label = 'Author';
+ $item = instance.dropdown.find('.is-active');
+ if ($item.length) {
+ label = $item.text();
}
- });
- });
- }
+ return label;
+ };
+ })(this),
+ clicked: function(options) {
+ return options.e.preventDefault();
+ },
+ id: function(obj, el) {
+ return $(el).data("id");
+ }
+ });
+ });
+}
- return IssueStatusSelect;
- })();
-}).call(window);
+window.IssueStatusSelect = IssueStatusSelect;
diff --git a/app/assets/javascripts/label_manager.js b/app/assets/javascripts/label_manager.js
index d8814802d9e..4927abac4c1 100644
--- a/app/assets/javascripts/label_manager.js
+++ b/app/assets/javascripts/label_manager.js
@@ -1,124 +1,123 @@
/* eslint-disable comma-dangle, class-methods-use-this, no-underscore-dangle, no-param-reassign, no-unused-vars, consistent-return, func-names, space-before-function-paren, max-len */
/* global Flash */
/* global Sortable */
+const gl = window.gl || (window.gl = {});
-((global) => {
- class LabelManager {
- constructor({ togglePriorityButton, prioritizedLabels, otherLabels } = {}) {
- this.togglePriorityButton = togglePriorityButton || $('.js-toggle-priority');
- this.prioritizedLabels = prioritizedLabels || $('.js-prioritized-labels');
- this.otherLabels = otherLabels || $('.js-other-labels');
- this.errorMessage = 'Unable to update label prioritization at this time';
- this.emptyState = document.querySelector('#js-priority-labels-empty-state');
- this.sortable = Sortable.create(this.prioritizedLabels.get(0), {
- filter: '.empty-message',
- forceFallback: true,
- fallbackClass: 'is-dragging',
- dataIdAttr: 'data-id',
- onUpdate: this.onPrioritySortUpdate.bind(this),
- });
- this.bindEvents();
- }
+class LabelManager {
+ constructor({ togglePriorityButton, prioritizedLabels, otherLabels } = {}) {
+ this.togglePriorityButton = togglePriorityButton || $('.js-toggle-priority');
+ this.prioritizedLabels = prioritizedLabels || $('.js-prioritized-labels');
+ this.otherLabels = otherLabels || $('.js-other-labels');
+ this.errorMessage = 'Unable to update label prioritization at this time';
+ this.emptyState = document.querySelector('#js-priority-labels-empty-state');
+ this.sortable = Sortable.create(this.prioritizedLabels.get(0), {
+ filter: '.empty-message',
+ forceFallback: true,
+ fallbackClass: 'is-dragging',
+ dataIdAttr: 'data-id',
+ onUpdate: this.onPrioritySortUpdate.bind(this),
+ });
+ this.bindEvents();
+ }
- bindEvents() {
- this.prioritizedLabels.find('.btn-action').on('mousedown', this, this.onButtonActionClick);
- return this.togglePriorityButton.on('click', this, this.onTogglePriorityClick);
- }
+ bindEvents() {
+ this.prioritizedLabels.find('.btn-action').on('mousedown', this, this.onButtonActionClick);
+ return this.togglePriorityButton.on('click', this, this.onTogglePriorityClick);
+ }
- onTogglePriorityClick(e) {
- e.preventDefault();
- const _this = e.data;
- const $btn = $(e.currentTarget);
- const $label = $(`#${$btn.data('domId')}`);
- const action = $btn.parents('.js-prioritized-labels').length ? 'remove' : 'add';
- const $tooltip = $(`#${$btn.find('.has-tooltip:visible').attr('aria-describedby')}`);
- $tooltip.tooltip('destroy');
- _this.toggleLabelPriority($label, action);
- _this.toggleEmptyState($label, $btn, action);
- }
+ onTogglePriorityClick(e) {
+ e.preventDefault();
+ const _this = e.data;
+ const $btn = $(e.currentTarget);
+ const $label = $(`#${$btn.data('domId')}`);
+ const action = $btn.parents('.js-prioritized-labels').length ? 'remove' : 'add';
+ const $tooltip = $(`#${$btn.find('.has-tooltip:visible').attr('aria-describedby')}`);
+ $tooltip.tooltip('destroy');
+ _this.toggleLabelPriority($label, action);
+ _this.toggleEmptyState($label, $btn, action);
+ }
- onButtonActionClick(e) {
- e.stopPropagation();
- $(e.currentTarget).tooltip('hide');
- }
+ onButtonActionClick(e) {
+ e.stopPropagation();
+ $(e.currentTarget).tooltip('hide');
+ }
- toggleEmptyState($label, $btn, action) {
- this.emptyState.classList.toggle('hidden', !!this.prioritizedLabels[0].querySelector(':scope > li'));
- }
+ toggleEmptyState($label, $btn, action) {
+ this.emptyState.classList.toggle('hidden', !!this.prioritizedLabels[0].querySelector(':scope > li'));
+ }
- toggleLabelPriority($label, action, persistState) {
- if (persistState == null) {
- persistState = true;
- }
- let xhr;
- const _this = this;
- const url = $label.find('.js-toggle-priority').data('url');
- let $target = this.prioritizedLabels;
- let $from = this.otherLabels;
- if (action === 'remove') {
- $target = this.otherLabels;
- $from = this.prioritizedLabels;
- }
- $label.detach().appendTo($target);
- if ($from.find('li').length) {
- $from.find('.empty-message').removeClass('hidden');
- }
- if ($target.find('> li:not(.empty-message)').length) {
- $target.find('.empty-message').addClass('hidden');
- }
- // Return if we are not persisting state
- if (!persistState) {
- return;
- }
- if (action === 'remove') {
- xhr = $.ajax({
- url,
- type: 'DELETE'
- });
- // Restore empty message
- if (!$from.find('li').length) {
- $from.find('.empty-message').removeClass('hidden');
- }
- } else {
- xhr = this.savePrioritySort($label, action);
- }
- return xhr.fail(this.rollbackLabelPosition.bind(this, $label, action));
+ toggleLabelPriority($label, action, persistState) {
+ if (persistState == null) {
+ persistState = true;
}
-
- onPrioritySortUpdate() {
- const xhr = this.savePrioritySort();
- return xhr.fail(function() {
- return new Flash(this.errorMessage, 'alert');
- });
+ let xhr;
+ const _this = this;
+ const url = $label.find('.js-toggle-priority').data('url');
+ let $target = this.prioritizedLabels;
+ let $from = this.otherLabels;
+ if (action === 'remove') {
+ $target = this.otherLabels;
+ $from = this.prioritizedLabels;
}
-
- savePrioritySort() {
- return $.post({
- url: this.prioritizedLabels.data('url'),
- data: {
- label_ids: this.getSortedLabelsIds()
- }
+ $label.detach().appendTo($target);
+ if ($from.find('li').length) {
+ $from.find('.empty-message').removeClass('hidden');
+ }
+ if ($target.find('> li:not(.empty-message)').length) {
+ $target.find('.empty-message').addClass('hidden');
+ }
+ // Return if we are not persisting state
+ if (!persistState) {
+ return;
+ }
+ if (action === 'remove') {
+ xhr = $.ajax({
+ url,
+ type: 'DELETE'
});
+ // Restore empty message
+ if (!$from.find('li').length) {
+ $from.find('.empty-message').removeClass('hidden');
+ }
+ } else {
+ xhr = this.savePrioritySort($label, action);
}
+ return xhr.fail(this.rollbackLabelPosition.bind(this, $label, action));
+ }
- rollbackLabelPosition($label, originalAction) {
- const action = originalAction === 'remove' ? 'add' : 'remove';
- this.toggleLabelPriority($label, action, false);
+ onPrioritySortUpdate() {
+ const xhr = this.savePrioritySort();
+ return xhr.fail(function() {
return new Flash(this.errorMessage, 'alert');
- }
+ });
+ }
- getSortedLabelsIds() {
- const sortedIds = [];
- this.prioritizedLabels.find('> li').each(function() {
- const id = $(this).data('id');
+ savePrioritySort() {
+ return $.post({
+ url: this.prioritizedLabels.data('url'),
+ data: {
+ label_ids: this.getSortedLabelsIds()
+ }
+ });
+ }
- if (id) {
- sortedIds.push(id);
- }
- });
- return sortedIds;
- }
+ rollbackLabelPosition($label, originalAction) {
+ const action = originalAction === 'remove' ? 'add' : 'remove';
+ this.toggleLabelPriority($label, action, false);
+ return new Flash(this.errorMessage, 'alert');
+ }
+
+ getSortedLabelsIds() {
+ const sortedIds = [];
+ this.prioritizedLabels.find('> li').each(function() {
+ const id = $(this).data('id');
+
+ if (id) {
+ sortedIds.push(id);
+ }
+ });
+ return sortedIds;
}
+}
- gl.LabelManager = LabelManager;
-})(window.gl || (window.gl = {}));
+gl.LabelManager = LabelManager;
diff --git a/app/assets/javascripts/labels.js b/app/assets/javascripts/labels.js
index 03dd61b4263..5e87f26afba 100644
--- a/app/assets/javascripts/labels.js
+++ b/app/assets/javascripts/labels.js
@@ -1,44 +1,41 @@
/* eslint-disable func-names, space-before-function-paren, no-var, prefer-rest-params, wrap-iife, vars-on-top, no-unused-vars, max-len */
-(function() {
- this.Labels = (function() {
- function Labels() {
- this.setSuggestedColor = this.setSuggestedColor.bind(this);
- this.updateColorPreview = this.updateColorPreview.bind(this);
- var form;
- form = $('.label-form');
- this.cleanBinding();
- this.addBinding();
- this.updateColorPreview();
- }
- Labels.prototype.addBinding = function() {
- $(document).on('click', '.suggest-colors a', this.setSuggestedColor);
- return $(document).on('input', 'input#label_color', this.updateColorPreview);
- };
+function Labels() {
+ this.setSuggestedColor = this.setSuggestedColor.bind(this);
+ this.updateColorPreview = this.updateColorPreview.bind(this);
+ var form;
+ form = $('.label-form');
+ this.cleanBinding();
+ this.addBinding();
+ this.updateColorPreview();
+}
- Labels.prototype.cleanBinding = function() {
- $(document).off('click', '.suggest-colors a');
- return $(document).off('input', 'input#label_color');
- };
+Labels.prototype.addBinding = function() {
+ $(document).on('click', '.suggest-colors a', this.setSuggestedColor);
+ return $(document).on('input', 'input#label_color', this.updateColorPreview);
+};
- Labels.prototype.updateColorPreview = function() {
- 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
- };
+Labels.prototype.cleanBinding = function() {
+ $(document).off('click', '.suggest-colors a');
+ return $(document).off('input', 'input#label_color');
+};
- // 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();
- };
+Labels.prototype.updateColorPreview = function() {
+ 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
+};
- return Labels;
- })();
-}).call(window);
+// 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();
+};
+
+window.Labels = Labels;
diff --git a/app/assets/javascripts/labels_select.js b/app/assets/javascripts/labels_select.js
index 8d7d3d73571..1b0de126bff 100644
--- a/app/assets/javascripts/labels_select.js
+++ b/app/assets/javascripts/labels_select.js
@@ -4,492 +4,488 @@
import IssuableBulkUpdateActions from './issuable_bulk_update_actions';
-(function() {
- this.LabelsSelect = (function() {
- function LabelsSelect(els) {
- var _this, $els;
- _this = this;
+function LabelsSelect(els) {
+ var _this, $els;
+ _this = this;
+
+ $els = $(els);
+
+ if (!els) {
+ $els = $('.js-label-select');
+ }
+
+ $els.each(function(i, dropdown) {
+ var $block, $colorPreview, $dropdown, $form, $loading, $selectbox, $sidebarCollapsedValue, $value, abilityName, defaultLabel, enableLabelCreateButton, issueURLSplit, issueUpdateURL, labelHTMLTemplate, labelNoneHTMLTemplate, labelUrl, namespacePath, projectPath, saveLabelData, selectedLabel, showAny, showNo, $sidebarLabelTooltip, initialSelected, $toggleText, fieldName, useId, propertyName, showMenuAbove, $container, $dropdownContainer;
+ $dropdown = $(dropdown);
+ $dropdownContainer = $dropdown.closest('.labels-filter');
+ $toggleText = $dropdown.find('.dropdown-toggle-text');
+ namespacePath = $dropdown.data('namespace-path');
+ projectPath = $dropdown.data('project-path');
+ labelUrl = $dropdown.data('labels');
+ issueUpdateURL = $dropdown.data('issueUpdate');
+ selectedLabel = $dropdown.data('selected');
+ if ((selectedLabel != null) && !$dropdown.hasClass('js-multiselect')) {
+ selectedLabel = selectedLabel.split(',');
+ }
+ showNo = $dropdown.data('show-no');
+ showAny = $dropdown.data('show-any');
+ showMenuAbove = $dropdown.data('showMenuAbove');
+ defaultLabel = $dropdown.data('default-label');
+ abilityName = $dropdown.data('ability-name');
+ $selectbox = $dropdown.closest('.selectbox');
+ $block = $selectbox.closest('.block');
+ $form = $dropdown.closest('form, .js-issuable-update');
+ $sidebarCollapsedValue = $block.find('.sidebar-collapsed-icon span');
+ $sidebarLabelTooltip = $block.find('.js-sidebar-labels-tooltip');
+ $value = $block.find('.value');
+ $loading = $block.find('.block-loading').fadeOut();
+ fieldName = $dropdown.data('field-name');
+ useId = $dropdown.is('.js-issuable-form-dropdown, .js-filter-bulk-update, .js-label-sidebar-dropdown');
+ propertyName = useId ? 'id' : 'title';
+ initialSelected = $selectbox
+ .find('input[name="' + $dropdown.data('field-name') + '"]')
+ .map(function () {
+ return this.value;
+ }).get();
+ if (issueUpdateURL != null) {
+ issueURLSplit = issueUpdateURL.split('/');
+ }
+ if (issueUpdateURL) {
+ labelHTMLTemplate = _.template('<% _.each(labels, function(label){ %> <a href="<%- ["",issueURLSplit[1], issueURLSplit[2],""].join("/") %>issues?label_name[]=<%- encodeURIComponent(label.title) %>"> <span class="label has-tooltip color-label" title="<%- label.description %>" style="background-color: <%- label.color %>; color: <%- label.text_color %>;"> <%- label.title %> </span> </a> <% }); %>');
+ labelNoneHTMLTemplate = '<span class="no-value">None</span>';
+ }
- $els = $(els);
+ $sidebarLabelTooltip.tooltip();
- if (!els) {
- $els = $('.js-label-select');
- }
+ if ($dropdown.closest('.dropdown').find('.dropdown-new-label').length) {
+ new gl.CreateLabelDropdown($dropdown.closest('.dropdown').find('.dropdown-new-label'), namespacePath, projectPath);
+ }
- $els.each(function(i, dropdown) {
- var $block, $colorPreview, $dropdown, $form, $loading, $selectbox, $sidebarCollapsedValue, $value, abilityName, defaultLabel, enableLabelCreateButton, issueURLSplit, issueUpdateURL, labelHTMLTemplate, labelNoneHTMLTemplate, labelUrl, namespacePath, projectPath, saveLabelData, selectedLabel, showAny, showNo, $sidebarLabelTooltip, initialSelected, $toggleText, fieldName, useId, propertyName, showMenuAbove, $container, $dropdownContainer;
- $dropdown = $(dropdown);
- $dropdownContainer = $dropdown.closest('.labels-filter');
- $toggleText = $dropdown.find('.dropdown-toggle-text');
- namespacePath = $dropdown.data('namespace-path');
- projectPath = $dropdown.data('project-path');
- labelUrl = $dropdown.data('labels');
- issueUpdateURL = $dropdown.data('issueUpdate');
- selectedLabel = $dropdown.data('selected');
- if ((selectedLabel != null) && !$dropdown.hasClass('js-multiselect')) {
- selectedLabel = selectedLabel.split(',');
- }
- showNo = $dropdown.data('show-no');
- showAny = $dropdown.data('show-any');
- showMenuAbove = $dropdown.data('showMenuAbove');
- defaultLabel = $dropdown.data('default-label');
- abilityName = $dropdown.data('ability-name');
- $selectbox = $dropdown.closest('.selectbox');
- $block = $selectbox.closest('.block');
- $form = $dropdown.closest('form, .js-issuable-update');
- $sidebarCollapsedValue = $block.find('.sidebar-collapsed-icon span');
- $sidebarLabelTooltip = $block.find('.js-sidebar-labels-tooltip');
- $value = $block.find('.value');
- $loading = $block.find('.block-loading').fadeOut();
- fieldName = $dropdown.data('field-name');
- useId = $dropdown.is('.js-issuable-form-dropdown, .js-filter-bulk-update, .js-label-sidebar-dropdown');
- propertyName = useId ? 'id' : 'title';
- initialSelected = $selectbox
- .find('input[name="' + $dropdown.data('field-name') + '"]')
- .map(function () {
- return this.value;
- }).get();
- if (issueUpdateURL != null) {
- issueURLSplit = issueUpdateURL.split('/');
- }
- if (issueUpdateURL) {
- labelHTMLTemplate = _.template('<% _.each(labels, function(label){ %> <a href="<%- ["",issueURLSplit[1], issueURLSplit[2],""].join("/") %>issues?label_name[]=<%- encodeURIComponent(label.title) %>"> <span class="label has-tooltip color-label" title="<%- label.description %>" style="background-color: <%- label.color %>; color: <%- label.text_color %>;"> <%- label.title %> </span> </a> <% }); %>');
- labelNoneHTMLTemplate = '<span class="no-value">None</span>';
- }
+ saveLabelData = function() {
+ var data, selected;
+ selected = $dropdown.closest('.selectbox').find("input[name='" + fieldName + "']").map(function() {
+ return this.value;
+ }).get();
- $sidebarLabelTooltip.tooltip();
+ if (_.isEqual(initialSelected, selected)) return;
+ initialSelected = selected;
- if ($dropdown.closest('.dropdown').find('.dropdown-new-label').length) {
- new gl.CreateLabelDropdown($dropdown.closest('.dropdown').find('.dropdown-new-label'), namespacePath, projectPath);
+ data = {};
+ data[abilityName] = {};
+ data[abilityName].label_ids = selected;
+ if (!selected.length) {
+ data[abilityName].label_ids = [''];
+ }
+ $loading.removeClass('hidden').fadeIn();
+ $dropdown.trigger('loading.gl.dropdown');
+ return $.ajax({
+ type: 'PUT',
+ url: issueUpdateURL,
+ dataType: 'JSON',
+ data: data
+ }).done(function(data) {
+ var labelCount, template, labelTooltipTitle, labelTitles;
+ $loading.fadeOut();
+ $dropdown.trigger('loaded.gl.dropdown');
+ $selectbox.hide();
+ data.issueURLSplit = issueURLSplit;
+ labelCount = 0;
+ if (data.labels.length) {
+ template = labelHTMLTemplate(data);
+ labelCount = data.labels.length;
}
+ else {
+ template = labelNoneHTMLTemplate;
+ }
+ $value.removeAttr('style').html(template);
+ $sidebarCollapsedValue.text(labelCount);
- saveLabelData = function() {
- var data, selected;
- selected = $dropdown.closest('.selectbox').find("input[name='" + fieldName + "']").map(function() {
- return this.value;
- }).get();
-
- if (_.isEqual(initialSelected, selected)) return;
- initialSelected = selected;
+ if (data.labels.length) {
+ labelTitles = data.labels.map(function(label) {
+ return label.title;
+ });
- data = {};
- data[abilityName] = {};
- data[abilityName].label_ids = selected;
- if (!selected.length) {
- data[abilityName].label_ids = [''];
+ if (labelTitles.length > 5) {
+ labelTitles = labelTitles.slice(0, 5);
+ labelTitles.push('and ' + (data.labels.length - 5) + ' more');
}
- $loading.removeClass('hidden').fadeIn();
- $dropdown.trigger('loading.gl.dropdown');
- return $.ajax({
- type: 'PUT',
- url: issueUpdateURL,
- dataType: 'JSON',
- data: data
- }).done(function(data) {
- var labelCount, template, labelTooltipTitle, labelTitles;
- $loading.fadeOut();
- $dropdown.trigger('loaded.gl.dropdown');
- $selectbox.hide();
- data.issueURLSplit = issueURLSplit;
- labelCount = 0;
- if (data.labels.length) {
- template = labelHTMLTemplate(data);
- labelCount = data.labels.length;
- }
- else {
- template = labelNoneHTMLTemplate;
- }
- $value.removeAttr('style').html(template);
- $sidebarCollapsedValue.text(labelCount);
-
- if (data.labels.length) {
- labelTitles = data.labels.map(function(label) {
- return label.title;
- });
-
- if (labelTitles.length > 5) {
- labelTitles = labelTitles.slice(0, 5);
- labelTitles.push('and ' + (data.labels.length - 5) + ' more');
- }
- labelTooltipTitle = labelTitles.join(', ');
- }
- else {
- labelTooltipTitle = '';
- $sidebarLabelTooltip.tooltip('destroy');
- }
+ labelTooltipTitle = labelTitles.join(', ');
+ }
+ else {
+ labelTooltipTitle = '';
+ $sidebarLabelTooltip.tooltip('destroy');
+ }
- $sidebarLabelTooltip
- .attr('title', labelTooltipTitle)
- .tooltip('fixTitle');
+ $sidebarLabelTooltip
+ .attr('title', labelTooltipTitle)
+ .tooltip('fixTitle');
- $('.has-tooltip', $value).tooltip({
- container: 'body'
- });
- return $value.find('a').each(function(i) {
- return setTimeout((function(_this) {
- return function() {
- return gl.animate.animate($(_this), 'pulse');
- };
- })(this), 200 * i);
- });
- });
- };
- $dropdown.glDropdown({
- showMenuAbove: showMenuAbove,
- data: function(term, callback) {
- return $.ajax({
- url: labelUrl
- }).done(function(data) {
- data = _.chain(data).groupBy(function(label) {
- return label.title;
- }).map(function(label) {
- var color;
- color = _.map(label, function(dup) {
- return dup.color;
- });
- return {
- id: label[0].id,
- title: label[0].title,
- color: color,
- duplicate: color.length > 1
- };
- }).value();
- if ($dropdown.hasClass('js-extra-options')) {
- var extraData = [];
- if (showNo) {
- extraData.unshift({
- id: 0,
- title: 'No Label'
- });
- }
- if (showAny) {
- extraData.unshift({
- isAny: true,
- title: 'Any Label'
- });
- }
- if (extraData.length) {
- extraData.push('divider');
- data = extraData.concat(data);
- }
- }
-
- callback(data);
- if (showMenuAbove) {
- $dropdown.data('glDropdown').positionMenuAbove();
- }
+ $('.has-tooltip', $value).tooltip({
+ container: 'body'
+ });
+ return $value.find('a').each(function(i) {
+ return setTimeout((function(_this) {
+ return function() {
+ return gl.animate.animate($(_this), 'pulse');
+ };
+ })(this), 200 * i);
+ });
+ });
+ };
+ $dropdown.glDropdown({
+ showMenuAbove: showMenuAbove,
+ data: function(term, callback) {
+ return $.ajax({
+ url: labelUrl
+ }).done(function(data) {
+ data = _.chain(data).groupBy(function(label) {
+ return label.title;
+ }).map(function(label) {
+ var color;
+ color = _.map(label, function(dup) {
+ return dup.color;
});
- },
- renderRow: function(label, instance) {
- var $a, $li, color, colorEl, indeterminate, removesAll, selectedClass, spacing, i, marked, dropdownName, dropdownValue;
- $li = $('<li>');
- $a = $('<a href="#">');
- selectedClass = [];
- removesAll = label.id <= 0 || (label.id == null);
- if ($dropdown.hasClass('js-filter-bulk-update')) {
- indeterminate = $dropdown.data('indeterminate') || [];
- marked = $dropdown.data('marked') || [];
-
- if (indeterminate.indexOf(label.id) !== -1) {
- selectedClass.push('is-indeterminate');
- }
-
- if (marked.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');
- }
- } else {
- if (this.id(label)) {
- dropdownName = $dropdown.data('fieldName');
- dropdownValue = this.id(label).toString().replace(/'/g, '\\\'');
-
- if ($form.find("input[type='hidden'][name='" + dropdownName + "'][value='" + dropdownValue + "']").length) {
- selectedClass.push('is-active');
- }
- }
-
- if ($dropdown.hasClass('js-multiselect') && removesAll) {
- selectedClass.push('dropdown-clear-active');
- }
- }
- if (label.duplicate) {
- spacing = 100 / label.color.length;
- // Reduce the colors to 4
- label.color = label.color.filter(function(color, i) {
- return i < 4;
+ return {
+ id: label[0].id,
+ title: label[0].title,
+ color: color,
+ duplicate: color.length > 1
+ };
+ }).value();
+ if ($dropdown.hasClass('js-extra-options')) {
+ var extraData = [];
+ if (showNo) {
+ extraData.unshift({
+ id: 0,
+ title: 'No Label'
});
- color = _.map(label.color, function(color, i) {
- var percentFirst, percentSecond;
- percentFirst = Math.floor(spacing * i);
- percentSecond = Math.floor(spacing * (i + 1));
- return color + " " + percentFirst + "%," + color + " " + percentSecond + "% ";
- }).join(',');
- color = "linear-gradient(" + color + ")";
- }
- else {
- if (label.color != null) {
- color = label.color[0];
- }
- }
- if (color) {
- colorEl = "<span class='dropdown-label-box' style='background: " + color + "'></span>";
- }
- 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');
- },
- search: {
- fields: ['title']
- },
- selectable: true,
- filterable: true,
- selected: $dropdown.data('selected') || [],
- toggleLabel: function(selected, el) {
- var isSelected = el !== null ? el.hasClass('is-active') : false;
- var title = selected.title;
- var selectedLabels = this.selected;
-
- if (selected.id === 0) {
- this.selected = [];
- return 'No Label';
- }
- else if (isSelected) {
- this.selected.push(title);
- }
- else {
- var index = this.selected.indexOf(title);
- this.selected.splice(index, 1);
- }
-
- if (selectedLabels.length === 1) {
- return selectedLabels;
- }
- else if (selectedLabels.length) {
- return selectedLabels[0] + " +" + (selectedLabels.length - 1) + " more";
- }
- else {
- return defaultLabel;
- }
- },
- fieldName: $dropdown.data('field-name'),
- id: function(label) {
- if (label.id <= 0) return label.title;
-
- if ($dropdown.hasClass('js-issuable-form-dropdown')) {
- return label.id;
}
-
- if ($dropdown.hasClass("js-filter-submit") && (label.isAny == null)) {
- return label.title;
- }
- else {
- return label.id;
- }
- },
- hidden: function() {
- var isIssueIndex, isMRIndex, page, selectedLabels;
- page = $('body').data('page');
- isIssueIndex = page === 'projects:issues:index';
- isMRIndex = page === 'projects:merge_requests:index';
- $selectbox.hide();
- // display:block overrides the hide-collapse rule
- $value.removeAttr('style');
-
- if ($dropdown.hasClass('js-issuable-form-dropdown')) {
- return;
- }
-
- if ($('html').hasClass('issue-boards-page')) {
- return;
+ if (showAny) {
+ extraData.unshift({
+ isAny: true,
+ title: 'Any Label'
+ });
}
- if ($dropdown.hasClass('js-multiselect')) {
- if ($dropdown.hasClass('js-filter-submit') && (isIssueIndex || isMRIndex)) {
- selectedLabels = $dropdown.closest('form').find("input:hidden[name='" + ($dropdown.data('fieldName')) + "']");
- Issuable.filterResults($dropdown.closest('form'));
- }
- else if ($dropdown.hasClass('js-filter-submit')) {
- $dropdown.closest('form').submit();
- }
- else {
- if (!$dropdown.hasClass('js-filter-bulk-update')) {
- saveLabelData();
- }
- }
+ if (extraData.length) {
+ extraData.push('divider');
+ data = extraData.concat(data);
}
- },
- multiSelect: $dropdown.hasClass('js-multiselect'),
- vue: $dropdown.hasClass('js-issue-board-sidebar'),
- clicked: function(options) {
- const { $el, e, isMarking } = options;
- const label = options.selectedObj;
-
- var isIssueIndex, isMRIndex, page, boardsModel;
- var fadeOutLoader = () => {
- $loading.fadeOut();
- };
+ }
- page = $('body').data('page');
- isIssueIndex = page === 'projects:issues:index';
- isMRIndex = page === 'projects:merge_requests:index';
+ callback(data);
+ if (showMenuAbove) {
+ $dropdown.data('glDropdown').positionMenuAbove();
+ }
+ });
+ },
+ renderRow: function(label, instance) {
+ var $a, $li, color, colorEl, indeterminate, removesAll, selectedClass, spacing, i, marked, dropdownName, dropdownValue;
+ $li = $('<li>');
+ $a = $('<a href="#">');
+ selectedClass = [];
+ removesAll = label.id <= 0 || (label.id == null);
+ if ($dropdown.hasClass('js-filter-bulk-update')) {
+ indeterminate = $dropdown.data('indeterminate') || [];
+ marked = $dropdown.data('marked') || [];
+
+ if (indeterminate.indexOf(label.id) !== -1) {
+ selectedClass.push('is-indeterminate');
+ }
- if ($dropdown.parent().find('.is-active:not(.dropdown-clear-active)').length) {
- $dropdown.parent()
- .find('.dropdown-clear-active')
- .removeClass('is-active');
+ if (marked.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');
+ }
+ } else {
+ if (this.id(label)) {
+ dropdownName = $dropdown.data('fieldName');
+ dropdownValue = this.id(label).toString().replace(/'/g, '\\\'');
- if ($dropdown.hasClass('js-issuable-form-dropdown')) {
- return;
+ if ($form.find("input[type='hidden'][name='" + dropdownName + "'][value='" + dropdownValue + "']").length) {
+ selectedClass.push('is-active');
}
+ }
- if ($dropdown.hasClass('js-filter-bulk-update')) {
- _this.enableBulkLabelDropdown();
- _this.setDropdownData($dropdown, isMarking, label.id);
- return;
- }
+ if ($dropdown.hasClass('js-multiselect') && removesAll) {
+ selectedClass.push('dropdown-clear-active');
+ }
+ }
+ if (label.duplicate) {
+ spacing = 100 / label.color.length;
+ // Reduce the colors to 4
+ label.color = label.color.filter(function(color, i) {
+ return i < 4;
+ });
+ color = _.map(label.color, function(color, i) {
+ var percentFirst, percentSecond;
+ percentFirst = Math.floor(spacing * i);
+ percentSecond = Math.floor(spacing * (i + 1));
+ return color + " " + percentFirst + "%," + color + " " + percentSecond + "% ";
+ }).join(',');
+ color = "linear-gradient(" + color + ")";
+ }
+ else {
+ if (label.color != null) {
+ color = label.color[0];
+ }
+ }
+ if (color) {
+ colorEl = "<span class='dropdown-label-box' style='background: " + color + "'></span>";
+ }
+ 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');
+ },
+ search: {
+ fields: ['title']
+ },
+ selectable: true,
+ filterable: true,
+ selected: $dropdown.data('selected') || [],
+ toggleLabel: function(selected, el) {
+ var isSelected = el !== null ? el.hasClass('is-active') : false;
+ var title = selected.title;
+ var selectedLabels = this.selected;
+
+ if (selected.id === 0) {
+ this.selected = [];
+ return 'No Label';
+ }
+ else if (isSelected) {
+ this.selected.push(title);
+ }
+ else {
+ var index = this.selected.indexOf(title);
+ this.selected.splice(index, 1);
+ }
- if ($dropdown.closest('.add-issues-modal').length) {
- boardsModel = gl.issueBoards.ModalStore.store.filter;
- }
+ if (selectedLabels.length === 1) {
+ return selectedLabels;
+ }
+ else if (selectedLabels.length) {
+ return selectedLabels[0] + " +" + (selectedLabels.length - 1) + " more";
+ }
+ else {
+ return defaultLabel;
+ }
+ },
+ fieldName: $dropdown.data('field-name'),
+ id: function(label) {
+ if (label.id <= 0) return label.title;
- if (boardsModel) {
- if (label.isAny) {
- boardsModel['label_name'] = [];
- } else if ($el.hasClass('is-active')) {
- boardsModel['label_name'].push(label.title);
- }
+ if ($dropdown.hasClass('js-issuable-form-dropdown')) {
+ return label.id;
+ }
- e.preventDefault();
- return;
- }
- else if ($dropdown.hasClass('js-filter-submit') && (isIssueIndex || isMRIndex)) {
- if (!$dropdown.hasClass('js-multiselect')) {
- selectedLabel = label.title;
- return Issuable.filterResults($dropdown.closest('form'));
- }
- }
- else if ($dropdown.hasClass('js-filter-submit')) {
- return $dropdown.closest('form').submit();
- }
- else if ($dropdown.hasClass('js-issue-board-sidebar')) {
- if ($el.hasClass('is-active')) {
- gl.issueBoards.BoardsStore.detail.issue.labels.push(new ListLabel({
- id: label.id,
- title: label.title,
- color: label.color[0],
- textColor: '#fff'
- }));
- }
- else {
- var labels = gl.issueBoards.BoardsStore.detail.issue.labels;
- labels = labels.filter(function (selectedLabel) {
- return selectedLabel.id !== label.id;
- });
- gl.issueBoards.BoardsStore.detail.issue.labels = labels;
- }
-
- $loading.fadeIn();
-
- gl.issueBoards.BoardsStore.detail.issue.update($dropdown.attr('data-issue-update'))
- .then(fadeOutLoader)
- .catch(fadeOutLoader);
- }
- else {
- if ($dropdown.hasClass('js-multiselect')) {
+ if ($dropdown.hasClass("js-filter-submit") && (label.isAny == null)) {
+ return label.title;
+ }
+ else {
+ return label.id;
+ }
+ },
+ hidden: function() {
+ var isIssueIndex, isMRIndex, page, selectedLabels;
+ page = $('body').data('page');
+ isIssueIndex = page === 'projects:issues:index';
+ isMRIndex = page === 'projects:merge_requests:index';
+ $selectbox.hide();
+ // display:block overrides the hide-collapse rule
+ $value.removeAttr('style');
+
+ if ($dropdown.hasClass('js-issuable-form-dropdown')) {
+ return;
+ }
- }
- else {
- return saveLabelData();
- }
+ if ($('html').hasClass('issue-boards-page')) {
+ return;
+ }
+ if ($dropdown.hasClass('js-multiselect')) {
+ if ($dropdown.hasClass('js-filter-submit') && (isIssueIndex || isMRIndex)) {
+ selectedLabels = $dropdown.closest('form').find("input:hidden[name='" + ($dropdown.data('fieldName')) + "']");
+ Issuable.filterResults($dropdown.closest('form'));
+ }
+ else if ($dropdown.hasClass('js-filter-submit')) {
+ $dropdown.closest('form').submit();
+ }
+ else {
+ if (!$dropdown.hasClass('js-filter-bulk-update')) {
+ saveLabelData();
}
- },
- });
-
- // Set dropdown data
- _this.setOriginalDropdownData($dropdownContainer, $dropdown);
- });
- this.bindEvents();
- }
+ }
+ }
+ },
+ multiSelect: $dropdown.hasClass('js-multiselect'),
+ vue: $dropdown.hasClass('js-issue-board-sidebar'),
+ clicked: function(options) {
+ const { $el, e, isMarking } = options;
+ const label = options.selectedObj;
+
+ var isIssueIndex, isMRIndex, page, boardsModel;
+ var fadeOutLoader = () => {
+ $loading.fadeOut();
+ };
- LabelsSelect.prototype.bindEvents = function() {
- return $('body').on('change', '.selected_issue', this.onSelectCheckboxIssue);
- };
+ page = $('body').data('page');
+ isIssueIndex = page === 'projects:issues:index';
+ isMRIndex = page === 'projects:merge_requests:index';
- LabelsSelect.prototype.onSelectCheckboxIssue = function() {
- if ($('.selected_issue:checked').length) {
- return;
- }
- return $('.issues-bulk-update .labels-filter .dropdown-toggle-text').text('Label');
- };
+ if ($dropdown.parent().find('.is-active:not(.dropdown-clear-active)').length) {
+ $dropdown.parent()
+ .find('.dropdown-clear-active')
+ .removeClass('is-active');
+ }
- LabelsSelect.prototype.enableBulkLabelDropdown = function() {
- IssuableBulkUpdateActions.willUpdateLabels = true;
- };
+ if ($dropdown.hasClass('js-issuable-form-dropdown')) {
+ return;
+ }
- LabelsSelect.prototype.setDropdownData = function($dropdown, isMarking, value) {
- var i, markedIds, unmarkedIds, indeterminateIds;
+ if ($dropdown.hasClass('js-filter-bulk-update')) {
+ _this.enableBulkLabelDropdown();
+ _this.setDropdownData($dropdown, isMarking, label.id);
+ return;
+ }
- markedIds = $dropdown.data('marked') || [];
- unmarkedIds = $dropdown.data('unmarked') || [];
- indeterminateIds = $dropdown.data('indeterminate') || [];
+ if ($dropdown.closest('.add-issues-modal').length) {
+ boardsModel = gl.issueBoards.ModalStore.store.filter;
+ }
- if (isMarking) {
- markedIds.push(value);
+ if (boardsModel) {
+ if (label.isAny) {
+ boardsModel['label_name'] = [];
+ } else if ($el.hasClass('is-active')) {
+ boardsModel['label_name'].push(label.title);
+ }
- i = indeterminateIds.indexOf(value);
- if (i > -1) {
- indeterminateIds.splice(i, 1);
+ e.preventDefault();
+ return;
}
-
- i = unmarkedIds.indexOf(value);
- if (i > -1) {
- unmarkedIds.splice(i, 1);
+ else if ($dropdown.hasClass('js-filter-submit') && (isIssueIndex || isMRIndex)) {
+ if (!$dropdown.hasClass('js-multiselect')) {
+ selectedLabel = label.title;
+ return Issuable.filterResults($dropdown.closest('form'));
+ }
}
- } else {
- // If marked item (not common) is unmarked
- i = markedIds.indexOf(value);
- if (i > -1) {
- markedIds.splice(i, 1);
+ else if ($dropdown.hasClass('js-filter-submit')) {
+ return $dropdown.closest('form').submit();
}
+ else if ($dropdown.hasClass('js-issue-board-sidebar')) {
+ if ($el.hasClass('is-active')) {
+ gl.issueBoards.BoardsStore.detail.issue.labels.push(new ListLabel({
+ id: label.id,
+ title: label.title,
+ color: label.color[0],
+ textColor: '#fff'
+ }));
+ }
+ else {
+ var labels = gl.issueBoards.BoardsStore.detail.issue.labels;
+ labels = labels.filter(function (selectedLabel) {
+ return selectedLabel.id !== label.id;
+ });
+ gl.issueBoards.BoardsStore.detail.issue.labels = labels;
+ }
- // If an indeterminate item is being unmarked
- if (IssuableBulkUpdateActions.getOriginalIndeterminateIds().indexOf(value) > -1) {
- unmarkedIds.push(value);
+ $loading.fadeIn();
+
+ gl.issueBoards.BoardsStore.detail.issue.update($dropdown.attr('data-issue-update'))
+ .then(fadeOutLoader)
+ .catch(fadeOutLoader);
}
+ else {
+ if ($dropdown.hasClass('js-multiselect')) {
- // If a marked item is being unmarked
- // (a marked item could also be a label that is present in all selection)
- if (IssuableBulkUpdateActions.getOriginalCommonIds().indexOf(value) > -1) {
- unmarkedIds.push(value);
+ }
+ else {
+ return saveLabelData();
+ }
}
- }
+ },
+ });
+
+ // Set dropdown data
+ _this.setOriginalDropdownData($dropdownContainer, $dropdown);
+ });
+ this.bindEvents();
+}
+
+LabelsSelect.prototype.bindEvents = function() {
+ return $('body').on('change', '.selected_issue', this.onSelectCheckboxIssue);
+};
+
+LabelsSelect.prototype.onSelectCheckboxIssue = function() {
+ if ($('.selected_issue:checked').length) {
+ return;
+ }
+ return $('.issues-bulk-update .labels-filter .dropdown-toggle-text').text('Label');
+};
+
+LabelsSelect.prototype.enableBulkLabelDropdown = function() {
+ IssuableBulkUpdateActions.willUpdateLabels = true;
+};
+
+LabelsSelect.prototype.setDropdownData = function($dropdown, isMarking, value) {
+ var i, markedIds, unmarkedIds, indeterminateIds;
+
+ markedIds = $dropdown.data('marked') || [];
+ unmarkedIds = $dropdown.data('unmarked') || [];
+ indeterminateIds = $dropdown.data('indeterminate') || [];
+
+ if (isMarking) {
+ markedIds.push(value);
+
+ i = indeterminateIds.indexOf(value);
+ if (i > -1) {
+ indeterminateIds.splice(i, 1);
+ }
- $dropdown.data('marked', markedIds);
- $dropdown.data('unmarked', unmarkedIds);
- $dropdown.data('indeterminate', indeterminateIds);
- };
+ i = unmarkedIds.indexOf(value);
+ if (i > -1) {
+ unmarkedIds.splice(i, 1);
+ }
+ } else {
+ // If marked item (not common) is unmarked
+ i = markedIds.indexOf(value);
+ if (i > -1) {
+ markedIds.splice(i, 1);
+ }
- LabelsSelect.prototype.setOriginalDropdownData = function($container, $dropdown) {
- var labels = [];
- $container.find('[name="label_name[]"]').map(function() {
- return labels.push(this.value);
- });
- $dropdown.data('marked', labels);
- };
+ // If an indeterminate item is being unmarked
+ if (IssuableBulkUpdateActions.getOriginalIndeterminateIds().indexOf(value) > -1) {
+ unmarkedIds.push(value);
+ }
- return LabelsSelect;
- })();
-}).call(window);
+ // If a marked item is being unmarked
+ // (a marked item could also be a label that is present in all selection)
+ if (IssuableBulkUpdateActions.getOriginalCommonIds().indexOf(value) > -1) {
+ unmarkedIds.push(value);
+ }
+ }
+
+ $dropdown.data('marked', markedIds);
+ $dropdown.data('unmarked', unmarkedIds);
+ $dropdown.data('indeterminate', indeterminateIds);
+};
+
+LabelsSelect.prototype.setOriginalDropdownData = function($container, $dropdown) {
+ var labels = [];
+ $container.find('[name="label_name[]"]').map(function() {
+ return labels.push(this.value);
+ });
+ $dropdown.data('marked', labels);
+};
+
+window.LabelsSelect = LabelsSelect;
diff --git a/app/assets/javascripts/layout_nav.js b/app/assets/javascripts/layout_nav.js
index 71064ccc539..db6ab6f83b6 100644
--- a/app/assets/javascripts/layout_nav.js
+++ b/app/assets/javascripts/layout_nav.js
@@ -1,58 +1,56 @@
/* eslint-disable func-names, space-before-function-paren, no-var, prefer-arrow-callback, no-unused-vars, one-var, one-var-declaration-per-line, vars-on-top, max-len */
import _ from 'underscore';
-(function() {
- var hideEndFade;
-
- hideEndFade = function($scrollingTabs) {
- return $scrollingTabs.each(function() {
- var $this;
- $this = $(this);
- return $this.siblings('.fade-right').toggleClass('scrolling', $this.width() < $this.prop('scrollWidth'));
- });
- };
-
- $(document).on('init.scrolling-tabs', () => {
- const $scrollingTabs = $('.scrolling-tabs').not('.is-initialized');
- $scrollingTabs.addClass('is-initialized');
-
- hideEndFade($scrollingTabs);
- $(window).off('resize.nav').on('resize.nav', function() {
- return hideEndFade($scrollingTabs);
- });
- $scrollingTabs.off('scroll').on('scroll', function(event) {
- var $this, currentPosition, maxPosition;
- $this = $(this);
- currentPosition = $this.scrollLeft();
- maxPosition = $this.prop('scrollWidth') - $this.outerWidth();
- $this.siblings('.fade-left').toggleClass('scrolling', currentPosition > 0);
- return $this.siblings('.fade-right').toggleClass('scrolling', currentPosition < maxPosition - 1);
- });
-
- $scrollingTabs.each(function () {
- var $this = $(this);
- var scrollingTabWidth = $this.width();
- var $active = $this.find('.active');
- var activeWidth = $active.width();
-
- if ($active.length) {
- var offset = $active.offset().left + activeWidth;
-
- if (offset > scrollingTabWidth - 30) {
- var scrollLeft = scrollingTabWidth / 2;
- scrollLeft = (offset - scrollLeft) - (activeWidth / 2);
- $this.scrollLeft(scrollLeft);
- }
- }
- });
+var hideEndFade;
+
+hideEndFade = function($scrollingTabs) {
+ return $scrollingTabs.each(function() {
+ var $this;
+ $this = $(this);
+ return $this.siblings('.fade-right').toggleClass('scrolling', $this.width() < $this.prop('scrollWidth'));
+ });
+};
+
+$(document).on('init.scrolling-tabs', () => {
+ const $scrollingTabs = $('.scrolling-tabs').not('.is-initialized');
+ $scrollingTabs.addClass('is-initialized');
+
+ hideEndFade($scrollingTabs);
+ $(window).off('resize.nav').on('resize.nav', function() {
+ return hideEndFade($scrollingTabs);
});
+ $scrollingTabs.off('scroll').on('scroll', function(event) {
+ var $this, currentPosition, maxPosition;
+ $this = $(this);
+ currentPosition = $this.scrollLeft();
+ maxPosition = $this.prop('scrollWidth') - $this.outerWidth();
+ $this.siblings('.fade-left').toggleClass('scrolling', currentPosition > 0);
+ return $this.siblings('.fade-right').toggleClass('scrolling', currentPosition < maxPosition - 1);
+ });
+
+ $scrollingTabs.each(function () {
+ var $this = $(this);
+ var scrollingTabWidth = $this.width();
+ var $active = $this.find('.active');
+ var activeWidth = $active.width();
- function applyScrollNavClass() {
- const scrollOpacityHeight = 40;
- $('.navbar-border').css('opacity', Math.min($(window).scrollTop() / scrollOpacityHeight, 1));
- }
+ if ($active.length) {
+ var offset = $active.offset().left + activeWidth;
- $(() => {
- $(window).on('scroll', _.throttle(applyScrollNavClass, 100));
+ if (offset > scrollingTabWidth - 30) {
+ var scrollLeft = scrollingTabWidth / 2;
+ scrollLeft = (offset - scrollLeft) - (activeWidth / 2);
+ $this.scrollLeft(scrollLeft);
+ }
+ }
});
-}).call(window);
+});
+
+function applyScrollNavClass() {
+ const scrollOpacityHeight = 40;
+ $('.navbar-border').css('opacity', Math.min($(window).scrollTop() / scrollOpacityHeight, 1));
+}
+
+$(() => {
+ $(window).on('scroll', _.throttle(applyScrollNavClass, 100));
+});
diff --git a/app/assets/javascripts/lib/utils/animate.js b/app/assets/javascripts/lib/utils/animate.js
index d93c1d0da59..a081e003891 100644
--- a/app/assets/javascripts/lib/utils/animate.js
+++ b/app/assets/javascripts/lib/utils/animate.js
@@ -1,49 +1,45 @@
/* eslint-disable func-names, space-before-function-paren, wrap-iife, no-param-reassign, no-void, prefer-template, no-var, new-cap, prefer-arrow-callback, consistent-return, max-len */
-(function() {
- (function(w) {
- if (w.gl == null) {
- w.gl = {};
+const w = window;
+
+if (w.gl == null) {
+ w.gl = {};
+}
+if (gl.animate == null) {
+ gl.animate = {};
+}
+gl.animate.animate = function($el, animation, options, done) {
+ if ((options != null ? options.cssStart : void 0) != null) {
+ $el.css(options.cssStart);
+ }
+ $el.removeClass(animation + ' animated').addClass(animation + ' animated').one('webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend', function() {
+ $(this).removeClass(animation + ' animated');
+ if (done != null) {
+ done();
}
- if (gl.animate == null) {
- gl.animate = {};
+ if ((options != null ? options.cssEnd : void 0) != null) {
+ $el.css(options.cssEnd);
}
- gl.animate.animate = function($el, animation, options, done) {
- if ((options != null ? options.cssStart : void 0) != null) {
- $el.css(options.cssStart);
- }
- $el.removeClass(animation + ' animated').addClass(animation + ' animated').one('webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend', function() {
- $(this).removeClass(animation + ' animated');
- if (done != null) {
- done();
+ });
+};
+gl.animate.animateEach = function($els, animation, time, options, done) {
+ var dfd;
+ dfd = $.Deferred();
+ if (!$els.length) {
+ dfd.resolve();
+ }
+ $els.each(function(i) {
+ setTimeout(function() {
+ var $this;
+ $this = $(this);
+ return gl.animate.animate($this, animation, options, function() {
+ if (i === $els.length - 1) {
+ dfd.resolve();
+ if (done != null) {
+ return done();
+ }
}
- if ((options != null ? options.cssEnd : void 0) != null) {
- $el.css(options.cssEnd);
- }
- });
- };
- gl.animate.animateEach = function($els, animation, time, options, done) {
- var dfd;
- dfd = $.Deferred();
- if (!$els.length) {
- dfd.resolve();
- }
- $els.each(function(i) {
- setTimeout((function(_this) {
- return function() {
- var $this;
- $this = $(_this);
- return gl.animate.animate($this, animation, options, function() {
- if (i === $els.length - 1) {
- dfd.resolve();
- if (done != null) {
- return done();
- }
- }
- });
- };
- })(this), time * i);
});
- return dfd.promise();
- };
- })(window);
-}).call(window);
+ }.bind(this), time * i);
+ });
+ return dfd.promise();
+};
diff --git a/app/assets/javascripts/lib/utils/common_utils.js b/app/assets/javascripts/lib/utils/common_utils.js
index 122ec138c59..1c8efcb245c 100644
--- a/app/assets/javascripts/lib/utils/common_utils.js
+++ b/app/assets/javascripts/lib/utils/common_utils.js
@@ -1,423 +1,420 @@
/* eslint-disable func-names, space-before-function-paren, wrap-iife, no-var, no-unused-expressions, no-param-reassign, no-else-return, quotes, object-shorthand, comma-dangle, camelcase, one-var, vars-on-top, one-var-declaration-per-line, no-return-assign, consistent-return, max-len, prefer-template */
-(function() {
- (function(w) {
- var base;
- const faviconEl = document.getElementById('favicon');
- const originalFavicon = faviconEl ? faviconEl.getAttribute('href') : null;
- w.gl || (w.gl = {});
- (base = w.gl).utils || (base.utils = {});
- w.gl.utils.isInGroupsPage = function() {
- return gl.utils.getPagePath() === 'groups';
- };
- w.gl.utils.isInProjectPage = function() {
- return gl.utils.getPagePath() === 'projects';
- };
- w.gl.utils.getProjectSlug = function() {
- if (this.isInProjectPage()) {
- return $('body').data('project');
- } else {
- return null;
- }
- };
- w.gl.utils.getGroupSlug = function() {
- if (this.isInGroupsPage()) {
- return $('body').data('group');
- } else {
- return null;
- }
- };
-
- w.gl.utils.ajaxGet = function(url) {
- return $.ajax({
- type: "GET",
- url: url,
- dataType: "script"
- });
- };
-
- w.gl.utils.ajaxPost = function(url, data) {
- return $.ajax({
- type: 'POST',
- url: url,
- data: data,
- });
- };
-
- w.gl.utils.extractLast = function(term) {
- return this.split(term).pop();
- };
-
- w.gl.utils.rstrip = function rstrip(val) {
- if (val) {
- return val.replace(/\s+$/, '');
+var base;
+const w = window;
+const faviconEl = document.getElementById('favicon');
+const originalFavicon = faviconEl ? faviconEl.getAttribute('href') : null;
+w.gl || (w.gl = {});
+(base = w.gl).utils || (base.utils = {});
+w.gl.utils.isInGroupsPage = function() {
+ return gl.utils.getPagePath() === 'groups';
+};
+w.gl.utils.isInProjectPage = function() {
+ return gl.utils.getPagePath() === 'projects';
+};
+w.gl.utils.getProjectSlug = function() {
+ if (this.isInProjectPage()) {
+ return $('body').data('project');
+ } else {
+ return null;
+ }
+};
+w.gl.utils.getGroupSlug = function() {
+ if (this.isInGroupsPage()) {
+ return $('body').data('group');
+ } else {
+ return null;
+ }
+};
+
+w.gl.utils.ajaxGet = function(url) {
+ return $.ajax({
+ type: "GET",
+ url: url,
+ dataType: "script"
+ });
+};
+
+w.gl.utils.ajaxPost = function(url, data) {
+ return $.ajax({
+ type: 'POST',
+ url: url,
+ data: data,
+ });
+};
+
+w.gl.utils.extractLast = function(term) {
+ return this.split(term).pop();
+};
+
+w.gl.utils.rstrip = function rstrip(val) {
+ if (val) {
+ return val.replace(/\s+$/, '');
+ } else {
+ return val;
+ }
+};
+
+gl.utils.updateTooltipTitle = function($tooltipEl, newTitle) {
+ return $tooltipEl.attr('title', newTitle).tooltip('fixTitle');
+};
+
+w.gl.utils.disableButtonIfEmptyField = function(field_selector, button_selector, event_name) {
+ event_name = event_name || 'input';
+ var closest_submit, field, that;
+ that = this;
+ field = $(field_selector);
+ closest_submit = field.closest('form').find(button_selector);
+ if (this.rstrip(field.val()) === "") {
+ closest_submit.disable();
+ }
+ return field.on(event_name, function() {
+ if (that.rstrip($(this).val()) === "") {
+ return closest_submit.disable();
+ } else {
+ return closest_submit.enable();
+ }
+ });
+};
+
+// automatically adjust scroll position for hash urls taking the height of the navbar into account
+// https://github.com/twitter/bootstrap/issues/1768
+w.gl.utils.handleLocationHash = function() {
+ var hash = w.gl.utils.getLocationHash();
+ if (!hash) return;
+
+ // This is required to handle non-unicode characters in hash
+ hash = decodeURIComponent(hash);
+
+ var fixedTabs = document.querySelector('.js-tabs-affix');
+ var fixedNav = document.querySelector('.navbar-gitlab');
+
+ var adjustment = 0;
+ if (fixedNav) adjustment -= fixedNav.offsetHeight;
+
+ // scroll to user-generated markdown anchor if we cannot find a match
+ if (document.getElementById(hash) === null) {
+ var target = document.getElementById('user-content-' + hash);
+ if (target && target.scrollIntoView) {
+ target.scrollIntoView(true);
+ window.scrollBy(0, adjustment);
+ }
+ } else {
+ // only adjust for fixedTabs when not targeting user-generated content
+ if (fixedTabs) {
+ adjustment -= fixedTabs.offsetHeight;
+ }
+ window.scrollBy(0, adjustment);
+ }
+};
+
+// Check if element scrolled into viewport from above or below
+// Courtesy http://stackoverflow.com/a/7557433/414749
+w.gl.utils.isInViewport = function(el) {
+ var rect = el.getBoundingClientRect();
+
+ return (
+ rect.top >= 0 &&
+ rect.left >= 0 &&
+ rect.bottom <= window.innerHeight &&
+ rect.right <= window.innerWidth
+ );
+};
+
+gl.utils.getPagePath = function(index) {
+ index = index || 0;
+ return $('body').data('page').split(':')[index];
+};
+
+gl.utils.parseUrl = function (url) {
+ var parser = document.createElement('a');
+ parser.href = url;
+ return parser;
+};
+
+gl.utils.parseUrlPathname = function (url) {
+ var parsedUrl = gl.utils.parseUrl(url);
+ // parsedUrl.pathname will return an absolute path for Firefox and a relative path for IE11
+ // We have to make sure we always have an absolute path.
+ return parsedUrl.pathname.charAt(0) === '/' ? parsedUrl.pathname : '/' + parsedUrl.pathname;
+};
+
+gl.utils.getUrlParamsArray = function () {
+ // We can trust that each param has one & since values containing & will be encoded
+ // Remove the first character of search as it is always ?
+ return window.location.search.slice(1).split('&').map((param) => {
+ const split = param.split('=');
+ return [decodeURI(split[0]), split[1]].join('=');
+ });
+};
+
+gl.utils.isMetaKey = function(e) {
+ return e.metaKey || e.ctrlKey || e.altKey || e.shiftKey;
+};
+
+gl.utils.isMetaClick = function(e) {
+ // Identify following special clicks
+ // 1) Cmd + Click on Mac (e.metaKey)
+ // 2) Ctrl + Click on PC (e.ctrlKey)
+ // 3) Middle-click or Mouse Wheel Click (e.which is 2)
+ return e.metaKey || e.ctrlKey || e.which === 2;
+};
+
+gl.utils.scrollToElement = function($el) {
+ var top = $el.offset().top;
+ gl.mrTabsHeight = gl.mrTabsHeight || $('.merge-request-tabs').height();
+
+ return $('body, html').animate({
+ scrollTop: top - (gl.mrTabsHeight)
+ }, 200);
+};
+
+/**
+ this will take in the `name` of the param you want to parse in the url
+ if the name does not exist this function will return `null`
+ otherwise it will return the value of the param key provided
+*/
+w.gl.utils.getParameterByName = (name, parseUrl) => {
+ const url = parseUrl || window.location.href;
+ name = name.replace(/[[\]]/g, '\\$&');
+ const regex = new RegExp(`[?&]${name}(=([^&#]*)|&|#|$)`);
+ const results = regex.exec(url);
+ if (!results) return null;
+ if (!results[2]) return '';
+ return decodeURIComponent(results[2].replace(/\+/g, ' '));
+};
+
+w.gl.utils.getSelectedFragment = () => {
+ const selection = window.getSelection();
+ if (selection.rangeCount === 0) return null;
+ const documentFragment = document.createDocumentFragment();
+ for (let i = 0; i < selection.rangeCount; i += 1) {
+ documentFragment.appendChild(selection.getRangeAt(i).cloneContents());
+ }
+ if (documentFragment.textContent.length === 0) return null;
+
+ return documentFragment;
+};
+
+w.gl.utils.insertText = (target, text) => {
+ // Firefox doesn't support `document.execCommand('insertText', false, text)` on textareas
+
+ const selectionStart = target.selectionStart;
+ const selectionEnd = target.selectionEnd;
+ const value = target.value;
+
+ const textBefore = value.substring(0, selectionStart);
+ const textAfter = value.substring(selectionEnd, value.length);
+
+ const insertedText = text instanceof Function ? text(textBefore, textAfter) : text;
+ const newText = textBefore + insertedText + textAfter;
+
+ target.value = newText;
+ target.selectionStart = target.selectionEnd = selectionStart + insertedText.length;
+
+ // Trigger autosave
+ $(target).trigger('input');
+
+ // Trigger autosize
+ var event = document.createEvent('Event');
+ event.initEvent('autosize:update', true, false);
+ target.dispatchEvent(event);
+};
+
+w.gl.utils.nodeMatchesSelector = (node, selector) => {
+ const matches = Element.prototype.matches ||
+ Element.prototype.matchesSelector ||
+ Element.prototype.mozMatchesSelector ||
+ Element.prototype.msMatchesSelector ||
+ Element.prototype.oMatchesSelector ||
+ Element.prototype.webkitMatchesSelector;
+
+ if (matches) {
+ return matches.call(node, selector);
+ }
+
+ // IE11 doesn't support `node.matches(selector)`
+
+ let parentNode = node.parentNode;
+ if (!parentNode) {
+ parentNode = document.createElement('div');
+ node = node.cloneNode(true);
+ parentNode.appendChild(node);
+ }
+
+ const matchingNodes = parentNode.querySelectorAll(selector);
+ return Array.prototype.indexOf.call(matchingNodes, node) !== -1;
+};
+
+/**
+ this will take in the headers from an API response and normalize them
+ this way we don't run into production issues when nginx gives us lowercased header keys
+*/
+w.gl.utils.normalizeHeaders = (headers) => {
+ const upperCaseHeaders = {};
+
+ Object.keys(headers).forEach((e) => {
+ upperCaseHeaders[e.toUpperCase()] = headers[e];
+ });
+
+ return upperCaseHeaders;
+};
+
+/**
+ this will take in the getAllResponseHeaders result and normalize them
+ this way we don't run into production issues when nginx gives us lowercased header keys
+*/
+w.gl.utils.normalizeCRLFHeaders = (headers) => {
+ const headersObject = {};
+ const headersArray = headers.split('\n');
+
+ headersArray.forEach((header) => {
+ const keyValue = header.split(': ');
+ headersObject[keyValue[0]] = keyValue[1];
+ });
+
+ return w.gl.utils.normalizeHeaders(headersObject);
+};
+
+/**
+ * Parses pagination object string values into numbers.
+ *
+ * @param {Object} paginationInformation
+ * @returns {Object}
+ */
+w.gl.utils.parseIntPagination = paginationInformation => ({
+ perPage: parseInt(paginationInformation['X-PER-PAGE'], 10),
+ page: parseInt(paginationInformation['X-PAGE'], 10),
+ total: parseInt(paginationInformation['X-TOTAL'], 10),
+ totalPages: parseInt(paginationInformation['X-TOTAL-PAGES'], 10),
+ nextPage: parseInt(paginationInformation['X-NEXT-PAGE'], 10),
+ previousPage: parseInt(paginationInformation['X-PREV-PAGE'], 10),
+});
+
+/**
+ * Updates the search parameter of a URL given the parameter and value provided.
+ *
+ * If no search params are present we'll add it.
+ * If param for page is already present, we'll update it
+ * If there are params but not for the given one, we'll add it at the end.
+ * Returns the new search parameters.
+ *
+ * @param {String} param
+ * @param {Number|String|Undefined|Null} value
+ * @return {String}
+ */
+w.gl.utils.setParamInURL = (param, value) => {
+ let search;
+ const locationSearch = window.location.search;
+
+ if (locationSearch.length) {
+ const parameters = locationSearch.substring(1, locationSearch.length)
+ .split('&')
+ .reduce((acc, element) => {
+ const val = element.split('=');
+ acc[val[0]] = decodeURIComponent(val[1]);
+ return acc;
+ }, {});
+
+ parameters[param] = value;
+
+ const toString = Object.keys(parameters)
+ .map(val => `${val}=${encodeURIComponent(parameters[val])}`)
+ .join('&');
+
+ search = `?${toString}`;
+ } else {
+ search = `?${param}=${value}`;
+ }
+
+ return search;
+};
+
+/**
+ * Converts permission provided as strings to booleans.
+ *
+ * @param {String} string
+ * @returns {Boolean}
+ */
+w.gl.utils.convertPermissionToBoolean = permission => permission === 'true';
+
+/**
+ * Back Off exponential algorithm
+ * backOff :: (Function<next, stop>, Number) -> Promise<Any, Error>
+ *
+ * @param {Function<next, stop>} fn function to be called
+ * @param {Number} timeout
+ * @return {Promise<Any, Error>}
+ * @example
+ * ```
+ * backOff(function (next, stop) {
+ * // Let's perform this function repeatedly for 60s or for the timeout provided.
+ *
+ * ourFunction()
+ * .then(function (result) {
+ * // continue if result is not what we need
+ * next();
+ *
+ * // when result is what we need let's stop with the repetions and jump out of the cycle
+ * stop(result);
+ * })
+ * .catch(function (error) {
+ * // if there is an error, we need to stop this with an error.
+ * stop(error);
+ * })
+ * }, 60000)
+ * .then(function (result) {})
+ * .catch(function (error) {
+ * // deal with errors passed to stop()
+ * })
+ * ```
+ */
+w.gl.utils.backOff = (fn, timeout = 60000) => {
+ const maxInterval = 32000;
+ let nextInterval = 2000;
+
+ const startTime = Date.now();
+
+ return new Promise((resolve, reject) => {
+ const stop = arg => ((arg instanceof Error) ? reject(arg) : resolve(arg));
+
+ const next = () => {
+ if (Date.now() - startTime < timeout) {
+ setTimeout(fn.bind(null, next, stop), nextInterval);
+ nextInterval = Math.min(nextInterval + nextInterval, maxInterval);
} else {
- return val;
+ reject(new Error('BACKOFF_TIMEOUT'));
}
};
- gl.utils.updateTooltipTitle = function($tooltipEl, newTitle) {
- return $tooltipEl.attr('title', newTitle).tooltip('fixTitle');
- };
-
- w.gl.utils.disableButtonIfEmptyField = function(field_selector, button_selector, event_name) {
- event_name = event_name || 'input';
- var closest_submit, field, that;
- that = this;
- field = $(field_selector);
- closest_submit = field.closest('form').find(button_selector);
- if (this.rstrip(field.val()) === "") {
- closest_submit.disable();
- }
- return field.on(event_name, function() {
- if (that.rstrip($(this).val()) === "") {
- return closest_submit.disable();
- } else {
- return closest_submit.enable();
- }
- });
- };
-
- // automatically adjust scroll position for hash urls taking the height of the navbar into account
- // https://github.com/twitter/bootstrap/issues/1768
- w.gl.utils.handleLocationHash = function() {
- var hash = w.gl.utils.getLocationHash();
- if (!hash) return;
-
- // This is required to handle non-unicode characters in hash
- hash = decodeURIComponent(hash);
-
- var fixedTabs = document.querySelector('.js-tabs-affix');
- var fixedNav = document.querySelector('.navbar-gitlab');
-
- var adjustment = 0;
- if (fixedNav) adjustment -= fixedNav.offsetHeight;
-
- // scroll to user-generated markdown anchor if we cannot find a match
- if (document.getElementById(hash) === null) {
- var target = document.getElementById('user-content-' + hash);
- if (target && target.scrollIntoView) {
- target.scrollIntoView(true);
- window.scrollBy(0, adjustment);
- }
+ fn(next, stop);
+ });
+};
+
+w.gl.utils.setFavicon = (faviconPath) => {
+ if (faviconEl && faviconPath) {
+ faviconEl.setAttribute('href', faviconPath);
+ }
+};
+
+w.gl.utils.resetFavicon = () => {
+ if (faviconEl) {
+ faviconEl.setAttribute('href', originalFavicon);
+ }
+};
+
+w.gl.utils.setCiStatusFavicon = (pageUrl) => {
+ $.ajax({
+ url: pageUrl,
+ dataType: 'json',
+ success: function(data) {
+ if (data && data.favicon) {
+ gl.utils.setFavicon(data.favicon);
} else {
- // only adjust for fixedTabs when not targeting user-generated content
- if (fixedTabs) {
- adjustment -= fixedTabs.offsetHeight;
- }
- window.scrollBy(0, adjustment);
+ gl.utils.resetFavicon();
}
- };
-
- // Check if element scrolled into viewport from above or below
- // Courtesy http://stackoverflow.com/a/7557433/414749
- w.gl.utils.isInViewport = function(el) {
- var rect = el.getBoundingClientRect();
-
- return (
- rect.top >= 0 &&
- rect.left >= 0 &&
- rect.bottom <= window.innerHeight &&
- rect.right <= window.innerWidth
- );
- };
-
- gl.utils.getPagePath = function(index) {
- index = index || 0;
- return $('body').data('page').split(':')[index];
- };
-
- gl.utils.parseUrl = function (url) {
- var parser = document.createElement('a');
- parser.href = url;
- return parser;
- };
-
- gl.utils.parseUrlPathname = function (url) {
- var parsedUrl = gl.utils.parseUrl(url);
- // parsedUrl.pathname will return an absolute path for Firefox and a relative path for IE11
- // We have to make sure we always have an absolute path.
- return parsedUrl.pathname.charAt(0) === '/' ? parsedUrl.pathname : '/' + parsedUrl.pathname;
- };
-
- gl.utils.getUrlParamsArray = function () {
- // We can trust that each param has one & since values containing & will be encoded
- // Remove the first character of search as it is always ?
- return window.location.search.slice(1).split('&').map((param) => {
- const split = param.split('=');
- return [decodeURI(split[0]), split[1]].join('=');
- });
- };
-
- gl.utils.isMetaKey = function(e) {
- return e.metaKey || e.ctrlKey || e.altKey || e.shiftKey;
- };
-
- gl.utils.isMetaClick = function(e) {
- // Identify following special clicks
- // 1) Cmd + Click on Mac (e.metaKey)
- // 2) Ctrl + Click on PC (e.ctrlKey)
- // 3) Middle-click or Mouse Wheel Click (e.which is 2)
- return e.metaKey || e.ctrlKey || e.which === 2;
- };
-
- gl.utils.scrollToElement = function($el) {
- var top = $el.offset().top;
- gl.mrTabsHeight = gl.mrTabsHeight || $('.merge-request-tabs').height();
-
- return $('body, html').animate({
- scrollTop: top - (gl.mrTabsHeight)
- }, 200);
- };
-
- /**
- this will take in the `name` of the param you want to parse in the url
- if the name does not exist this function will return `null`
- otherwise it will return the value of the param key provided
- */
- w.gl.utils.getParameterByName = (name, parseUrl) => {
- const url = parseUrl || window.location.href;
- name = name.replace(/[[\]]/g, '\\$&');
- const regex = new RegExp(`[?&]${name}(=([^&#]*)|&|#|$)`);
- const results = regex.exec(url);
- if (!results) return null;
- if (!results[2]) return '';
- return decodeURIComponent(results[2].replace(/\+/g, ' '));
- };
-
- w.gl.utils.getSelectedFragment = () => {
- const selection = window.getSelection();
- if (selection.rangeCount === 0) return null;
- const documentFragment = document.createDocumentFragment();
- for (let i = 0; i < selection.rangeCount; i += 1) {
- documentFragment.appendChild(selection.getRangeAt(i).cloneContents());
- }
- if (documentFragment.textContent.length === 0) return null;
-
- return documentFragment;
- };
-
- w.gl.utils.insertText = (target, text) => {
- // Firefox doesn't support `document.execCommand('insertText', false, text)` on textareas
-
- const selectionStart = target.selectionStart;
- const selectionEnd = target.selectionEnd;
- const value = target.value;
-
- const textBefore = value.substring(0, selectionStart);
- const textAfter = value.substring(selectionEnd, value.length);
-
- const insertedText = text instanceof Function ? text(textBefore, textAfter) : text;
- const newText = textBefore + insertedText + textAfter;
-
- target.value = newText;
- target.selectionStart = target.selectionEnd = selectionStart + insertedText.length;
-
- // Trigger autosave
- $(target).trigger('input');
-
- // Trigger autosize
- var event = document.createEvent('Event');
- event.initEvent('autosize:update', true, false);
- target.dispatchEvent(event);
- };
-
- w.gl.utils.nodeMatchesSelector = (node, selector) => {
- const matches = Element.prototype.matches ||
- Element.prototype.matchesSelector ||
- Element.prototype.mozMatchesSelector ||
- Element.prototype.msMatchesSelector ||
- Element.prototype.oMatchesSelector ||
- Element.prototype.webkitMatchesSelector;
-
- if (matches) {
- return matches.call(node, selector);
- }
-
- // IE11 doesn't support `node.matches(selector)`
-
- let parentNode = node.parentNode;
- if (!parentNode) {
- parentNode = document.createElement('div');
- node = node.cloneNode(true);
- parentNode.appendChild(node);
- }
-
- const matchingNodes = parentNode.querySelectorAll(selector);
- return Array.prototype.indexOf.call(matchingNodes, node) !== -1;
- };
-
- /**
- this will take in the headers from an API response and normalize them
- this way we don't run into production issues when nginx gives us lowercased header keys
- */
- w.gl.utils.normalizeHeaders = (headers) => {
- const upperCaseHeaders = {};
-
- Object.keys(headers).forEach((e) => {
- upperCaseHeaders[e.toUpperCase()] = headers[e];
- });
-
- return upperCaseHeaders;
- };
-
- /**
- this will take in the getAllResponseHeaders result and normalize them
- this way we don't run into production issues when nginx gives us lowercased header keys
- */
- w.gl.utils.normalizeCRLFHeaders = (headers) => {
- const headersObject = {};
- const headersArray = headers.split('\n');
-
- headersArray.forEach((header) => {
- const keyValue = header.split(': ');
- headersObject[keyValue[0]] = keyValue[1];
- });
-
- return w.gl.utils.normalizeHeaders(headersObject);
- };
-
- /**
- * Parses pagination object string values into numbers.
- *
- * @param {Object} paginationInformation
- * @returns {Object}
- */
- w.gl.utils.parseIntPagination = paginationInformation => ({
- perPage: parseInt(paginationInformation['X-PER-PAGE'], 10),
- page: parseInt(paginationInformation['X-PAGE'], 10),
- total: parseInt(paginationInformation['X-TOTAL'], 10),
- totalPages: parseInt(paginationInformation['X-TOTAL-PAGES'], 10),
- nextPage: parseInt(paginationInformation['X-NEXT-PAGE'], 10),
- previousPage: parseInt(paginationInformation['X-PREV-PAGE'], 10),
- });
-
- /**
- * Updates the search parameter of a URL given the parameter and value provided.
- *
- * If no search params are present we'll add it.
- * If param for page is already present, we'll update it
- * If there are params but not for the given one, we'll add it at the end.
- * Returns the new search parameters.
- *
- * @param {String} param
- * @param {Number|String|Undefined|Null} value
- * @return {String}
- */
- w.gl.utils.setParamInURL = (param, value) => {
- let search;
- const locationSearch = window.location.search;
-
- if (locationSearch.length) {
- const parameters = locationSearch.substring(1, locationSearch.length)
- .split('&')
- .reduce((acc, element) => {
- const val = element.split('=');
- acc[val[0]] = decodeURIComponent(val[1]);
- return acc;
- }, {});
-
- parameters[param] = value;
-
- const toString = Object.keys(parameters)
- .map(val => `${val}=${encodeURIComponent(parameters[val])}`)
- .join('&');
-
- search = `?${toString}`;
- } else {
- search = `?${param}=${value}`;
- }
-
- return search;
- };
-
- /**
- * Converts permission provided as strings to booleans.
- *
- * @param {String} string
- * @returns {Boolean}
- */
- w.gl.utils.convertPermissionToBoolean = permission => permission === 'true';
-
- /**
- * Back Off exponential algorithm
- * backOff :: (Function<next, stop>, Number) -> Promise<Any, Error>
- *
- * @param {Function<next, stop>} fn function to be called
- * @param {Number} timeout
- * @return {Promise<Any, Error>}
- * @example
- * ```
- * backOff(function (next, stop) {
- * // Let's perform this function repeatedly for 60s or for the timeout provided.
- *
- * ourFunction()
- * .then(function (result) {
- * // continue if result is not what we need
- * next();
- *
- * // when result is what we need let's stop with the repetions and jump out of the cycle
- * stop(result);
- * })
- * .catch(function (error) {
- * // if there is an error, we need to stop this with an error.
- * stop(error);
- * })
- * }, 60000)
- * .then(function (result) {})
- * .catch(function (error) {
- * // deal with errors passed to stop()
- * })
- * ```
- */
- w.gl.utils.backOff = (fn, timeout = 60000) => {
- const maxInterval = 32000;
- let nextInterval = 2000;
-
- const startTime = Date.now();
-
- return new Promise((resolve, reject) => {
- const stop = arg => ((arg instanceof Error) ? reject(arg) : resolve(arg));
-
- const next = () => {
- if (Date.now() - startTime < timeout) {
- setTimeout(fn.bind(null, next, stop), nextInterval);
- nextInterval = Math.min(nextInterval + nextInterval, maxInterval);
- } else {
- reject(new Error('BACKOFF_TIMEOUT'));
- }
- };
-
- fn(next, stop);
- });
- };
-
- w.gl.utils.setFavicon = (faviconPath) => {
- if (faviconEl && faviconPath) {
- faviconEl.setAttribute('href', faviconPath);
- }
- };
-
- w.gl.utils.resetFavicon = () => {
- if (faviconEl) {
- faviconEl.setAttribute('href', originalFavicon);
- }
- };
-
- w.gl.utils.setCiStatusFavicon = (pageUrl) => {
- $.ajax({
- url: pageUrl,
- dataType: 'json',
- success: function(data) {
- if (data && data.favicon) {
- gl.utils.setFavicon(data.favicon);
- } else {
- gl.utils.resetFavicon();
- }
- },
- error: function() {
- gl.utils.resetFavicon();
- }
- });
- };
- })(window);
-}).call(window);
+ },
+ error: function() {
+ gl.utils.resetFavicon();
+ }
+ });
+};
diff --git a/app/assets/javascripts/lib/utils/datetime_utility.js b/app/assets/javascripts/lib/utils/datetime_utility.js
index 1d1763c3963..ee7b6417c5b 100644
--- a/app/assets/javascripts/lib/utils/datetime_utility.js
+++ b/app/assets/javascripts/lib/utils/datetime_utility.js
@@ -1,4 +1,4 @@
-/* eslint-disable func-names, space-before-function-paren, wrap-iife, no-var, no-param-reassign, no-cond-assign, comma-dangle, no-unused-expressions, prefer-template, max-len */
+/* eslint-disable func-names, space-before-function-paren, wrap-iife, no-var, no-param-reassign, no-cond-assign, comma-dangle, no-unused-expressions, prefer-template, max-len, vars-on-top */
import timeago from 'timeago.js';
import dateFormat from 'vendor/date.format';
@@ -11,123 +11,120 @@ import {
window.timeago = timeago;
window.dateFormat = dateFormat;
-(function() {
- (function(w) {
- var base;
- var timeagoInstance;
+var w = window;
+var base;
+var timeagoInstance;
- if (w.gl == null) {
- w.gl = {};
- }
- if ((base = w.gl).utils == null) {
- base.utils = {};
- }
- w.gl.utils.days = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];
-
- w.gl.utils.formatDate = function(datetime) {
- return dateFormat(datetime, 'mmm d, yyyy h:MMtt Z');
- };
+if (w.gl == null) {
+ w.gl = {};
+}
+if ((base = w.gl).utils == null) {
+ base.utils = {};
+}
+w.gl.utils.days = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];
- w.gl.utils.getDayName = function(date) {
- return this.days[date.getDay()];
- };
+w.gl.utils.formatDate = function(datetime) {
+ return dateFormat(datetime, 'mmm d, yyyy h:MMtt Z');
+};
- w.gl.utils.localTimeAgo = function($timeagoEls, setTimeago = true) {
- $timeagoEls.each((i, el) => {
- el.setAttribute('title', el.getAttribute('title'));
+w.gl.utils.getDayName = function(date) {
+ return this.days[date.getDay()];
+};
- if (setTimeago) {
- // Recreate with custom template
- $(el).tooltip({
- template: '<div class="tooltip local-timeago" role="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>'
- });
- }
+w.gl.utils.localTimeAgo = function($timeagoEls, setTimeago = true) {
+ $timeagoEls.each((i, el) => {
+ el.setAttribute('title', el.getAttribute('title'));
- el.classList.add('js-timeago-render');
+ if (setTimeago) {
+ // Recreate with custom template
+ $(el).tooltip({
+ template: '<div class="tooltip local-timeago" role="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>'
});
+ }
- gl.utils.renderTimeago($timeagoEls);
+ el.classList.add('js-timeago-render');
+ });
+
+ gl.utils.renderTimeago($timeagoEls);
+};
+
+w.gl.utils.getTimeago = function() {
+ var locale;
+
+ if (!timeagoInstance) {
+ const localeRemaining = function(number, index) {
+ return [
+ [s__('Timeago|less than a minute ago'), s__('Timeago|a while')],
+ [s__('Timeago|less than a minute ago'), s__('Timeago|%s seconds remaining')],
+ [s__('Timeago|about a minute ago'), s__('Timeago|1 minute remaining')],
+ [s__('Timeago|%s minutes ago'), s__('Timeago|%s minutes remaining')],
+ [s__('Timeago|about an hour ago'), s__('Timeago|1 hour remaining')],
+ [s__('Timeago|about %s hours ago'), s__('Timeago|%s hours remaining')],
+ [s__('Timeago|a day ago'), s__('Timeago|1 day remaining')],
+ [s__('Timeago|%s days ago'), s__('Timeago|%s days remaining')],
+ [s__('Timeago|a week ago'), s__('Timeago|1 week remaining')],
+ [s__('Timeago|%s weeks ago'), s__('Timeago|%s weeks remaining')],
+ [s__('Timeago|a month ago'), s__('Timeago|1 month remaining')],
+ [s__('Timeago|%s months ago'), s__('Timeago|%s months remaining')],
+ [s__('Timeago|a year ago'), s__('Timeago|1 year remaining')],
+ [s__('Timeago|%s years ago'), s__('Timeago|%s years remaining')]
+ ][index];
};
-
- w.gl.utils.getTimeago = function() {
- var locale;
-
- if (!timeagoInstance) {
- const localeRemaining = function(number, index) {
- return [
- [s__('Timeago|less than a minute ago'), s__('Timeago|a while')],
- [s__('Timeago|less than a minute ago'), s__('Timeago|%s seconds remaining')],
- [s__('Timeago|about a minute ago'), s__('Timeago|1 minute remaining')],
- [s__('Timeago|%s minutes ago'), s__('Timeago|%s minutes remaining')],
- [s__('Timeago|about an hour ago'), s__('Timeago|1 hour remaining')],
- [s__('Timeago|about %s hours ago'), s__('Timeago|%s hours remaining')],
- [s__('Timeago|a day ago'), s__('Timeago|1 day remaining')],
- [s__('Timeago|%s days ago'), s__('Timeago|%s days remaining')],
- [s__('Timeago|a week ago'), s__('Timeago|1 week remaining')],
- [s__('Timeago|%s weeks ago'), s__('Timeago|%s weeks remaining')],
- [s__('Timeago|a month ago'), s__('Timeago|1 month remaining')],
- [s__('Timeago|%s months ago'), s__('Timeago|%s months remaining')],
- [s__('Timeago|a year ago'), s__('Timeago|1 year remaining')],
- [s__('Timeago|%s years ago'), s__('Timeago|%s years remaining')]
- ][index];
- };
- locale = function(number, index) {
- return [
- [s__('Timeago|less than a minute ago'), s__('Timeago|a while')],
- [s__('Timeago|less than a minute ago'), s__('Timeago|in %s seconds')],
- [s__('Timeago|about a minute ago'), s__('Timeago|in 1 minute')],
- [s__('Timeago|%s minutes ago'), s__('Timeago|in %s minutes')],
- [s__('Timeago|about an hour ago'), s__('Timeago|in 1 hour')],
- [s__('Timeago|about %s hours ago'), s__('Timeago|in %s hours')],
- [s__('Timeago|a day ago'), s__('Timeago|in 1 day')],
- [s__('Timeago|%s days ago'), s__('Timeago|in %s days')],
- [s__('Timeago|a week ago'), s__('Timeago|in 1 week')],
- [s__('Timeago|%s weeks ago'), s__('Timeago|in %s weeks')],
- [s__('Timeago|a month ago'), s__('Timeago|in 1 month')],
- [s__('Timeago|%s months ago'), s__('Timeago|in %s months')],
- [s__('Timeago|a year ago'), s__('Timeago|in 1 year')],
- [s__('Timeago|%s years ago'), s__('Timeago|in %s years')]
- ][index];
- };
-
- timeago.register(lang, locale);
- timeago.register(`${lang}-remaining`, localeRemaining);
- timeagoInstance = timeago();
- }
-
- return timeagoInstance;
+ locale = function(number, index) {
+ return [
+ [s__('Timeago|less than a minute ago'), s__('Timeago|a while')],
+ [s__('Timeago|less than a minute ago'), s__('Timeago|in %s seconds')],
+ [s__('Timeago|about a minute ago'), s__('Timeago|in 1 minute')],
+ [s__('Timeago|%s minutes ago'), s__('Timeago|in %s minutes')],
+ [s__('Timeago|about an hour ago'), s__('Timeago|in 1 hour')],
+ [s__('Timeago|about %s hours ago'), s__('Timeago|in %s hours')],
+ [s__('Timeago|a day ago'), s__('Timeago|in 1 day')],
+ [s__('Timeago|%s days ago'), s__('Timeago|in %s days')],
+ [s__('Timeago|a week ago'), s__('Timeago|in 1 week')],
+ [s__('Timeago|%s weeks ago'), s__('Timeago|in %s weeks')],
+ [s__('Timeago|a month ago'), s__('Timeago|in 1 month')],
+ [s__('Timeago|%s months ago'), s__('Timeago|in %s months')],
+ [s__('Timeago|a year ago'), s__('Timeago|in 1 year')],
+ [s__('Timeago|%s years ago'), s__('Timeago|in %s years')]
+ ][index];
};
- w.gl.utils.timeFor = function(time, suffix, expiredLabel) {
- var timefor;
- if (!time) {
- return '';
- }
- if (new Date(time) < new Date()) {
- expiredLabel || (expiredLabel = s__('Timeago|Past due'));
- timefor = expiredLabel;
- } else {
- timefor = gl.utils.getTimeago().format(time, `${lang}-remaining`).trim();
- }
- return timefor;
- };
+ timeago.register(lang, locale);
+ timeago.register(`${lang}-remaining`, localeRemaining);
+ timeagoInstance = timeago();
+ }
- w.gl.utils.renderTimeago = function($els) {
- const timeagoEls = $els || document.querySelectorAll('.js-timeago-render');
+ return timeagoInstance;
+};
- // timeago.js sets timeouts internally for each timeago value to be updated in real time
- gl.utils.getTimeago().render(timeagoEls, lang);
- };
+w.gl.utils.timeFor = function(time, suffix, expiredLabel) {
+ var timefor;
+ if (!time) {
+ return '';
+ }
+ if (new Date(time) < new Date()) {
+ expiredLabel || (expiredLabel = s__('Timeago|Past due'));
+ timefor = expiredLabel;
+ } else {
+ timefor = gl.utils.getTimeago().format(time, `${lang}-remaining`).trim();
+ }
+ return timefor;
+};
- w.gl.utils.getDayDifference = function(a, b) {
- var millisecondsPerDay = 1000 * 60 * 60 * 24;
- var date1 = Date.UTC(a.getFullYear(), a.getMonth(), a.getDate());
- var date2 = Date.UTC(b.getFullYear(), b.getMonth(), b.getDate());
+w.gl.utils.renderTimeago = function($els) {
+ const timeagoEls = $els || document.querySelectorAll('.js-timeago-render');
- return Math.floor((date2 - date1) / millisecondsPerDay);
- };
- })(window);
-}).call(window);
+ // timeago.js sets timeouts internally for each timeago value to be updated in real time
+ gl.utils.getTimeago().render(timeagoEls, lang);
+};
+
+w.gl.utils.getDayDifference = function(a, b) {
+ var millisecondsPerDay = 1000 * 60 * 60 * 24;
+ var date1 = Date.UTC(a.getFullYear(), a.getMonth(), a.getDate());
+ var date2 = Date.UTC(b.getFullYear(), b.getMonth(), b.getDate());
+
+ return Math.floor((date2 - date1) / millisecondsPerDay);
+};
/**
* Port of ruby helper time_interval_in_words.
diff --git a/app/assets/javascripts/lib/utils/pretty_time.js b/app/assets/javascripts/lib/utils/pretty_time.js
index ae397212e55..a3d0b55afd3 100644
--- a/app/assets/javascripts/lib/utils/pretty_time.js
+++ b/app/assets/javascripts/lib/utils/pretty_time.js
@@ -1,65 +1,63 @@
-(() => {
+/*
+ * TODO: Make these methods more configurable (e.g. parseSeconds timePeriodContstraints,
+ * stringifyTime condensed or non-condensed, abbreviateTimelengths)
+ * */
+const gl = window.gl || (window.gl = {});
+const utils = window.gl.utils = gl.utils || {};
+const prettyTime = utils.prettyTime = {
/*
- * TODO: Make these methods more configurable (e.g. parseSeconds timePeriodContstraints,
- * stringifyTime condensed or non-condensed, abbreviateTimelengths)
- * */
+ * Accepts seconds and returns a timeObject { weeks: #, days: #, hours: #, minutes: # }
+ * Seconds can be negative or positive, zero or non-zero.
+ */
+ parseSeconds(seconds) {
+ const DAYS_PER_WEEK = 5;
+ const HOURS_PER_DAY = 8;
+ const MINUTES_PER_HOUR = 60;
+ const MINUTES_PER_WEEK = DAYS_PER_WEEK * HOURS_PER_DAY * MINUTES_PER_HOUR;
+ const MINUTES_PER_DAY = HOURS_PER_DAY * MINUTES_PER_HOUR;
+
+ const timePeriodConstraints = {
+ weeks: MINUTES_PER_WEEK,
+ days: MINUTES_PER_DAY,
+ hours: MINUTES_PER_HOUR,
+ minutes: 1,
+ };
+
+ let unorderedMinutes = prettyTime.secondsToMinutes(seconds);
+
+ return _.mapObject(timePeriodConstraints, (minutesPerPeriod) => {
+ const periodCount = Math.floor(unorderedMinutes / minutesPerPeriod);
+
+ unorderedMinutes -= (periodCount * minutesPerPeriod);
+
+ return periodCount;
+ });
+ },
- const utils = window.gl.utils = gl.utils || {};
- const prettyTime = utils.prettyTime = {
- /*
- * Accepts seconds and returns a timeObject { weeks: #, days: #, hours: #, minutes: # }
- * Seconds can be negative or positive, zero or non-zero.
- */
- parseSeconds(seconds) {
- const DAYS_PER_WEEK = 5;
- const HOURS_PER_DAY = 8;
- const MINUTES_PER_HOUR = 60;
- const MINUTES_PER_WEEK = DAYS_PER_WEEK * HOURS_PER_DAY * MINUTES_PER_HOUR;
- const MINUTES_PER_DAY = HOURS_PER_DAY * MINUTES_PER_HOUR;
-
- const timePeriodConstraints = {
- weeks: MINUTES_PER_WEEK,
- days: MINUTES_PER_DAY,
- hours: MINUTES_PER_HOUR,
- minutes: 1,
- };
-
- let unorderedMinutes = prettyTime.secondsToMinutes(seconds);
-
- return _.mapObject(timePeriodConstraints, (minutesPerPeriod) => {
- const periodCount = Math.floor(unorderedMinutes / minutesPerPeriod);
-
- unorderedMinutes -= (periodCount * minutesPerPeriod);
-
- return periodCount;
- });
- },
-
- /*
- * Accepts a timeObject and returns a condensed string representation of it
- * (e.g. '1w 2d 3h 1m' or '1h 30m'). Zero value units are not included.
- */
-
- stringifyTime(timeObject) {
- const reducedTime = _.reduce(timeObject, (memo, unitValue, unitName) => {
- const isNonZero = !!unitValue;
- return isNonZero ? `${memo} ${unitValue}${unitName.charAt(0)}` : memo;
- }, '').trim();
- return reducedTime.length ? reducedTime : '0m';
- },
-
- /*
- * Accepts a time string of any size (e.g. '1w 2d 3h 5m' or '1w 2d') and returns
- * the first non-zero unit/value pair.
- */
-
- abbreviateTime(timeStr) {
- return timeStr.split(' ')
- .filter(unitStr => unitStr.charAt(0) !== '0')[0];
- },
+ /*
+ * Accepts a timeObject and returns a condensed string representation of it
+ * (e.g. '1w 2d 3h 1m' or '1h 30m'). Zero value units are not included.
+ */
+
+ stringifyTime(timeObject) {
+ const reducedTime = _.reduce(timeObject, (memo, unitValue, unitName) => {
+ const isNonZero = !!unitValue;
+ return isNonZero ? `${memo} ${unitValue}${unitName.charAt(0)}` : memo;
+ }, '').trim();
+ return reducedTime.length ? reducedTime : '0m';
+ },
- secondsToMinutes(seconds) {
- return Math.abs(seconds / 60);
- },
- };
-})(window.gl || (window.gl = {}));
+ /*
+ * Accepts a time string of any size (e.g. '1w 2d 3h 5m' or '1w 2d') and returns
+ * the first non-zero unit/value pair.
+ */
+
+ abbreviateTime(timeStr) {
+ return timeStr.split(' ')
+ .filter(unitStr => unitStr.charAt(0) !== '0')[0];
+ },
+
+ secondsToMinutes(seconds) {
+ return Math.abs(seconds / 60);
+ },
+};
diff --git a/app/assets/javascripts/logo.js b/app/assets/javascripts/logo.js
index 729baa2e1a7..5b96686a331 100644
--- a/app/assets/javascripts/logo.js
+++ b/app/assets/javascripts/logo.js
@@ -1,7 +1,5 @@
/* eslint-disable func-names, space-before-function-paren, prefer-arrow-callback */
-(function() {
- window.addEventListener('beforeunload', function() {
- $('.tanuki-logo').addClass('animate');
- });
-}).call(window);
+window.addEventListener('beforeunload', function() {
+ $('.tanuki-logo').addClass('animate');
+});
diff --git a/app/assets/javascripts/member_expiration_date.js b/app/assets/javascripts/member_expiration_date.js
index e034729bd39..9b633485ff2 100644
--- a/app/assets/javascripts/member_expiration_date.js
+++ b/app/assets/javascripts/member_expiration_date.js
@@ -1,53 +1,51 @@
/* global Pikaday */
/* global dateFormat */
-(() => {
- // Add datepickers to all `js-access-expiration-date` elements. If those elements are
- // children of an element with the `clearable-input` class, and have a sibling
- // `js-clear-input` element, then show that element when there is a value in the
- // datepicker, and make clicking on that element clear the field.
- //
- window.gl = window.gl || {};
- gl.MemberExpirationDate = (selector = '.js-access-expiration-date') => {
- function toggleClearInput() {
- $(this).closest('.clearable-input').toggleClass('has-value', $(this).val() !== '');
- }
- const inputs = $(selector);
-
- inputs.each((i, el) => {
- const $input = $(el);
-
- const calendar = new Pikaday({
- field: $input.get(0),
- theme: 'gitlab-theme animate-picker',
- format: 'yyyy-mm-dd',
- minDate: new Date(),
- container: $input.parent().get(0),
- onSelect(dateText) {
- $input.val(dateFormat(new Date(dateText), 'yyyy-mm-dd'));
-
- $input.trigger('change');
-
- toggleClearInput.call($input);
- },
- });
-
- calendar.setDate(new Date($input.val()));
- $input.data('pikaday', calendar);
+// Add datepickers to all `js-access-expiration-date` elements. If those elements are
+// children of an element with the `clearable-input` class, and have a sibling
+// `js-clear-input` element, then show that element when there is a value in the
+// datepicker, and make clicking on that element clear the field.
+//
+window.gl = window.gl || {};
+gl.MemberExpirationDate = (selector = '.js-access-expiration-date') => {
+ function toggleClearInput() {
+ $(this).closest('.clearable-input').toggleClass('has-value', $(this).val() !== '');
+ }
+ const inputs = $(selector);
+
+ inputs.each((i, el) => {
+ const $input = $(el);
+
+ const calendar = new Pikaday({
+ field: $input.get(0),
+ theme: 'gitlab-theme animate-picker',
+ format: 'yyyy-mm-dd',
+ minDate: new Date(),
+ container: $input.parent().get(0),
+ onSelect(dateText) {
+ $input.val(dateFormat(new Date(dateText), 'yyyy-mm-dd'));
+
+ $input.trigger('change');
+
+ toggleClearInput.call($input);
+ },
});
- inputs.next('.js-clear-input').on('click', function clicked(event) {
- event.preventDefault();
+ calendar.setDate(new Date($input.val()));
+ $input.data('pikaday', calendar);
+ });
- const input = $(this).closest('.clearable-input').find(selector);
- const calendar = input.data('pikaday');
+ inputs.next('.js-clear-input').on('click', function clicked(event) {
+ event.preventDefault();
- calendar.setDate(null);
- input.trigger('change');
- toggleClearInput.call(input);
- });
+ const input = $(this).closest('.clearable-input').find(selector);
+ const calendar = input.data('pikaday');
+
+ calendar.setDate(null);
+ input.trigger('change');
+ toggleClearInput.call(input);
+ });
- inputs.on('blur', toggleClearInput);
+ inputs.on('blur', toggleClearInput);
- inputs.each(toggleClearInput);
- };
-}).call(window);
+ inputs.each(toggleClearInput);
+};
diff --git a/app/assets/javascripts/members.js b/app/assets/javascripts/members.js
index 8291b8c4a70..12a9abe281f 100644
--- a/app/assets/javascripts/members.js
+++ b/app/assets/javascripts/members.js
@@ -1,81 +1,79 @@
/* eslint-disable class-methods-use-this */
-(() => {
- window.gl = window.gl || {};
+window.gl = window.gl || {};
- class Members {
- constructor() {
- this.addListeners();
- this.initGLDropdown();
- }
+class Members {
+ constructor() {
+ this.addListeners();
+ this.initGLDropdown();
+ }
- addListeners() {
- $('.project_member, .group_member').off('ajax:success').on('ajax:success', this.removeRow);
- $('.js-member-update-control').off('change').on('change', this.formSubmit.bind(this));
- $('.js-edit-member-form').off('ajax:success').on('ajax:success', this.formSuccess.bind(this));
- gl.utils.disableButtonIfEmptyField('#user_ids', 'input[name=commit]', 'change');
- }
+ addListeners() {
+ $('.project_member, .group_member').off('ajax:success').on('ajax:success', this.removeRow);
+ $('.js-member-update-control').off('change').on('change', this.formSubmit.bind(this));
+ $('.js-edit-member-form').off('ajax:success').on('ajax:success', this.formSuccess.bind(this));
+ gl.utils.disableButtonIfEmptyField('#user_ids', 'input[name=commit]', 'change');
+ }
- initGLDropdown() {
- $('.js-member-permissions-dropdown').each((i, btn) => {
- const $btn = $(btn);
+ initGLDropdown() {
+ $('.js-member-permissions-dropdown').each((i, btn) => {
+ const $btn = $(btn);
- $btn.glDropdown({
- selectable: true,
- isSelectable(selected, $el) {
- return !$el.hasClass('is-active');
- },
- fieldName: $btn.data('field-name'),
- id(selected, $el) {
- return $el.data('id');
- },
- toggleLabel(selected, $el) {
- return $el.text();
- },
- clicked: (options) => {
- this.formSubmit(null, options.$el);
- },
- });
+ $btn.glDropdown({
+ selectable: true,
+ isSelectable(selected, $el) {
+ return !$el.hasClass('is-active');
+ },
+ fieldName: $btn.data('field-name'),
+ id(selected, $el) {
+ return $el.data('id');
+ },
+ toggleLabel(selected, $el) {
+ return $el.text();
+ },
+ clicked: (options) => {
+ this.formSubmit(null, options.$el);
+ },
});
- }
+ });
+ }
- removeRow(e) {
- const $target = $(e.target);
+ removeRow(e) {
+ const $target = $(e.target);
- if ($target.hasClass('btn-remove')) {
- $target.closest('.member')
- .fadeOut(function fadeOutMemberRow() {
- $(this).remove();
- });
- }
+ if ($target.hasClass('btn-remove')) {
+ $target.closest('.member')
+ .fadeOut(function fadeOutMemberRow() {
+ $(this).remove();
+ });
}
+ }
- formSubmit(e, $el = null) {
- const $this = e ? $(e.currentTarget) : $el;
- const { $toggle, $dateInput } = this.getMemberListItems($this);
+ formSubmit(e, $el = null) {
+ const $this = e ? $(e.currentTarget) : $el;
+ const { $toggle, $dateInput } = this.getMemberListItems($this);
- $this.closest('form').trigger('submit.rails');
+ $this.closest('form').trigger('submit.rails');
- $toggle.disable();
- $dateInput.disable();
- }
+ $toggle.disable();
+ $dateInput.disable();
+ }
- formSuccess(e) {
- const { $toggle, $dateInput } = this.getMemberListItems($(e.currentTarget).closest('.member'));
+ formSuccess(e) {
+ const { $toggle, $dateInput } = this.getMemberListItems($(e.currentTarget).closest('.member'));
- $toggle.enable();
- $dateInput.enable();
- }
+ $toggle.enable();
+ $dateInput.enable();
+ }
- getMemberListItems($el) {
- const $memberListItem = $el.is('.member') ? $el : $(`#${$el.data('el-id')}`);
+ getMemberListItems($el) {
+ const $memberListItem = $el.is('.member') ? $el : $(`#${$el.data('el-id')}`);
- return {
- $memberListItem,
- $toggle: $memberListItem.find('.dropdown-menu-toggle'),
- $dateInput: $memberListItem.find('.js-access-expiration-date'),
- };
- }
+ return {
+ $memberListItem,
+ $toggle: $memberListItem.find('.dropdown-menu-toggle'),
+ $dateInput: $memberListItem.find('.js-access-expiration-date'),
+ };
}
+}
- gl.Members = Members;
-})();
+gl.Members = Members;
diff --git a/app/assets/javascripts/merge_request.js b/app/assets/javascripts/merge_request.js
index 0db2abe507d..5444457f651 100644
--- a/app/assets/javascripts/merge_request.js
+++ b/app/assets/javascripts/merge_request.js
@@ -6,127 +6,123 @@ import TaskList from './task_list';
import './merge_request_tabs';
import IssuablesHelper from './helpers/issuables_helper';
-(function() {
- this.MergeRequest = (function() {
- function MergeRequest(opts) {
- // Initialize MergeRequest behavior
- //
- // Options:
- // action - String, current controller action
- //
- this.opts = opts != null ? opts : {};
- this.submitNoteForm = this.submitNoteForm.bind(this);
- this.$el = $('.merge-request');
- this.$('.show-all-commits').on('click', (function(_this) {
- return function() {
- return _this.showAllCommits();
- };
- })(this));
-
- this.initTabs();
- this.initMRBtnListeners();
- this.initCommitMessageListeners();
- this.closeReopenReportToggle = IssuablesHelper.initCloseReopenReport();
-
- if ($("a.btn-close").length) {
- this.taskList = new TaskList({
- dataType: 'merge_request',
- fieldName: 'description',
- selector: '.detail-page-description',
- onSuccess: (result) => {
- document.querySelector('#task_status').innerText = result.task_status;
- document.querySelector('#task_status_short').innerText = result.task_status_short;
- }
- });
- }
- }
-
- // Local jQuery finder
- MergeRequest.prototype.$ = function(selector) {
- return this.$el.find(selector);
- };
-
- MergeRequest.prototype.initTabs = function() {
- if (window.mrTabs) {
- window.mrTabs.unbindEvents();
- }
- window.mrTabs = new gl.MergeRequestTabs(this.opts);
+function MergeRequest(opts) {
+ // Initialize MergeRequest behavior
+ //
+ // Options:
+ // action - String, current controller action
+ //
+ this.opts = opts != null ? opts : {};
+ this.submitNoteForm = this.submitNoteForm.bind(this);
+ this.$el = $('.merge-request');
+ this.$('.show-all-commits').on('click', (function(_this) {
+ return function() {
+ return _this.showAllCommits();
};
-
- MergeRequest.prototype.showAllCommits = function() {
- this.$('.first-commits').remove();
- return this.$('.all-commits').removeClass('hide');
- };
-
- MergeRequest.prototype.initMRBtnListeners = function() {
- var _this;
- _this = this;
- return $('a.btn-close, a.btn-reopen').on('click', function(e) {
- var $this, shouldSubmit;
- $this = $(this);
- shouldSubmit = $this.hasClass('btn-comment');
- if (shouldSubmit && $this.data('submitted')) {
- return;
- }
-
- if (this.closeReopenReportToggle) this.closeReopenReportToggle.setDisable();
-
- if (shouldSubmit) {
- if ($this.hasClass('btn-comment-and-close') || $this.hasClass('btn-comment-and-reopen')) {
- e.preventDefault();
- e.stopImmediatePropagation();
-
- _this.submitNoteForm($this.closest('form'), $this);
- }
- }
- });
- };
-
- MergeRequest.prototype.submitNoteForm = function(form, $button) {
- var noteText;
- noteText = form.find("textarea.js-note-text").val();
- if (noteText.trim().length > 0) {
- form.submit();
- $button.data('submitted', true);
- return $button.trigger('click');
+ })(this));
+
+ this.initTabs();
+ this.initMRBtnListeners();
+ this.initCommitMessageListeners();
+ this.closeReopenReportToggle = IssuablesHelper.initCloseReopenReport();
+
+ if ($("a.btn-close").length) {
+ this.taskList = new TaskList({
+ dataType: 'merge_request',
+ fieldName: 'description',
+ selector: '.detail-page-description',
+ onSuccess: (result) => {
+ document.querySelector('#task_status').innerText = result.task_status;
+ document.querySelector('#task_status_short').innerText = result.task_status_short;
}
- };
-
- MergeRequest.prototype.initCommitMessageListeners = function() {
- $(document).on('click', 'a.js-with-description-link', function(e) {
- var textarea = $('textarea.js-commit-message');
- e.preventDefault();
+ });
+ }
+}
+
+// Local jQuery finder
+MergeRequest.prototype.$ = function(selector) {
+ return this.$el.find(selector);
+};
+
+MergeRequest.prototype.initTabs = function() {
+ if (window.mrTabs) {
+ window.mrTabs.unbindEvents();
+ }
+ window.mrTabs = new gl.MergeRequestTabs(this.opts);
+};
+
+MergeRequest.prototype.showAllCommits = function() {
+ this.$('.first-commits').remove();
+ return this.$('.all-commits').removeClass('hide');
+};
+
+MergeRequest.prototype.initMRBtnListeners = function() {
+ var _this;
+ _this = this;
+ return $('a.btn-close, a.btn-reopen').on('click', function(e) {
+ var $this, shouldSubmit;
+ $this = $(this);
+ shouldSubmit = $this.hasClass('btn-comment');
+ if (shouldSubmit && $this.data('submitted')) {
+ return;
+ }
- textarea.val(textarea.data('messageWithDescription'));
- $('.js-with-description-hint').hide();
- $('.js-without-description-hint').show();
- });
+ if (this.closeReopenReportToggle) this.closeReopenReportToggle.setDisable();
- $(document).on('click', 'a.js-without-description-link', function(e) {
- var textarea = $('textarea.js-commit-message');
+ if (shouldSubmit) {
+ if ($this.hasClass('btn-comment-and-close') || $this.hasClass('btn-comment-and-reopen')) {
e.preventDefault();
+ e.stopImmediatePropagation();
- textarea.val(textarea.data('messageWithoutDescription'));
- $('.js-with-description-hint').show();
- $('.js-without-description-hint').hide();
- });
- };
-
- MergeRequest.prototype.updateStatusText = function(classToRemove, classToAdd, newStatusText) {
- $('.detail-page-header .status-box')
- .removeClass(classToRemove)
- .addClass(classToAdd)
- .find('span')
- .text(newStatusText);
- };
-
- MergeRequest.prototype.decreaseCounter = function(by = 1) {
- const $el = $('.nav-links .js-merge-counter');
- const count = Math.max((parseInt($el.text().replace(/[^\d]/, ''), 10) - by), 0);
-
- $el.text(gl.text.addDelimiter(count));
- };
-
- return MergeRequest;
- })();
-}).call(window);
+ _this.submitNoteForm($this.closest('form'), $this);
+ }
+ }
+ });
+};
+
+MergeRequest.prototype.submitNoteForm = function(form, $button) {
+ var noteText;
+ noteText = form.find("textarea.js-note-text").val();
+ if (noteText.trim().length > 0) {
+ form.submit();
+ $button.data('submitted', true);
+ return $button.trigger('click');
+ }
+};
+
+MergeRequest.prototype.initCommitMessageListeners = function() {
+ $(document).on('click', 'a.js-with-description-link', function(e) {
+ var textarea = $('textarea.js-commit-message');
+ e.preventDefault();
+
+ textarea.val(textarea.data('messageWithDescription'));
+ $('.js-with-description-hint').hide();
+ $('.js-without-description-hint').show();
+ });
+
+ $(document).on('click', 'a.js-without-description-link', function(e) {
+ var textarea = $('textarea.js-commit-message');
+ e.preventDefault();
+
+ textarea.val(textarea.data('messageWithoutDescription'));
+ $('.js-with-description-hint').show();
+ $('.js-without-description-hint').hide();
+ });
+};
+
+MergeRequest.prototype.updateStatusText = function(classToRemove, classToAdd, newStatusText) {
+ $('.detail-page-header .status-box')
+ .removeClass(classToRemove)
+ .addClass(classToAdd)
+ .find('span')
+ .text(newStatusText);
+};
+
+MergeRequest.prototype.decreaseCounter = function(by = 1) {
+ const $el = $('.nav-links .js-merge-counter');
+ const count = Math.max((parseInt($el.text().replace(/[^\d]/, ''), 10) - by), 0);
+
+ $el.text(gl.text.addDelimiter(count));
+};
+
+window.MergeRequest = MergeRequest;
diff --git a/app/assets/javascripts/merge_request_tabs.js b/app/assets/javascripts/merge_request_tabs.js
index 7840f05a8ae..d73ebdb1a22 100644
--- a/app/assets/javascripts/merge_request_tabs.js
+++ b/app/assets/javascripts/merge_request_tabs.js
@@ -54,370 +54,368 @@ import BlobForkSuggestion from './blob/blob_fork_suggestion';
//
/* eslint-enable max-len */
-(() => {
- // Store the `location` object, allowing for easier stubbing in tests
- let location = window.location;
+// Store the `location` object, allowing for easier stubbing in tests
+let location = window.location;
- class MergeRequestTabs {
+class MergeRequestTabs {
- constructor({ action, setUrl, stubLocation } = {}) {
- this.diffsLoaded = false;
- this.pipelinesLoaded = false;
- this.commitsLoaded = false;
- this.fixedLayoutPref = null;
+ constructor({ action, setUrl, stubLocation } = {}) {
+ this.diffsLoaded = false;
+ this.pipelinesLoaded = false;
+ this.commitsLoaded = false;
+ this.fixedLayoutPref = null;
- this.setUrl = setUrl !== undefined ? setUrl : true;
- this.setCurrentAction = this.setCurrentAction.bind(this);
- this.tabShown = this.tabShown.bind(this);
- this.showTab = this.showTab.bind(this);
+ this.setUrl = setUrl !== undefined ? setUrl : true;
+ this.setCurrentAction = this.setCurrentAction.bind(this);
+ this.tabShown = this.tabShown.bind(this);
+ this.showTab = this.showTab.bind(this);
- if (stubLocation) {
- location = stubLocation;
- }
-
- this.bindEvents();
- this.activateTab(action);
- this.initAffix();
+ if (stubLocation) {
+ location = stubLocation;
}
- bindEvents() {
- $(document)
- .on('shown.bs.tab', '.merge-request-tabs a[data-toggle="tab"]', this.tabShown)
- .on('click', '.js-show-tab', this.showTab);
+ this.bindEvents();
+ this.activateTab(action);
+ this.initAffix();
+ }
- $('.merge-request-tabs a[data-toggle="tab"]')
- .on('click', this.clickTab);
- }
+ bindEvents() {
+ $(document)
+ .on('shown.bs.tab', '.merge-request-tabs a[data-toggle="tab"]', this.tabShown)
+ .on('click', '.js-show-tab', this.showTab);
+
+ $('.merge-request-tabs a[data-toggle="tab"]')
+ .on('click', this.clickTab);
+ }
- // Used in tests
- unbindEvents() {
- $(document)
- .off('shown.bs.tab', '.merge-request-tabs a[data-toggle="tab"]', this.tabShown)
- .off('click', '.js-show-tab', this.showTab);
+ // Used in tests
+ unbindEvents() {
+ $(document)
+ .off('shown.bs.tab', '.merge-request-tabs a[data-toggle="tab"]', this.tabShown)
+ .off('click', '.js-show-tab', this.showTab);
- $('.merge-request-tabs a[data-toggle="tab"]')
- .off('click', this.clickTab);
- }
+ $('.merge-request-tabs a[data-toggle="tab"]')
+ .off('click', this.clickTab);
+ }
- destroyPipelinesView() {
- if (this.commitPipelinesTable) {
- this.commitPipelinesTable.$destroy();
- this.commitPipelinesTable = null;
+ destroyPipelinesView() {
+ if (this.commitPipelinesTable) {
+ this.commitPipelinesTable.$destroy();
+ this.commitPipelinesTable = null;
- document.querySelector('#commit-pipeline-table-view').innerHTML = '';
- }
+ document.querySelector('#commit-pipeline-table-view').innerHTML = '';
}
+ }
- showTab(e) {
+ showTab(e) {
+ e.preventDefault();
+ this.activateTab($(e.target).data('action'));
+ }
+
+ clickTab(e) {
+ if (e.currentTarget && gl.utils.isMetaClick(e)) {
+ const targetLink = e.currentTarget.getAttribute('href');
+ e.stopImmediatePropagation();
e.preventDefault();
- this.activateTab($(e.target).data('action'));
+ window.open(targetLink, '_blank');
}
+ }
- clickTab(e) {
- if (e.currentTarget && gl.utils.isMetaClick(e)) {
- const targetLink = e.currentTarget.getAttribute('href');
- e.stopImmediatePropagation();
- e.preventDefault();
- window.open(targetLink, '_blank');
+ tabShown(e) {
+ const $target = $(e.target);
+ const action = $target.data('action');
+
+ if (action === 'commits') {
+ this.loadCommits($target.attr('href'));
+ this.expandView();
+ this.resetViewContainer();
+ this.destroyPipelinesView();
+ } else if (this.isDiffAction(action)) {
+ this.loadDiff($target.attr('href'));
+ if (Breakpoints.get().getBreakpointSize() !== 'lg') {
+ this.shrinkView();
}
- }
-
- tabShown(e) {
- const $target = $(e.target);
- const action = $target.data('action');
-
- if (action === 'commits') {
- this.loadCommits($target.attr('href'));
- this.expandView();
- this.resetViewContainer();
- this.destroyPipelinesView();
- } else if (this.isDiffAction(action)) {
- this.loadDiff($target.attr('href'));
- if (Breakpoints.get().getBreakpointSize() !== 'lg') {
- this.shrinkView();
- }
- if (this.diffViewType() === 'parallel') {
- this.expandViewContainer();
- }
- this.destroyPipelinesView();
- } else if (action === 'pipelines') {
- this.resetViewContainer();
- this.mountPipelinesView();
- } else {
- if (Breakpoints.get().getBreakpointSize() !== 'xs') {
- this.expandView();
- }
- this.resetViewContainer();
- this.destroyPipelinesView();
+ if (this.diffViewType() === 'parallel') {
+ this.expandViewContainer();
}
- if (this.setUrl) {
- this.setCurrentAction(action);
+ this.destroyPipelinesView();
+ } else if (action === 'pipelines') {
+ this.resetViewContainer();
+ this.mountPipelinesView();
+ } else {
+ if (Breakpoints.get().getBreakpointSize() !== 'xs') {
+ this.expandView();
}
+ this.resetViewContainer();
+ this.destroyPipelinesView();
}
+ if (this.setUrl) {
+ this.setCurrentAction(action);
+ }
+ }
- scrollToElement(container) {
- if (location.hash) {
- const offset = 0 - (
- $('.navbar-gitlab').outerHeight() +
- $('.js-tabs-affix').outerHeight()
- );
- const $el = $(`${container} ${location.hash}:not(.match)`);
- if ($el.length) {
- $.scrollTo($el[0], { offset });
- }
+ scrollToElement(container) {
+ if (location.hash) {
+ const offset = 0 - (
+ $('.navbar-gitlab').outerHeight() +
+ $('.js-tabs-affix').outerHeight()
+ );
+ const $el = $(`${container} ${location.hash}:not(.match)`);
+ if ($el.length) {
+ $.scrollTo($el[0], { offset });
}
}
+ }
+
+ // Activate a tab based on the current action
+ activateTab(action) {
+ // important note: the .tab('show') method triggers 'shown.bs.tab' event itself
+ $(`.merge-request-tabs a[data-action='${action}']`).tab('show');
+ }
- // Activate a tab based on the current action
- activateTab(action) {
- // important note: the .tab('show') method triggers 'shown.bs.tab' event itself
- $(`.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('show')
+ // 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
+ setCurrentAction(action) {
+ this.currentAction = action;
+
+ // Remove a trailing '/commits' '/diffs' '/pipelines'
+ let newState = location.pathname.replace(/\/(commits|diffs|pipelines)(\.html)?\/?$/, '');
+
+ // Append the new action if we're on a tab other than 'notes'
+ if (this.currentAction !== 'show' && this.currentAction !== 'new') {
+ newState += `/${this.currentAction}`;
}
- // 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('show')
- // 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
- setCurrentAction(action) {
- this.currentAction = action;
+ // Ensure parameters and hash come along for the ride
+ newState += location.search + location.hash;
- // Remove a trailing '/commits' '/diffs' '/pipelines'
- let newState = location.pathname.replace(/\/(commits|diffs|pipelines)(\.html)?\/?$/, '');
+ // TODO: Consider refactoring in light of turbolinks removal.
- // Append the new action if we're on a tab other than 'notes'
- if (this.currentAction !== 'show' && this.currentAction !== 'new') {
- newState += `/${this.currentAction}`;
- }
+ // Replace the current history state with the new one without breaking
+ // Turbolinks' history.
+ //
+ // See https://github.com/rails/turbolinks/issues/363
+ window.history.replaceState({
+ url: newState,
+ }, document.title, newState);
- // Ensure parameters and hash come along for the ride
- newState += location.search + location.hash;
+ return newState;
+ }
- // TODO: Consider refactoring in light of turbolinks removal.
+ loadCommits(source) {
+ if (this.commitsLoaded) {
+ return;
+ }
+ this.ajaxGet({
+ url: `${source}.json`,
+ success: (data) => {
+ document.querySelector('div#commits').innerHTML = data.html;
+ gl.utils.localTimeAgo($('.js-timeago', 'div#commits'));
+ this.commitsLoaded = true;
+ this.scrollToElement('#commits');
+ },
+ });
+ }
- // Replace the current history state with the new one without breaking
- // Turbolinks' history.
- //
- // See https://github.com/rails/turbolinks/issues/363
- window.history.replaceState({
- url: newState,
- }, document.title, newState);
+ mountPipelinesView() {
+ const pipelineTableViewEl = document.querySelector('#commit-pipeline-table-view');
+ const CommitPipelinesTable = gl.CommitPipelinesTable;
+ this.commitPipelinesTable = new CommitPipelinesTable({
+ propsData: {
+ endpoint: pipelineTableViewEl.dataset.endpoint,
+ helpPagePath: pipelineTableViewEl.dataset.helpPagePath,
+ },
+ }).$mount();
+
+ // $mount(el) replaces the el with the new rendered component. We need it in order to mount
+ // it everytime this tab is clicked - https://vuejs.org/v2/api/#vm-mount
+ pipelineTableViewEl.appendChild(this.commitPipelinesTable.$el);
+ }
- return newState;
+ loadDiff(source) {
+ if (this.diffsLoaded) {
+ return;
}
- loadCommits(source) {
- if (this.commitsLoaded) {
- return;
- }
- this.ajaxGet({
- url: `${source}.json`,
- success: (data) => {
- document.querySelector('div#commits').innerHTML = data.html;
- gl.utils.localTimeAgo($('.js-timeago', 'div#commits'));
- this.commitsLoaded = true;
- this.scrollToElement('#commits');
- },
- });
- }
+ // We extract pathname for the current Changes tab anchor href
+ // some pages like MergeRequestsController#new has query parameters on that anchor
+ const urlPathname = gl.utils.parseUrlPathname(source);
- mountPipelinesView() {
- const pipelineTableViewEl = document.querySelector('#commit-pipeline-table-view');
- const CommitPipelinesTable = gl.CommitPipelinesTable;
- this.commitPipelinesTable = new CommitPipelinesTable({
- propsData: {
- endpoint: pipelineTableViewEl.dataset.endpoint,
- helpPagePath: pipelineTableViewEl.dataset.helpPagePath,
- },
- }).$mount();
+ this.ajaxGet({
+ url: `${urlPathname}.json${location.search}`,
+ success: (data) => {
+ const $container = $('#diffs');
+ $container.html(data.html);
- // $mount(el) replaces the el with the new rendered component. We need it in order to mount
- // it everytime this tab is clicked - https://vuejs.org/v2/api/#vm-mount
- pipelineTableViewEl.appendChild(this.commitPipelinesTable.$el);
- }
+ if (typeof gl.diffNotesCompileComponents !== 'undefined') {
+ gl.diffNotesCompileComponents();
+ }
- loadDiff(source) {
- if (this.diffsLoaded) {
- return;
- }
+ gl.utils.localTimeAgo($('.js-timeago', 'div#diffs'));
+ $('#diffs .js-syntax-highlight').syntaxHighlight();
- // We extract pathname for the current Changes tab anchor href
- // some pages like MergeRequestsController#new has query parameters on that anchor
- const urlPathname = gl.utils.parseUrlPathname(source);
-
- this.ajaxGet({
- url: `${urlPathname}.json${location.search}`,
- success: (data) => {
- const $container = $('#diffs');
- $container.html(data.html);
-
- if (typeof gl.diffNotesCompileComponents !== 'undefined') {
- gl.diffNotesCompileComponents();
- }
-
- gl.utils.localTimeAgo($('.js-timeago', 'div#diffs'));
- $('#diffs .js-syntax-highlight').syntaxHighlight();
-
- if (this.diffViewType() === 'parallel' && this.isDiffAction(this.currentAction)) {
- this.expandViewContainer();
- }
- this.diffsLoaded = true;
-
- new gl.Diff();
- this.scrollToElement('#diffs');
-
- $('.diff-file').each((i, el) => {
- new BlobForkSuggestion({
- openButtons: $(el).find('.js-edit-blob-link-fork-toggler'),
- forkButtons: $(el).find('.js-fork-suggestion-button'),
- cancelButtons: $(el).find('.js-cancel-fork-suggestion-button'),
- suggestionSections: $(el).find('.js-file-fork-suggestion-section'),
- actionTextPieces: $(el).find('.js-file-fork-suggestion-section-action'),
- })
- .init();
+ if (this.diffViewType() === 'parallel' && this.isDiffAction(this.currentAction)) {
+ this.expandViewContainer();
+ }
+ this.diffsLoaded = true;
+
+ new gl.Diff();
+ this.scrollToElement('#diffs');
+
+ $('.diff-file').each((i, el) => {
+ new BlobForkSuggestion({
+ openButtons: $(el).find('.js-edit-blob-link-fork-toggler'),
+ forkButtons: $(el).find('.js-fork-suggestion-button'),
+ cancelButtons: $(el).find('.js-cancel-fork-suggestion-button'),
+ suggestionSections: $(el).find('.js-file-fork-suggestion-section'),
+ actionTextPieces: $(el).find('.js-file-fork-suggestion-section-action'),
+ })
+ .init();
+ });
+
+ // Scroll any linked note into view
+ // Similar to `toggler_behavior` in the discussion tab
+ const hash = window.gl.utils.getLocationHash();
+ const anchor = hash && $container.find(`.note[id="${hash}"]`);
+ if (anchor && anchor.length > 0) {
+ const notesContent = anchor.closest('.notes_content');
+ const lineType = notesContent.hasClass('new') ? 'new' : 'old';
+ notes.toggleDiffNote({
+ target: anchor,
+ lineType,
+ forceShow: true,
});
+ anchor[0].scrollIntoView();
+ window.gl.utils.handleLocationHash();
+ // We have multiple elements on the page with `#note_xxx`
+ // (discussion and diff tabs) and `:target` only applies to the first
+ anchor.addClass('target');
+ }
+ },
+ });
+ }
- // Scroll any linked note into view
- // Similar to `toggler_behavior` in the discussion tab
- const hash = window.gl.utils.getLocationHash();
- const anchor = hash && $container.find(`.note[id="${hash}"]`);
- if (anchor && anchor.length > 0) {
- const notesContent = anchor.closest('.notes_content');
- const lineType = notesContent.hasClass('new') ? 'new' : 'old';
- notes.toggleDiffNote({
- target: anchor,
- lineType,
- forceShow: true,
- });
- anchor[0].scrollIntoView();
- window.gl.utils.handleLocationHash();
- // We have multiple elements on the page with `#note_xxx`
- // (discussion and diff tabs) and `:target` only applies to the first
- anchor.addClass('target');
- }
- },
- });
- }
+ // Show or hide the loading spinner
+ //
+ // status - Boolean, true to show, false to hide
+ toggleLoading(status) {
+ $('.mr-loading-status .loading').toggle(status);
+ }
- // Show or hide the loading spinner
- //
- // status - Boolean, true to show, false to hide
- toggleLoading(status) {
- $('.mr-loading-status .loading').toggle(status);
- }
+ ajaxGet(options) {
+ const defaults = {
+ beforeSend: () => this.toggleLoading(true),
+ error: () => new Flash('An error occurred while fetching this tab.', 'alert'),
+ complete: () => this.toggleLoading(false),
+ dataType: 'json',
+ type: 'GET',
+ };
+ $.ajax($.extend({}, defaults, options));
+ }
- ajaxGet(options) {
- const defaults = {
- beforeSend: () => this.toggleLoading(true),
- error: () => new Flash('An error occurred while fetching this tab.', 'alert'),
- complete: () => this.toggleLoading(false),
- dataType: 'json',
- type: 'GET',
- };
- $.ajax($.extend({}, defaults, options));
- }
+ diffViewType() {
+ return $('.inline-parallel-buttons a.active').data('view-type');
+ }
- diffViewType() {
- return $('.inline-parallel-buttons a.active').data('view-type');
- }
+ isDiffAction(action) {
+ return action === 'diffs' || action === 'new/diffs';
+ }
- isDiffAction(action) {
- return action === 'diffs' || action === 'new/diffs';
+ expandViewContainer() {
+ const $wrapper = $('.content-wrapper .container-fluid');
+ if (this.fixedLayoutPref === null) {
+ this.fixedLayoutPref = $wrapper.hasClass('container-limited');
}
+ $wrapper.removeClass('container-limited');
+ }
- expandViewContainer() {
- const $wrapper = $('.content-wrapper .container-fluid');
- if (this.fixedLayoutPref === null) {
- this.fixedLayoutPref = $wrapper.hasClass('container-limited');
- }
- $wrapper.removeClass('container-limited');
+ resetViewContainer() {
+ if (this.fixedLayoutPref !== null) {
+ $('.content-wrapper .container-fluid')
+ .toggleClass('container-limited', this.fixedLayoutPref);
}
+ }
- resetViewContainer() {
- if (this.fixedLayoutPref !== null) {
- $('.content-wrapper .container-fluid')
- .toggleClass('container-limited', this.fixedLayoutPref);
- }
- }
+ shrinkView() {
+ const $gutterIcon = $('.js-sidebar-toggle i:visible');
- shrinkView() {
- const $gutterIcon = $('.js-sidebar-toggle i:visible');
+ // Wait until listeners are set
+ setTimeout(() => {
+ // Only when sidebar is expanded
+ if ($gutterIcon.is('.fa-angle-double-right')) {
+ $gutterIcon.closest('a').trigger('click', [true]);
+ }
+ }, 0);
+ }
- // Wait until listeners are set
- setTimeout(() => {
- // Only when sidebar is expanded
- if ($gutterIcon.is('.fa-angle-double-right')) {
- $gutterIcon.closest('a').trigger('click', [true]);
- }
- }, 0);
+ // Expand the issuable sidebar unless the user explicitly collapsed it
+ expandView() {
+ if (Cookies.get('collapsed_gutter') === 'true') {
+ return;
}
+ const $gutterIcon = $('.js-sidebar-toggle i:visible');
- // Expand the issuable sidebar unless the user explicitly collapsed it
- expandView() {
- if (Cookies.get('collapsed_gutter') === 'true') {
- return;
+ // Wait until listeners are set
+ setTimeout(() => {
+ // Only when sidebar is collapsed
+ if ($gutterIcon.is('.fa-angle-double-left')) {
+ $gutterIcon.closest('a').trigger('click', [true]);
}
- const $gutterIcon = $('.js-sidebar-toggle i:visible');
+ }, 0);
+ }
- // Wait until listeners are set
- setTimeout(() => {
- // Only when sidebar is collapsed
- if ($gutterIcon.is('.fa-angle-double-left')) {
- $gutterIcon.closest('a').trigger('click', [true]);
- }
- }, 0);
- }
+ initAffix() {
+ const $tabs = $('.js-tabs-affix');
+ const $fixedNav = $('.navbar-gitlab');
+
+ // Screen space on small screens is usually very sparse
+ // So we dont affix the tabs on these
+ if (Breakpoints.get().getBreakpointSize() === 'xs' || !$tabs.length) return;
+
+ /**
+ If the browser does not support position sticky, it returns the position as static.
+ If the browser does support sticky, then we allow the browser to handle it, if not
+ then we default back to Bootstraps affix
+ **/
+ if ($tabs.css('position') !== 'static') return;
+
+ const $diffTabs = $('#diff-notes-app');
+
+ $tabs.off('affix.bs.affix affix-top.bs.affix')
+ .affix({
+ offset: {
+ top: () => (
+ $diffTabs.offset().top - $tabs.height() - $fixedNav.height()
+ ),
+ },
+ })
+ .on('affix.bs.affix', () => $diffTabs.css({ marginTop: $tabs.height() }))
+ .on('affix-top.bs.affix', () => $diffTabs.css({ marginTop: '' }));
- initAffix() {
- const $tabs = $('.js-tabs-affix');
- const $fixedNav = $('.navbar-gitlab');
-
- // Screen space on small screens is usually very sparse
- // So we dont affix the tabs on these
- if (Breakpoints.get().getBreakpointSize() === 'xs' || !$tabs.length) return;
-
- /**
- If the browser does not support position sticky, it returns the position as static.
- If the browser does support sticky, then we allow the browser to handle it, if not
- then we default back to Bootstraps affix
- **/
- if ($tabs.css('position') !== 'static') return;
-
- const $diffTabs = $('#diff-notes-app');
-
- $tabs.off('affix.bs.affix affix-top.bs.affix')
- .affix({
- offset: {
- top: () => (
- $diffTabs.offset().top - $tabs.height() - $fixedNav.height()
- ),
- },
- })
- .on('affix.bs.affix', () => $diffTabs.css({ marginTop: $tabs.height() }))
- .on('affix-top.bs.affix', () => $diffTabs.css({ marginTop: '' }));
-
- // Fix bug when reloading the page already scrolling
- if ($tabs.hasClass('affix')) {
- $tabs.trigger('affix.bs.affix');
- }
+ // Fix bug when reloading the page already scrolling
+ if ($tabs.hasClass('affix')) {
+ $tabs.trigger('affix.bs.affix');
}
}
+}
- window.gl = window.gl || {};
- window.gl.MergeRequestTabs = MergeRequestTabs;
-})();
+window.gl = window.gl || {};
+window.gl.MergeRequestTabs = MergeRequestTabs;
diff --git a/app/assets/javascripts/milestone.js b/app/assets/javascripts/milestone.js
index 3e07ec4d0aa..6f503b7293a 100644
--- a/app/assets/javascripts/milestone.js
+++ b/app/assets/javascripts/milestone.js
@@ -2,52 +2,48 @@
/* global Flash */
/* global Sortable */
-(function() {
- this.Milestone = (function() {
- function Milestone() {
- this.bindTabsSwitching();
-
- // Load merge request tab if it is active
- // merge request tab is active based on different conditions in the backend
- this.loadTab($('.js-milestone-tabs .active a'));
-
- this.loadInitialTab();
- }
-
- Milestone.prototype.bindTabsSwitching = function() {
- return $('a[data-toggle="tab"]').on('show.bs.tab', (e) => {
- const $target = $(e.target);
-
- location.hash = $target.attr('href');
- this.loadTab($target);
- });
- };
-
- Milestone.prototype.loadInitialTab = function() {
- const $target = $(`.js-milestone-tabs a[href="${location.hash}"]`);
-
- if ($target.length) {
- $target.tab('show');
- }
- };
-
- Milestone.prototype.loadTab = function($target) {
- const endpoint = $target.data('endpoint');
- const tabElId = $target.attr('href');
-
- if (endpoint && !$target.hasClass('is-loaded')) {
- $.ajax({
- url: endpoint,
- dataType: 'JSON',
- })
- .fail(() => new Flash('Error loading milestone tab'))
- .done((data) => {
- $(tabElId).html(data.html);
- $target.addClass('is-loaded');
- });
- }
- };
-
- return Milestone;
- })();
-}).call(window);
+function Milestone() {
+ this.bindTabsSwitching();
+
+ // Load merge request tab if it is active
+ // merge request tab is active based on different conditions in the backend
+ this.loadTab($('.js-milestone-tabs .active a'));
+
+ this.loadInitialTab();
+}
+
+Milestone.prototype.bindTabsSwitching = function() {
+ return $('a[data-toggle="tab"]').on('show.bs.tab', (e) => {
+ const $target = $(e.target);
+
+ location.hash = $target.attr('href');
+ this.loadTab($target);
+ });
+};
+
+Milestone.prototype.loadInitialTab = function() {
+ const $target = $(`.js-milestone-tabs a[href="${location.hash}"]`);
+
+ if ($target.length) {
+ $target.tab('show');
+ }
+};
+
+Milestone.prototype.loadTab = function($target) {
+ const endpoint = $target.data('endpoint');
+ const tabElId = $target.attr('href');
+
+ if (endpoint && !$target.hasClass('is-loaded')) {
+ $.ajax({
+ url: endpoint,
+ dataType: 'JSON',
+ })
+ .fail(() => new Flash('Error loading milestone tab'))
+ .done((data) => {
+ $(tabElId).html(data.html);
+ $target.addClass('is-loaded');
+ });
+ }
+};
+
+window.Milestone = Milestone;
diff --git a/app/assets/javascripts/milestone_select.js b/app/assets/javascripts/milestone_select.js
index 9d481d7c003..bde4923fd2e 100644
--- a/app/assets/javascripts/milestone_select.js
+++ b/app/assets/javascripts/milestone_select.js
@@ -2,224 +2,220 @@
/* global Issuable */
/* global ListMilestone */
-(function() {
- this.MilestoneSelect = (function() {
- function MilestoneSelect(currentProject, els) {
- var _this, $els;
- if (currentProject != null) {
- _this = this;
- this.currentProject = JSON.parse(currentProject);
- }
+function MilestoneSelect(currentProject, els) {
+ var _this, $els;
+ if (currentProject != null) {
+ _this = this;
+ this.currentProject = JSON.parse(currentProject);
+ }
- $els = $(els);
+ $els = $(els);
- if (!els) {
- $els = $('.js-milestone-select');
- }
+ if (!els) {
+ $els = $('.js-milestone-select');
+ }
- $els.each(function(i, dropdown) {
- var $block, $dropdown, $loading, $selectbox, $sidebarCollapsedValue, $value, abilityName, collapsedSidebarLabelTemplate, defaultLabel, defaultNo, issuableId, issueUpdateURL, milestoneLinkNoneTemplate, milestoneLinkTemplate, milestonesUrl, projectId, selectedMilestone, selectedMilestoneDefault, showAny, showNo, showUpcoming, showStarted, useId, showMenuAbove;
- $dropdown = $(dropdown);
- projectId = $dropdown.data('project-id');
- milestonesUrl = $dropdown.data('milestones');
- issueUpdateURL = $dropdown.data('issueUpdate');
- showNo = $dropdown.data('show-no');
- showAny = $dropdown.data('show-any');
- showMenuAbove = $dropdown.data('showMenuAbove');
- showUpcoming = $dropdown.data('show-upcoming');
- showStarted = $dropdown.data('show-started');
- useId = $dropdown.data('use-id');
- defaultLabel = $dropdown.data('default-label');
- defaultNo = $dropdown.data('default-no');
- issuableId = $dropdown.data('issuable-id');
- abilityName = $dropdown.data('ability-name');
- $selectbox = $dropdown.closest('.selectbox');
- $block = $selectbox.closest('.block');
- $sidebarCollapsedValue = $block.find('.sidebar-collapsed-icon');
- $value = $block.find('.value');
- $loading = $block.find('.block-loading').fadeOut();
- selectedMilestoneDefault = (showAny ? '' : null);
- selectedMilestoneDefault = (showNo && defaultNo ? 'No Milestone' : selectedMilestoneDefault);
- selectedMilestone = $dropdown.data('selected') || selectedMilestoneDefault;
- if (issueUpdateURL) {
- milestoneLinkTemplate = _.template('<a href="/<%- full_path %>/milestones/<%- iid %>" class="bold has-tooltip" data-container="body" title="<%- remaining %>"><%- title %></a>');
- milestoneLinkNoneTemplate = '<span class="no-value">None</span>';
- collapsedSidebarLabelTemplate = _.template('<span class="has-tooltip" data-container="body" title="<%- remaining %>" data-placement="left"> <%- title %> </span>');
- }
- return $dropdown.glDropdown({
- showMenuAbove: showMenuAbove,
- data: function(term, callback) {
- return $.ajax({
- url: milestonesUrl
- }).done(function(data) {
- var extraOptions = [];
- if (showAny) {
- extraOptions.push({
- id: 0,
- name: '',
- title: 'Any Milestone'
- });
- }
- if (showNo) {
- extraOptions.push({
- id: -1,
- name: 'No Milestone',
- title: 'No Milestone'
- });
- }
- if (showUpcoming) {
- extraOptions.push({
- id: -2,
- name: '#upcoming',
- title: 'Upcoming'
- });
- }
- if (showStarted) {
- extraOptions.push({
- id: -3,
- name: '#started',
- title: 'Started'
- });
- }
- if (extraOptions.length) {
- extraOptions.push('divider');
- }
-
- callback(extraOptions.concat(data));
- if (showMenuAbove) {
- $dropdown.data('glDropdown').positionMenuAbove();
- }
- $(`[data-milestone-id="${selectedMilestone}"] > a`).addClass('is-active');
+ $els.each(function(i, dropdown) {
+ var $block, $dropdown, $loading, $selectbox, $sidebarCollapsedValue, $value, abilityName, collapsedSidebarLabelTemplate, defaultLabel, defaultNo, issuableId, issueUpdateURL, milestoneLinkNoneTemplate, milestoneLinkTemplate, milestonesUrl, projectId, selectedMilestone, selectedMilestoneDefault, showAny, showNo, showUpcoming, showStarted, useId, showMenuAbove;
+ $dropdown = $(dropdown);
+ projectId = $dropdown.data('project-id');
+ milestonesUrl = $dropdown.data('milestones');
+ issueUpdateURL = $dropdown.data('issueUpdate');
+ showNo = $dropdown.data('show-no');
+ showAny = $dropdown.data('show-any');
+ showMenuAbove = $dropdown.data('showMenuAbove');
+ showUpcoming = $dropdown.data('show-upcoming');
+ showStarted = $dropdown.data('show-started');
+ useId = $dropdown.data('use-id');
+ defaultLabel = $dropdown.data('default-label');
+ defaultNo = $dropdown.data('default-no');
+ issuableId = $dropdown.data('issuable-id');
+ abilityName = $dropdown.data('ability-name');
+ $selectbox = $dropdown.closest('.selectbox');
+ $block = $selectbox.closest('.block');
+ $sidebarCollapsedValue = $block.find('.sidebar-collapsed-icon');
+ $value = $block.find('.value');
+ $loading = $block.find('.block-loading').fadeOut();
+ selectedMilestoneDefault = (showAny ? '' : null);
+ selectedMilestoneDefault = (showNo && defaultNo ? 'No Milestone' : selectedMilestoneDefault);
+ selectedMilestone = $dropdown.data('selected') || selectedMilestoneDefault;
+ if (issueUpdateURL) {
+ milestoneLinkTemplate = _.template('<a href="/<%- full_path %>/milestones/<%- iid %>" class="bold has-tooltip" data-container="body" title="<%- remaining %>"><%- title %></a>');
+ milestoneLinkNoneTemplate = '<span class="no-value">None</span>';
+ collapsedSidebarLabelTemplate = _.template('<span class="has-tooltip" data-container="body" title="<%- remaining %>" data-placement="left"> <%- title %> </span>');
+ }
+ return $dropdown.glDropdown({
+ showMenuAbove: showMenuAbove,
+ data: function(term, callback) {
+ return $.ajax({
+ url: milestonesUrl
+ }).done(function(data) {
+ var extraOptions = [];
+ if (showAny) {
+ extraOptions.push({
+ id: 0,
+ name: '',
+ title: 'Any Milestone'
});
- },
- renderRow: function(milestone) {
- return `
- <li data-milestone-id="${milestone.name}">
- <a href='#' class='dropdown-menu-milestone-link'>
- ${_.escape(milestone.title)}
- </a>
- </li>
- `;
- },
- filterable: true,
- search: {
- fields: ['title']
- },
- selectable: true,
- toggleLabel: function(selected, el, e) {
- if (selected && 'id' in selected && $(el).hasClass('is-active')) {
- return selected.title;
- } else {
- return defaultLabel;
- }
- },
- defaultLabel: defaultLabel,
- fieldName: $dropdown.data('field-name'),
- text: function(milestone) {
- return _.escape(milestone.title);
- },
- id: function(milestone) {
- if (!useId && !$dropdown.is('.js-issuable-form-dropdown')) {
- return milestone.name;
- } else {
- return milestone.id;
- }
- },
- isSelected: function(milestone) {
- return milestone.name === selectedMilestone;
- },
- hidden: function() {
- $selectbox.hide();
- // display:block overrides the hide-collapse rule
- return $value.css('display', '');
- },
- opened: function(e) {
- const $el = $(e.currentTarget);
- if ($dropdown.hasClass('js-issue-board-sidebar')) {
- selectedMilestone = $dropdown[0].dataset.selected || selectedMilestoneDefault;
- }
- $('a.is-active', $el).removeClass('is-active');
- $(`[data-milestone-id="${selectedMilestone}"] > a`, $el).addClass('is-active');
- },
- vue: $dropdown.hasClass('js-issue-board-sidebar'),
- clicked: function(options) {
- const { $el, e } = options;
- let selected = options.selectedObj;
- var data, isIssueIndex, isMRIndex, isSelecting, page, boardsStore;
- page = $('body').data('page');
- isIssueIndex = page === 'projects:issues:index';
- isMRIndex = (page === page && page === 'projects:merge_requests:index');
- isSelecting = (selected.name !== selectedMilestone);
- selectedMilestone = isSelecting ? selected.name : selectedMilestoneDefault;
- if ($dropdown.hasClass('js-filter-bulk-update') || $dropdown.hasClass('js-issuable-form-dropdown')) {
- e.preventDefault();
- return;
- }
+ }
+ if (showNo) {
+ extraOptions.push({
+ id: -1,
+ name: 'No Milestone',
+ title: 'No Milestone'
+ });
+ }
+ if (showUpcoming) {
+ extraOptions.push({
+ id: -2,
+ name: '#upcoming',
+ title: 'Upcoming'
+ });
+ }
+ if (showStarted) {
+ extraOptions.push({
+ id: -3,
+ name: '#started',
+ title: 'Started'
+ });
+ }
+ if (extraOptions.length) {
+ extraOptions.push('divider');
+ }
- if ($dropdown.closest('.add-issues-modal').length) {
- boardsStore = gl.issueBoards.ModalStore.store.filter;
- }
+ callback(extraOptions.concat(data));
+ if (showMenuAbove) {
+ $dropdown.data('glDropdown').positionMenuAbove();
+ }
+ $(`[data-milestone-id="${selectedMilestone}"] > a`).addClass('is-active');
+ });
+ },
+ renderRow: function(milestone) {
+ return `
+ <li data-milestone-id="${milestone.name}">
+ <a href='#' class='dropdown-menu-milestone-link'>
+ ${_.escape(milestone.title)}
+ </a>
+ </li>
+ `;
+ },
+ filterable: true,
+ search: {
+ fields: ['title']
+ },
+ selectable: true,
+ toggleLabel: function(selected, el, e) {
+ if (selected && 'id' in selected && $(el).hasClass('is-active')) {
+ return selected.title;
+ } else {
+ return defaultLabel;
+ }
+ },
+ defaultLabel: defaultLabel,
+ fieldName: $dropdown.data('field-name'),
+ text: function(milestone) {
+ return _.escape(milestone.title);
+ },
+ id: function(milestone) {
+ if (!useId && !$dropdown.is('.js-issuable-form-dropdown')) {
+ return milestone.name;
+ } else {
+ return milestone.id;
+ }
+ },
+ isSelected: function(milestone) {
+ return milestone.name === selectedMilestone;
+ },
+ hidden: function() {
+ $selectbox.hide();
+ // display:block overrides the hide-collapse rule
+ return $value.css('display', '');
+ },
+ opened: function(e) {
+ const $el = $(e.currentTarget);
+ if ($dropdown.hasClass('js-issue-board-sidebar')) {
+ selectedMilestone = $dropdown[0].dataset.selected || selectedMilestoneDefault;
+ }
+ $('a.is-active', $el).removeClass('is-active');
+ $(`[data-milestone-id="${selectedMilestone}"] > a`, $el).addClass('is-active');
+ },
+ vue: $dropdown.hasClass('js-issue-board-sidebar'),
+ clicked: function(options) {
+ const { $el, e } = options;
+ let selected = options.selectedObj;
+ var data, isIssueIndex, isMRIndex, isSelecting, page, boardsStore;
+ page = $('body').data('page');
+ isIssueIndex = page === 'projects:issues:index';
+ isMRIndex = (page === page && page === 'projects:merge_requests:index');
+ isSelecting = (selected.name !== selectedMilestone);
+ selectedMilestone = isSelecting ? selected.name : selectedMilestoneDefault;
+ if ($dropdown.hasClass('js-filter-bulk-update') || $dropdown.hasClass('js-issuable-form-dropdown')) {
+ e.preventDefault();
+ return;
+ }
+
+ if ($dropdown.closest('.add-issues-modal').length) {
+ boardsStore = gl.issueBoards.ModalStore.store.filter;
+ }
- if (boardsStore) {
- boardsStore[$dropdown.data('field-name')] = selected.name;
- e.preventDefault();
- } else if ($dropdown.hasClass('js-filter-submit') && (isIssueIndex || isMRIndex)) {
- return Issuable.filterResults($dropdown.closest('form'));
- } else if ($dropdown.hasClass('js-filter-submit')) {
- return $dropdown.closest('form').submit();
- } else if ($dropdown.hasClass('js-issue-board-sidebar')) {
- if (selected.id !== -1 && isSelecting) {
- gl.issueBoards.boardStoreIssueSet('milestone', new ListMilestone({
- id: selected.id,
- title: selected.name
- }));
- } else {
- gl.issueBoards.boardStoreIssueDelete('milestone');
- }
+ if (boardsStore) {
+ boardsStore[$dropdown.data('field-name')] = selected.name;
+ e.preventDefault();
+ } else if ($dropdown.hasClass('js-filter-submit') && (isIssueIndex || isMRIndex)) {
+ return Issuable.filterResults($dropdown.closest('form'));
+ } else if ($dropdown.hasClass('js-filter-submit')) {
+ return $dropdown.closest('form').submit();
+ } else if ($dropdown.hasClass('js-issue-board-sidebar')) {
+ if (selected.id !== -1 && isSelecting) {
+ gl.issueBoards.boardStoreIssueSet('milestone', new ListMilestone({
+ id: selected.id,
+ title: selected.name
+ }));
+ } else {
+ gl.issueBoards.boardStoreIssueDelete('milestone');
+ }
- $dropdown.trigger('loading.gl.dropdown');
- $loading.removeClass('hidden').fadeIn();
+ $dropdown.trigger('loading.gl.dropdown');
+ $loading.removeClass('hidden').fadeIn();
- gl.issueBoards.BoardsStore.detail.issue.update($dropdown.attr('data-issue-update'))
- .then(function () {
- $dropdown.trigger('loaded.gl.dropdown');
- $loading.fadeOut();
- })
- .catch(() => {
- $loading.fadeOut();
- });
+ gl.issueBoards.BoardsStore.detail.issue.update($dropdown.attr('data-issue-update'))
+ .then(function () {
+ $dropdown.trigger('loaded.gl.dropdown');
+ $loading.fadeOut();
+ })
+ .catch(() => {
+ $loading.fadeOut();
+ });
+ } else {
+ selected = $selectbox.find('input[type="hidden"]').val();
+ data = {};
+ data[abilityName] = {};
+ data[abilityName].milestone_id = selected != null ? selected : null;
+ $loading.removeClass('hidden').fadeIn();
+ $dropdown.trigger('loading.gl.dropdown');
+ return $.ajax({
+ type: 'PUT',
+ url: issueUpdateURL,
+ data: data
+ }).done(function(data) {
+ $dropdown.trigger('loaded.gl.dropdown');
+ $loading.fadeOut();
+ $selectbox.hide();
+ $value.css('display', '');
+ if (data.milestone != null) {
+ data.milestone.full_path = _this.currentProject.full_path;
+ data.milestone.remaining = gl.utils.timeFor(data.milestone.due_date);
+ $value.html(milestoneLinkTemplate(data.milestone));
+ return $sidebarCollapsedValue.find('span').html(collapsedSidebarLabelTemplate(data.milestone));
} else {
- selected = $selectbox.find('input[type="hidden"]').val();
- data = {};
- data[abilityName] = {};
- data[abilityName].milestone_id = selected != null ? selected : null;
- $loading.removeClass('hidden').fadeIn();
- $dropdown.trigger('loading.gl.dropdown');
- return $.ajax({
- type: 'PUT',
- url: issueUpdateURL,
- data: data
- }).done(function(data) {
- $dropdown.trigger('loaded.gl.dropdown');
- $loading.fadeOut();
- $selectbox.hide();
- $value.css('display', '');
- if (data.milestone != null) {
- data.milestone.full_path = _this.currentProject.full_path;
- data.milestone.remaining = gl.utils.timeFor(data.milestone.due_date);
- $value.html(milestoneLinkTemplate(data.milestone));
- return $sidebarCollapsedValue.find('span').html(collapsedSidebarLabelTemplate(data.milestone));
- } else {
- $value.html(milestoneLinkNoneTemplate);
- return $sidebarCollapsedValue.find('span').text('No');
- }
- });
+ $value.html(milestoneLinkNoneTemplate);
+ return $sidebarCollapsedValue.find('span').text('No');
}
- }
- });
- });
- }
+ });
+ }
+ }
+ });
+ });
+}
- return MilestoneSelect;
- })();
-}).call(window);
+window.MilestoneSelect = MilestoneSelect;
diff --git a/app/assets/javascripts/namespace_select.js b/app/assets/javascripts/namespace_select.js
index 5da2db063a4..6ecd54e67f6 100644
--- a/app/assets/javascripts/namespace_select.js
+++ b/app/assets/javascripts/namespace_select.js
@@ -1,85 +1,78 @@
/* eslint-disable func-names, space-before-function-paren, no-var, prefer-rest-params, wrap-iife, one-var, vars-on-top, one-var-declaration-per-line, comma-dangle, object-shorthand, no-else-return, prefer-template, quotes, prefer-arrow-callback, no-param-reassign, no-cond-assign, max-len */
import Api from './api';
-(function() {
- window.NamespaceSelect = (function() {
- function NamespaceSelect(opts) {
- this.onSelectItem = this.onSelectItem.bind(this);
- var fieldName, showAny;
- this.dropdown = opts.dropdown;
- showAny = true;
- fieldName = 'namespace_id';
- if (this.dropdown.attr('data-field-name')) {
- fieldName = this.dropdown.data('fieldName');
+function NamespaceSelect(opts) {
+ this.onSelectItem = this.onSelectItem.bind(this);
+ var fieldName, showAny;
+ this.dropdown = opts.dropdown;
+ showAny = true;
+ fieldName = 'namespace_id';
+ if (this.dropdown.attr('data-field-name')) {
+ fieldName = this.dropdown.data('fieldName');
+ }
+ if (this.dropdown.attr('data-show-any')) {
+ showAny = this.dropdown.data('showAny');
+ }
+ this.dropdown.glDropdown({
+ filterable: true,
+ selectable: true,
+ filterRemote: true,
+ search: {
+ fields: ['path']
+ },
+ fieldName: fieldName,
+ toggleLabel: function(selected) {
+ if (selected.id == null) {
+ return selected.text;
+ } else {
+ return selected.kind + ": " + selected.full_path;
}
- if (this.dropdown.attr('data-show-any')) {
- showAny = this.dropdown.data('showAny');
- }
- this.dropdown.glDropdown({
- filterable: true,
- selectable: true,
- filterRemote: true,
- search: {
- fields: ['path']
- },
- fieldName: fieldName,
- toggleLabel: function(selected) {
- if (selected.id == null) {
- return selected.text;
- } else {
- return selected.kind + ": " + selected.full_path;
- }
- },
- data: function(term, dataCallback) {
- return Api.namespaces(term, function(namespaces) {
- var anyNamespace;
- if (showAny) {
- anyNamespace = {
- text: 'Any namespace',
- id: null
- };
- namespaces.unshift(anyNamespace);
- namespaces.splice(1, 0, 'divider');
- }
- return dataCallback(namespaces);
- });
- },
- text: function(namespace) {
- if (namespace.id == null) {
- return namespace.text;
- } else {
- return namespace.kind + ": " + namespace.full_path;
- }
- },
- renderRow: this.renderRow,
- clicked: this.onSelectItem
+ },
+ data: function(term, dataCallback) {
+ return Api.namespaces(term, function(namespaces) {
+ var anyNamespace;
+ if (showAny) {
+ anyNamespace = {
+ text: 'Any namespace',
+ id: null
+ };
+ namespaces.unshift(anyNamespace);
+ namespaces.splice(1, 0, 'divider');
+ }
+ return dataCallback(namespaces);
});
- }
-
- NamespaceSelect.prototype.onSelectItem = function(options) {
- const { e } = options;
- return e.preventDefault();
- };
+ },
+ text: function(namespace) {
+ if (namespace.id == null) {
+ return namespace.text;
+ } else {
+ return namespace.kind + ": " + namespace.full_path;
+ }
+ },
+ renderRow: this.renderRow,
+ clicked: this.onSelectItem
+ });
+}
- return NamespaceSelect;
- })();
+NamespaceSelect.prototype.onSelectItem = function(options) {
+ const { e } = options;
+ return e.preventDefault();
+};
- window.NamespaceSelects = (function() {
- function NamespaceSelects(opts) {
- var ref;
- if (opts == null) {
- opts = {};
- }
- this.$dropdowns = (ref = opts.$dropdowns) != null ? ref : $('.js-namespace-select');
- this.$dropdowns.each(function(i, dropdown) {
- var $dropdown;
- $dropdown = $(dropdown);
- return new window.NamespaceSelect({
- dropdown: $dropdown
- });
- });
- }
+function NamespaceSelects(opts) {
+ var ref;
+ if (opts == null) {
+ opts = {};
+ }
+ this.$dropdowns = (ref = opts.$dropdowns) != null ? ref : $('.js-namespace-select');
+ this.$dropdowns.each(function(i, dropdown) {
+ var $dropdown;
+ $dropdown = $(dropdown);
+ return new window.NamespaceSelect({
+ dropdown: $dropdown
+ });
+ });
+}
- return NamespaceSelects;
- })();
-}).call(window);
+window.NamespaceSelect = NamespaceSelect;
+window.NamespaceSelects = NamespaceSelects;
diff --git a/app/assets/javascripts/new_branch_form.js b/app/assets/javascripts/new_branch_form.js
index 39fb302b644..ad11ec92e58 100644
--- a/app/assets/javascripts/new_branch_form.js
+++ b/app/assets/javascripts/new_branch_form.js
@@ -1,97 +1,93 @@
/* eslint-disable func-names, space-before-function-paren, no-var, one-var, prefer-rest-params, max-len, vars-on-top, wrap-iife, consistent-return, comma-dangle, one-var-declaration-per-line, quotes, no-return-assign, prefer-arrow-callback, prefer-template, no-shadow, no-else-return, max-len, object-shorthand */
import RefSelectDropdown from '~/ref_select_dropdown';
-(function() {
- this.NewBranchForm = (function() {
- function NewBranchForm(form, availableRefs) {
- this.validate = this.validate.bind(this);
- this.branchNameError = form.find('.js-branch-name-error');
- this.name = form.find('.js-branch-name');
- this.ref = form.find('#ref');
- new RefSelectDropdown($('.js-branch-select'), availableRefs); // eslint-disable-line no-new
- this.setupRestrictions();
- this.addBinding();
- this.init();
- }
+function NewBranchForm(form, availableRefs) {
+ this.validate = this.validate.bind(this);
+ this.branchNameError = form.find('.js-branch-name-error');
+ this.name = form.find('.js-branch-name');
+ this.ref = form.find('#ref');
+ new RefSelectDropdown($('.js-branch-select'), availableRefs); // eslint-disable-line no-new
+ this.setupRestrictions();
+ this.addBinding();
+ this.init();
+}
- NewBranchForm.prototype.addBinding = function() {
- return this.name.on('blur', this.validate);
- };
+NewBranchForm.prototype.addBinding = function() {
+ return this.name.on('blur', this.validate);
+};
- NewBranchForm.prototype.init = function() {
- if (this.name.length && this.name.val().length > 0) {
- return this.name.trigger('blur');
- }
- };
+NewBranchForm.prototype.init = function() {
+ if (this.name.length && this.name.val().length > 0) {
+ return this.name.trigger('blur');
+ }
+};
- NewBranchForm.prototype.setupRestrictions = function() {
- var endsWith, invalid, single, startsWith;
- startsWith = {
- pattern: /^(\/|\.)/g,
- prefix: "can't start with",
- conjunction: "or"
- };
- endsWith = {
- pattern: /(\/|\.|\.lock)$/g,
- prefix: "can't end in",
- conjunction: "or"
- };
- invalid = {
- pattern: /(\s|~|\^|:|\?|\*|\[|\\|\.\.|@\{|\/{2,}){1}/g,
- prefix: "can't contain",
- conjunction: ", "
- };
- single = {
- pattern: /^@+$/g,
- prefix: "can't be",
- conjunction: "or"
- };
- return this.restrictions = [startsWith, invalid, endsWith, single];
- };
+NewBranchForm.prototype.setupRestrictions = function() {
+ var endsWith, invalid, single, startsWith;
+ startsWith = {
+ pattern: /^(\/|\.)/g,
+ prefix: "can't start with",
+ conjunction: "or"
+ };
+ endsWith = {
+ pattern: /(\/|\.|\.lock)$/g,
+ prefix: "can't end in",
+ conjunction: "or"
+ };
+ invalid = {
+ pattern: /(\s|~|\^|:|\?|\*|\[|\\|\.\.|@\{|\/{2,}){1}/g,
+ prefix: "can't contain",
+ conjunction: ", "
+ };
+ single = {
+ pattern: /^@+$/g,
+ prefix: "can't be",
+ conjunction: "or"
+ };
+ return this.restrictions = [startsWith, invalid, endsWith, single];
+};
- NewBranchForm.prototype.validate = function() {
- var errorMessage, errors, formatter, unique, validator;
- const indexOf = [].indexOf;
+NewBranchForm.prototype.validate = function() {
+ var errorMessage, errors, formatter, unique, validator;
+ const indexOf = [].indexOf;
- this.branchNameError.empty();
- unique = function(values, value) {
- if (indexOf.call(values, value) === -1) {
- values.push(value);
- }
- return values;
- };
- formatter = function(values, restriction) {
- var formatted;
- formatted = values.map(function(value) {
- switch (false) {
- case !/\s/.test(value):
- return 'spaces';
- case !/\/{2,}/g.test(value):
- return 'consecutive slashes';
- default:
- return "'" + value + "'";
- }
- });
- return restriction.prefix + " " + (formatted.join(restriction.conjunction));
- };
- validator = (function(_this) {
- return function(errors, restriction) {
- var matched;
- matched = _this.name.val().match(restriction.pattern);
- if (matched) {
- return errors.concat(formatter(matched.reduce(unique, []), restriction));
- } else {
- return errors;
- }
- };
- })(this);
- errors = this.restrictions.reduce(validator, []);
- if (errors.length > 0) {
- errorMessage = $("<span/>").text(errors.join(', '));
- return this.branchNameError.append(errorMessage);
+ this.branchNameError.empty();
+ unique = function(values, value) {
+ if (indexOf.call(values, value) === -1) {
+ values.push(value);
+ }
+ return values;
+ };
+ formatter = function(values, restriction) {
+ var formatted;
+ formatted = values.map(function(value) {
+ switch (false) {
+ case !/\s/.test(value):
+ return 'spaces';
+ case !/\/{2,}/g.test(value):
+ return 'consecutive slashes';
+ default:
+ return "'" + value + "'";
+ }
+ });
+ return restriction.prefix + " " + (formatted.join(restriction.conjunction));
+ };
+ validator = (function(_this) {
+ return function(errors, restriction) {
+ var matched;
+ matched = _this.name.val().match(restriction.pattern);
+ if (matched) {
+ return errors.concat(formatter(matched.reduce(unique, []), restriction));
+ } else {
+ return errors;
}
};
+ })(this);
+ errors = this.restrictions.reduce(validator, []);
+ if (errors.length > 0) {
+ errorMessage = $("<span/>").text(errors.join(', '));
+ return this.branchNameError.append(errorMessage);
+ }
+};
- return NewBranchForm;
- })();
-}).call(window);
+window.NewBranchForm = NewBranchForm;
diff --git a/app/assets/javascripts/new_commit_form.js b/app/assets/javascripts/new_commit_form.js
index 04073ef7270..9f7820b05f8 100644
--- a/app/assets/javascripts/new_commit_form.js
+++ b/app/assets/javascripts/new_commit_form.js
@@ -1,32 +1,29 @@
/* eslint-disable func-names, space-before-function-paren, no-var, prefer-rest-params, wrap-iife, no-return-assign, max-len */
-(function() {
- this.NewCommitForm = (function() {
- function NewCommitForm(form) {
- this.form = form;
- this.renderDestination = this.renderDestination.bind(this);
- this.branchName = form.find('.js-branch-name');
- this.originalBranch = form.find('.js-original-branch');
- this.createMergeRequest = form.find('.js-create-merge-request');
- this.createMergeRequestContainer = form.find('.js-create-merge-request-container');
- this.branchName.keyup(this.renderDestination);
- this.renderDestination();
- }
- NewCommitForm.prototype.renderDestination = function() {
- var different;
- different = this.branchName.val() !== this.originalBranch.val();
- if (different) {
- this.createMergeRequestContainer.show();
- if (!this.wasDifferent) {
- this.createMergeRequest.prop('checked', true);
- }
- } else {
- this.createMergeRequestContainer.hide();
- this.createMergeRequest.prop('checked', false);
- }
- return this.wasDifferent = different;
- };
+function NewCommitForm(form) {
+ this.form = form;
+ this.renderDestination = this.renderDestination.bind(this);
+ this.branchName = form.find('.js-branch-name');
+ this.originalBranch = form.find('.js-original-branch');
+ this.createMergeRequest = form.find('.js-create-merge-request');
+ this.createMergeRequestContainer = form.find('.js-create-merge-request-container');
+ this.branchName.keyup(this.renderDestination);
+ this.renderDestination();
+}
+
+NewCommitForm.prototype.renderDestination = function() {
+ var different;
+ different = this.branchName.val() !== this.originalBranch.val();
+ if (different) {
+ this.createMergeRequestContainer.show();
+ if (!this.wasDifferent) {
+ this.createMergeRequest.prop('checked', true);
+ }
+ } else {
+ this.createMergeRequestContainer.hide();
+ this.createMergeRequest.prop('checked', false);
+ }
+ return this.wasDifferent = different;
+};
- return NewCommitForm;
- })();
-}).call(window);
+window.NewCommitForm = NewCommitForm;
diff --git a/app/assets/javascripts/notifications_dropdown.js b/app/assets/javascripts/notifications_dropdown.js
index 838356133cd..f9f486fb4d8 100644
--- a/app/assets/javascripts/notifications_dropdown.js
+++ b/app/assets/javascripts/notifications_dropdown.js
@@ -1,31 +1,27 @@
/* eslint-disable func-names, space-before-function-paren, wrap-iife, one-var, no-var, one-var-declaration-per-line, no-unused-vars, consistent-return, prefer-arrow-callback, no-else-return, max-len */
/* global Flash */
-(function() {
- this.NotificationsDropdown = (function() {
- function NotificationsDropdown() {
- $(document).off('click', '.update-notification').on('click', '.update-notification', function(e) {
- var form, label, notificationLevel;
- e.preventDefault();
- if ($(this).is('.is-active') && $(this).data('notification-level') === 'custom') {
- return;
- }
- notificationLevel = $(this).data('notification-level');
- label = $(this).data('notification-title');
- form = $(this).parents('.notification-form:first');
- form.find('.js-notification-loading').toggleClass('fa-bell fa-spin fa-spinner');
- form.find('#notification_setting_level').val(notificationLevel);
- return form.submit();
- });
- $(document).off('ajax:success', '.notification-form').on('ajax:success', '.notification-form', function(e, data) {
- if (data.saved) {
- return $(e.currentTarget).closest('.js-notification-dropdown').replaceWith(data.html);
- } else {
- return new Flash('Failed to save new settings', 'alert');
- }
- });
+function NotificationsDropdown() {
+ $(document).off('click', '.update-notification').on('click', '.update-notification', function(e) {
+ var form, label, notificationLevel;
+ e.preventDefault();
+ if ($(this).is('.is-active') && $(this).data('notification-level') === 'custom') {
+ return;
}
+ notificationLevel = $(this).data('notification-level');
+ label = $(this).data('notification-title');
+ form = $(this).parents('.notification-form:first');
+ form.find('.js-notification-loading').toggleClass('fa-bell fa-spin fa-spinner');
+ form.find('#notification_setting_level').val(notificationLevel);
+ return form.submit();
+ });
+ $(document).off('ajax:success', '.notification-form').on('ajax:success', '.notification-form', function(e, data) {
+ if (data.saved) {
+ return $(e.currentTarget).closest('.js-notification-dropdown').replaceWith(data.html);
+ } else {
+ return new Flash('Failed to save new settings', 'alert');
+ }
+ });
+}
- return NotificationsDropdown;
- })();
-}).call(window);
+window.NotificationsDropdown = NotificationsDropdown;
diff --git a/app/assets/javascripts/notifications_form.js b/app/assets/javascripts/notifications_form.js
index 2ab9c4fed2c..d8709a6fa5f 100644
--- a/app/assets/javascripts/notifications_form.js
+++ b/app/assets/javascripts/notifications_form.js
@@ -1,55 +1,51 @@
/* eslint-disable func-names, space-before-function-paren, no-var, prefer-rest-params, wrap-iife, one-var, one-var-declaration-per-line, newline-per-chained-call, comma-dangle, consistent-return, prefer-arrow-callback, max-len */
-(function() {
- this.NotificationsForm = (function() {
- function NotificationsForm() {
- this.toggleCheckbox = this.toggleCheckbox.bind(this);
- this.removeEventListeners();
- this.initEventListeners();
- }
+function NotificationsForm() {
+ this.toggleCheckbox = this.toggleCheckbox.bind(this);
+ this.removeEventListeners();
+ this.initEventListeners();
+}
- NotificationsForm.prototype.removeEventListeners = function() {
- return $(document).off('change', '.js-custom-notification-event');
- };
+NotificationsForm.prototype.removeEventListeners = function() {
+ return $(document).off('change', '.js-custom-notification-event');
+};
- NotificationsForm.prototype.initEventListeners = function() {
- return $(document).on('change', '.js-custom-notification-event', this.toggleCheckbox);
- };
+NotificationsForm.prototype.initEventListeners = function() {
+ return $(document).on('change', '.js-custom-notification-event', this.toggleCheckbox);
+};
- NotificationsForm.prototype.toggleCheckbox = function(e) {
- var $checkbox, $parent;
- $checkbox = $(e.currentTarget);
- $parent = $checkbox.closest('.checkbox');
- return this.saveEvent($checkbox, $parent);
- };
+NotificationsForm.prototype.toggleCheckbox = function(e) {
+ var $checkbox, $parent;
+ $checkbox = $(e.currentTarget);
+ $parent = $checkbox.closest('.checkbox');
+ return this.saveEvent($checkbox, $parent);
+};
- NotificationsForm.prototype.showCheckboxLoadingSpinner = function($parent) {
- return $parent.addClass('is-loading').find('.custom-notification-event-loading').removeClass('fa-check').addClass('fa-spin fa-spinner').removeClass('is-done');
- };
+NotificationsForm.prototype.showCheckboxLoadingSpinner = function($parent) {
+ return $parent.addClass('is-loading').find('.custom-notification-event-loading').removeClass('fa-check').addClass('fa-spin fa-spinner').removeClass('is-done');
+};
- NotificationsForm.prototype.saveEvent = function($checkbox, $parent) {
- var form;
- form = $parent.parents('form:first');
- return $.ajax({
- url: form.attr('action'),
- method: form.attr('method'),
- dataType: 'json',
- data: form.serialize(),
- beforeSend: (function(_this) {
- return function() {
- return _this.showCheckboxLoadingSpinner($parent);
- };
- })(this)
- }).done(function(data) {
- $checkbox.enable();
- if (data.saved) {
- $parent.find('.custom-notification-event-loading').toggleClass('fa-spin fa-spinner fa-check is-done');
- return setTimeout(function() {
- return $parent.removeClass('is-loading').find('.custom-notification-event-loading').toggleClass('fa-spin fa-spinner fa-check is-done');
- }, 2000);
- }
- });
- };
+NotificationsForm.prototype.saveEvent = function($checkbox, $parent) {
+ var form;
+ form = $parent.parents('form:first');
+ return $.ajax({
+ url: form.attr('action'),
+ method: form.attr('method'),
+ dataType: 'json',
+ data: form.serialize(),
+ beforeSend: (function(_this) {
+ return function() {
+ return _this.showCheckboxLoadingSpinner($parent);
+ };
+ })(this)
+ }).done(function(data) {
+ $checkbox.enable();
+ if (data.saved) {
+ $parent.find('.custom-notification-event-loading').toggleClass('fa-spin fa-spinner fa-check is-done');
+ return setTimeout(function() {
+ return $parent.removeClass('is-loading').find('.custom-notification-event-loading').toggleClass('fa-spin fa-spinner fa-check is-done');
+ }, 2000);
+ }
+ });
+};
- return NotificationsForm;
- })();
-}).call(window);
+window.NotificationsForm = NotificationsForm;
diff --git a/app/assets/javascripts/pager.js b/app/assets/javascripts/pager.js
index 01110420cca..898bc40dacb 100644
--- a/app/assets/javascripts/pager.js
+++ b/app/assets/javascripts/pager.js
@@ -1,78 +1,76 @@
import '~/lib/utils/common_utils';
import '~/lib/utils/url_utility';
-(() => {
- const ENDLESS_SCROLL_BOTTOM_PX = 400;
- const ENDLESS_SCROLL_FIRE_DELAY_MS = 1000;
+const ENDLESS_SCROLL_BOTTOM_PX = 400;
+const ENDLESS_SCROLL_FIRE_DELAY_MS = 1000;
- const Pager = {
- init(limit = 0, preload = false, disable = false, prepareData = $.noop, callback = $.noop) {
- this.url = $('.content_list').data('href') || gl.utils.removeParams(['limit', 'offset']);
- this.limit = limit;
- this.offset = parseInt(gl.utils.getParameterByName('offset'), 10) || this.limit;
- this.disable = disable;
- this.prepareData = prepareData;
- this.callback = callback;
- this.loading = $('.loading').first();
- if (preload) {
- this.offset = 0;
- this.getOld();
- }
- this.initLoadMore();
- },
+const Pager = {
+ init(limit = 0, preload = false, disable = false, prepareData = $.noop, callback = $.noop) {
+ this.url = $('.content_list').data('href') || gl.utils.removeParams(['limit', 'offset']);
+ this.limit = limit;
+ this.offset = parseInt(gl.utils.getParameterByName('offset'), 10) || this.limit;
+ this.disable = disable;
+ this.prepareData = prepareData;
+ this.callback = callback;
+ this.loading = $('.loading').first();
+ if (preload) {
+ this.offset = 0;
+ this.getOld();
+ }
+ this.initLoadMore();
+ },
- getOld() {
- this.loading.show();
- $.ajax({
- type: 'GET',
- url: this.url,
- data: `limit=${this.limit}&offset=${this.offset}`,
- dataType: 'json',
- error: () => this.loading.hide(),
- success: (data) => {
- this.append(data.count, this.prepareData(data.html));
- this.callback();
+ getOld() {
+ this.loading.show();
+ $.ajax({
+ type: 'GET',
+ url: this.url,
+ data: `limit=${this.limit}&offset=${this.offset}`,
+ dataType: 'json',
+ error: () => this.loading.hide(),
+ success: (data) => {
+ this.append(data.count, this.prepareData(data.html));
+ this.callback();
- // keep loading until we've filled the viewport height
- if (!this.disable && !this.isScrollable()) {
- this.getOld();
- } else {
- this.loading.hide();
- }
- },
- });
- },
+ // keep loading until we've filled the viewport height
+ if (!this.disable && !this.isScrollable()) {
+ this.getOld();
+ } else {
+ this.loading.hide();
+ }
+ },
+ });
+ },
- append(count, html) {
- $('.content_list').append(html);
- if (count > 0) {
- this.offset += count;
- } else {
- this.disable = true;
- }
- },
+ append(count, html) {
+ $('.content_list').append(html);
+ if (count > 0) {
+ this.offset += count;
+ } else {
+ this.disable = true;
+ }
+ },
- isScrollable() {
- const $w = $(window);
- return $(document).height() > $w.height() + $w.scrollTop() + ENDLESS_SCROLL_BOTTOM_PX;
- },
+ isScrollable() {
+ const $w = $(window);
+ return $(document).height() > $w.height() + $w.scrollTop() + ENDLESS_SCROLL_BOTTOM_PX;
+ },
- initLoadMore() {
- $(document).unbind('scroll');
- $(document).endlessScroll({
- bottomPixels: ENDLESS_SCROLL_BOTTOM_PX,
- fireDelay: ENDLESS_SCROLL_FIRE_DELAY_MS,
- fireOnce: true,
- ceaseFire: () => this.disable === true,
- callback: () => {
- if (!this.loading.is(':visible')) {
- this.loading.show();
- this.getOld();
- }
- },
- });
- },
- };
+ initLoadMore() {
+ $(document).unbind('scroll');
+ $(document).endlessScroll({
+ bottomPixels: ENDLESS_SCROLL_BOTTOM_PX,
+ fireDelay: ENDLESS_SCROLL_FIRE_DELAY_MS,
+ fireOnce: true,
+ ceaseFire: () => this.disable === true,
+ callback: () => {
+ if (!this.loading.is(':visible')) {
+ this.loading.show();
+ this.getOld();
+ }
+ },
+ });
+ },
+};
- window.Pager = Pager;
-})();
+window.Pager = Pager;
diff --git a/app/assets/javascripts/preview_markdown.js b/app/assets/javascripts/preview_markdown.js
index 141333b2b4d..fd1cbda10dd 100644
--- a/app/assets/javascripts/preview_markdown.js
+++ b/app/assets/javascripts/preview_markdown.js
@@ -6,195 +6,191 @@
// (including the explanation of quick actions), and showing a warning when
// more than `x` users are referenced.
//
-(function () {
- var lastTextareaPreviewed;
- var lastTextareaHeight = null;
- var markdownPreview;
- var previewButtonSelector;
- var writeButtonSelector;
-
- window.MarkdownPreview = (function () {
- function MarkdownPreview() {}
-
- // Minimum number of users referenced before triggering a warning
- MarkdownPreview.prototype.referenceThreshold = 10;
- MarkdownPreview.prototype.emptyMessage = 'Nothing to preview.';
-
- MarkdownPreview.prototype.ajaxCache = {};
-
- MarkdownPreview.prototype.showPreview = function ($form) {
- var mdText;
- var preview = $form.find('.js-md-preview');
- var url = preview.data('url');
- if (preview.hasClass('md-preview-loading')) {
- return;
- }
- mdText = $form.find('textarea.markdown-area').val();
-
- if (mdText.trim().length === 0) {
- preview.text(this.emptyMessage);
- this.hideReferencedUsers($form);
+var lastTextareaPreviewed;
+var lastTextareaHeight = null;
+var markdownPreview;
+var previewButtonSelector;
+var writeButtonSelector;
+
+function MarkdownPreview() {}
+
+// Minimum number of users referenced before triggering a warning
+MarkdownPreview.prototype.referenceThreshold = 10;
+MarkdownPreview.prototype.emptyMessage = 'Nothing to preview.';
+
+MarkdownPreview.prototype.ajaxCache = {};
+
+MarkdownPreview.prototype.showPreview = function ($form) {
+ var mdText;
+ var preview = $form.find('.js-md-preview');
+ var url = preview.data('url');
+ if (preview.hasClass('md-preview-loading')) {
+ return;
+ }
+ mdText = $form.find('textarea.markdown-area').val();
+
+ if (mdText.trim().length === 0) {
+ preview.text(this.emptyMessage);
+ this.hideReferencedUsers($form);
+ } else {
+ preview.addClass('md-preview-loading').text('Loading...');
+ this.fetchMarkdownPreview(mdText, url, (function (response) {
+ var body;
+ if (response.body.length > 0) {
+ body = response.body;
} else {
- preview.addClass('md-preview-loading').text('Loading...');
- this.fetchMarkdownPreview(mdText, url, (function (response) {
- var body;
- if (response.body.length > 0) {
- body = response.body;
- } else {
- body = this.emptyMessage;
- }
-
- preview.removeClass('md-preview-loading').html(body);
- preview.renderGFM();
- this.renderReferencedUsers(response.references.users, $form);
-
- if (response.references.commands) {
- this.renderReferencedCommands(response.references.commands, $form);
- }
- }).bind(this));
- }
- };
-
- MarkdownPreview.prototype.fetchMarkdownPreview = function (text, url, success) {
- if (!url) {
- return;
+ body = this.emptyMessage;
}
- if (text === this.ajaxCache.text) {
- success(this.ajaxCache.response);
- return;
- }
- $.ajax({
- type: 'POST',
- url: url,
- data: {
- text: text
- },
- dataType: 'json',
- success: (function (response) {
- this.ajaxCache = {
- text: text,
- response: response
- };
- success(response);
- }).bind(this)
- });
- };
-
- MarkdownPreview.prototype.hideReferencedUsers = function ($form) {
- $form.find('.referenced-users').hide();
- };
-
- MarkdownPreview.prototype.renderReferencedUsers = function (users, $form) {
- var referencedUsers;
- referencedUsers = $form.find('.referenced-users');
- if (referencedUsers.length) {
- if (users.length >= this.referenceThreshold) {
- referencedUsers.show();
- referencedUsers.find('.js-referenced-users-count').text(users.length);
- } else {
- referencedUsers.hide();
- }
- }
- };
-
- MarkdownPreview.prototype.hideReferencedCommands = function ($form) {
- $form.find('.referenced-commands').hide();
- };
-
- MarkdownPreview.prototype.renderReferencedCommands = function (commands, $form) {
- var referencedCommands;
- referencedCommands = $form.find('.referenced-commands');
- if (commands.length > 0) {
- referencedCommands.html(commands);
- referencedCommands.show();
- } else {
- referencedCommands.html('');
- referencedCommands.hide();
- }
- };
-
- return MarkdownPreview;
- }());
-
- markdownPreview = new window.MarkdownPreview();
-
- previewButtonSelector = '.js-md-preview-button';
-
- writeButtonSelector = '.js-md-write-button';
-
- lastTextareaPreviewed = null;
- $.fn.setupMarkdownPreview = function () {
- var $form = $(this);
- $form.find('textarea.markdown-area').on('input', function () {
- markdownPreview.hideReferencedUsers($form);
- });
- };
+ preview.removeClass('md-preview-loading').html(body);
+ preview.renderGFM();
+ this.renderReferencedUsers(response.references.users, $form);
- $(document).on('markdown-preview:show', function (e, $form) {
- if (!$form) {
- return;
+ if (response.references.commands) {
+ this.renderReferencedCommands(response.references.commands, $form);
+ }
+ }).bind(this));
+ }
+};
+
+MarkdownPreview.prototype.fetchMarkdownPreview = function (text, url, success) {
+ if (!url) {
+ return;
+ }
+ if (text === this.ajaxCache.text) {
+ success(this.ajaxCache.response);
+ return;
+ }
+ $.ajax({
+ type: 'POST',
+ url: url,
+ data: {
+ text: text
+ },
+ dataType: 'json',
+ success: (function (response) {
+ this.ajaxCache = {
+ text: text,
+ response: response
+ };
+ success(response);
+ }).bind(this)
+ });
+};
+
+MarkdownPreview.prototype.hideReferencedUsers = function ($form) {
+ $form.find('.referenced-users').hide();
+};
+
+MarkdownPreview.prototype.renderReferencedUsers = function (users, $form) {
+ var referencedUsers;
+ referencedUsers = $form.find('.referenced-users');
+ if (referencedUsers.length) {
+ if (users.length >= this.referenceThreshold) {
+ referencedUsers.show();
+ referencedUsers.find('.js-referenced-users-count').text(users.length);
+ } else {
+ referencedUsers.hide();
}
+ }
+};
- lastTextareaPreviewed = $form.find('textarea.markdown-area');
- lastTextareaHeight = lastTextareaPreviewed.height();
+MarkdownPreview.prototype.hideReferencedCommands = function ($form) {
+ $form.find('.referenced-commands').hide();
+};
- // toggle tabs
- $form.find(writeButtonSelector).parent().removeClass('active');
- $form.find(previewButtonSelector).parent().addClass('active');
+MarkdownPreview.prototype.renderReferencedCommands = function (commands, $form) {
+ var referencedCommands;
+ referencedCommands = $form.find('.referenced-commands');
+ if (commands.length > 0) {
+ referencedCommands.html(commands);
+ referencedCommands.show();
+ } else {
+ referencedCommands.html('');
+ referencedCommands.hide();
+ }
+};
- // toggle content
- $form.find('.md-write-holder').hide();
- $form.find('.md-preview-holder').show();
- markdownPreview.showPreview($form);
- });
+window.MarkdownPreview = MarkdownPreview;
- $(document).on('markdown-preview:hide', function (e, $form) {
- if (!$form) {
- return;
- }
- lastTextareaPreviewed = null;
+markdownPreview = new window.MarkdownPreview();
- if (lastTextareaHeight) {
- $form.find('textarea.markdown-area').height(lastTextareaHeight);
- }
+previewButtonSelector = '.js-md-preview-button';
- // toggle tabs
- $form.find(writeButtonSelector).parent().addClass('active');
- $form.find(previewButtonSelector).parent().removeClass('active');
+writeButtonSelector = '.js-md-write-button';
- // toggle content
- $form.find('.md-write-holder').show();
- $form.find('textarea.markdown-area').focus();
- $form.find('.md-preview-holder').hide();
+lastTextareaPreviewed = null;
- markdownPreview.hideReferencedCommands($form);
- });
-
- $(document).on('markdown-preview:toggle', function (e, keyboardEvent) {
- var $target;
- $target = $(keyboardEvent.target);
- if ($target.is('textarea.markdown-area')) {
- $(document).triggerHandler('markdown-preview:show', [$target.closest('form')]);
- keyboardEvent.preventDefault();
- } else if (lastTextareaPreviewed) {
- $target = lastTextareaPreviewed;
- $(document).triggerHandler('markdown-preview:hide', [$target.closest('form')]);
- keyboardEvent.preventDefault();
- }
- });
-
- $(document).on('click', previewButtonSelector, function (e) {
- var $form;
- e.preventDefault();
- $form = $(this).closest('form');
- $(document).triggerHandler('markdown-preview:show', [$form]);
+$.fn.setupMarkdownPreview = function () {
+ var $form = $(this);
+ $form.find('textarea.markdown-area').on('input', function () {
+ markdownPreview.hideReferencedUsers($form);
});
+};
+
+$(document).on('markdown-preview:show', function (e, $form) {
+ if (!$form) {
+ return;
+ }
+
+ lastTextareaPreviewed = $form.find('textarea.markdown-area');
+ lastTextareaHeight = lastTextareaPreviewed.height();
+
+ // 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();
+ markdownPreview.showPreview($form);
+});
+
+$(document).on('markdown-preview:hide', function (e, $form) {
+ if (!$form) {
+ return;
+ }
+ lastTextareaPreviewed = null;
- $(document).on('click', writeButtonSelector, function (e) {
- var $form;
- e.preventDefault();
- $form = $(this).closest('form');
- $(document).triggerHandler('markdown-preview:hide', [$form]);
- });
-}());
+ if (lastTextareaHeight) {
+ $form.find('textarea.markdown-area').height(lastTextareaHeight);
+ }
+
+ // 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();
+ $form.find('.md-preview-holder').hide();
+
+ markdownPreview.hideReferencedCommands($form);
+});
+
+$(document).on('markdown-preview:toggle', function (e, keyboardEvent) {
+ var $target;
+ $target = $(keyboardEvent.target);
+ if ($target.is('textarea.markdown-area')) {
+ $(document).triggerHandler('markdown-preview:show', [$target.closest('form')]);
+ keyboardEvent.preventDefault();
+ } else if (lastTextareaPreviewed) {
+ $target = lastTextareaPreviewed;
+ $(document).triggerHandler('markdown-preview:hide', [$target.closest('form')]);
+ keyboardEvent.preventDefault();
+ }
+});
+
+$(document).on('click', previewButtonSelector, function (e) {
+ var $form;
+ e.preventDefault();
+ $form = $(this).closest('form');
+ $(document).triggerHandler('markdown-preview:show', [$form]);
+});
+
+$(document).on('click', writeButtonSelector, function (e) {
+ var $form;
+ e.preventDefault();
+ $form = $(this).closest('form');
+ $(document).triggerHandler('markdown-preview:hide', [$form]);
+});
diff --git a/app/assets/javascripts/project.js b/app/assets/javascripts/project.js
index 738e710deb9..e93ab0f06f2 100644
--- a/app/assets/javascripts/project.js
+++ b/app/assets/javascripts/project.js
@@ -3,129 +3,125 @@
import Cookies from 'js-cookie';
-(function() {
- this.Project = (function() {
- function Project() {
- $('ul.clone-options-dropdown a').click(function() {
- var url;
- if ($(this).hasClass('active')) {
- return;
- }
- $('.active').not($(this)).removeClass('active');
- $(this).toggleClass('active');
- 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();
- });
- $('.hide-no-ssh-message').on('click', function(e) {
- Cookies.set('hide_no_ssh_message', 'false');
- $(this).parents('.no-ssh-key-message').remove();
- return e.preventDefault();
- });
- $('.hide-no-password-message').on('click', function(e) {
- Cookies.set('hide_no_password_message', 'false');
- $(this).parents('.no-password-message').remove();
- return e.preventDefault();
- });
- this.projectSelectDropdown();
+function Project() {
+ $('ul.clone-options-dropdown a').click(function() {
+ var url;
+ if ($(this).hasClass('active')) {
+ return;
}
+ $('.active').not($(this)).removeClass('active');
+ $(this).toggleClass('active');
+ 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();
+ });
+ $('.hide-no-ssh-message').on('click', function(e) {
+ Cookies.set('hide_no_ssh_message', 'false');
+ $(this).parents('.no-ssh-key-message').remove();
+ return e.preventDefault();
+ });
+ $('.hide-no-password-message').on('click', function(e) {
+ Cookies.set('hide_no_password_message', 'false');
+ $(this).parents('.no-password-message').remove();
+ return e.preventDefault();
+ });
+ this.projectSelectDropdown();
+}
- Project.prototype.projectSelectDropdown = function() {
- new ProjectSelect();
- $('.project-item-select').on('click', (function(_this) {
- return function(e) {
- return _this.changeProject($(e.currentTarget).val());
- };
- })(this));
- return $('.js-projects-dropdown-toggle').on('click', function(e) {
- e.preventDefault();
- return $('.js-projects-dropdown').select2('open');
- });
+Project.prototype.projectSelectDropdown = function() {
+ new ProjectSelect();
+ $('.project-item-select').on('click', (function(_this) {
+ return function(e) {
+ return _this.changeProject($(e.currentTarget).val());
};
+ })(this));
+ return $('.js-projects-dropdown-toggle').on('click', function(e) {
+ e.preventDefault();
+ return $('.js-projects-dropdown').select2('open');
+ });
+};
- Project.prototype.changeProject = function(url) {
- return window.location = url;
- };
+Project.prototype.changeProject = function(url) {
+ return window.location = url;
+};
- Project.prototype.initRefSwitcher = function() {
- var refListItem = document.createElement('li');
- var refLink = document.createElement('a');
+Project.prototype.initRefSwitcher = function() {
+ var refListItem = document.createElement('li');
+ var refLink = document.createElement('a');
- refLink.href = '#';
+ refLink.href = '#';
- return $('.js-project-refs-dropdown').each(function() {
- var $dropdown, selected;
- $dropdown = $(this);
- selected = $dropdown.data('selected');
- return $dropdown.glDropdown({
- data: function(term, callback) {
- return $.ajax({
- url: $dropdown.data('refs-url'),
- data: {
- ref: $dropdown.data('ref'),
- search: term
- },
- dataType: "json"
- }).done(function(refs) {
- return callback(refs);
- });
+ return $('.js-project-refs-dropdown').each(function() {
+ var $dropdown, selected;
+ $dropdown = $(this);
+ selected = $dropdown.data('selected');
+ return $dropdown.glDropdown({
+ data: function(term, callback) {
+ return $.ajax({
+ url: $dropdown.data('refs-url'),
+ data: {
+ ref: $dropdown.data('ref'),
+ search: term
},
- selectable: true,
- filterable: true,
- filterRemote: true,
- filterByText: true,
- fieldName: $dropdown.data('field-name'),
- renderRow: function(ref) {
- var li = refListItem.cloneNode(false);
+ dataType: "json"
+ }).done(function(refs) {
+ return callback(refs);
+ });
+ },
+ selectable: true,
+ filterable: true,
+ filterRemote: true,
+ filterByText: true,
+ fieldName: $dropdown.data('field-name'),
+ renderRow: function(ref) {
+ var li = refListItem.cloneNode(false);
- if (ref.header != null) {
- li.className = 'dropdown-header';
- li.textContent = ref.header;
- } else {
- var link = refLink.cloneNode(false);
+ if (ref.header != null) {
+ li.className = 'dropdown-header';
+ li.textContent = ref.header;
+ } else {
+ var link = refLink.cloneNode(false);
- if (ref === selected) {
- link.className = 'is-active';
- }
+ if (ref === selected) {
+ link.className = 'is-active';
+ }
- link.textContent = ref;
- link.dataset.ref = ref;
+ link.textContent = ref;
+ link.dataset.ref = ref;
- li.appendChild(link);
- }
+ li.appendChild(link);
+ }
- return li;
- },
- id: function(obj, $el) {
- return $el.attr('data-ref');
- },
- toggleLabel: function(obj, $el) {
- return $el.text().trim();
- },
- clicked: function(options) {
- const { e } = options;
- e.preventDefault();
- if ($('input[name="ref"]').length) {
- var $form = $dropdown.closest('form');
- var action = $form.attr('action');
- var divider = action.indexOf('?') === -1 ? '?' : '&';
- gl.utils.visitUrl(action + '' + divider + '' + $form.serialize());
- }
- }
- });
- });
- };
+ return li;
+ },
+ id: function(obj, $el) {
+ return $el.attr('data-ref');
+ },
+ toggleLabel: function(obj, $el) {
+ return $el.text().trim();
+ },
+ clicked: function(options) {
+ const { e } = options;
+ e.preventDefault();
+ if ($('input[name="ref"]').length) {
+ var $form = $dropdown.closest('form');
+ var action = $form.attr('action');
+ var divider = action.indexOf('?') === -1 ? '?' : '&';
+ gl.utils.visitUrl(action + '' + divider + '' + $form.serialize());
+ }
+ }
+ });
+ });
+};
- return Project;
- })();
-}).call(window);
+window.Project = Project;
diff --git a/app/assets/javascripts/project_avatar.js b/app/assets/javascripts/project_avatar.js
index aabdfbf65e2..e412504de31 100644
--- a/app/assets/javascripts/project_avatar.js
+++ b/app/assets/javascripts/project_avatar.js
@@ -1,20 +1,16 @@
/* eslint-disable func-names, space-before-function-paren, wrap-iife, no-var, one-var, one-var-declaration-per-line, no-useless-escape, max-len */
-(function() {
- this.ProjectAvatar = (function() {
- function ProjectAvatar() {
- $('.js-choose-project-avatar-button').bind('click', function() {
- var form;
- form = $(this).closest('form');
- return form.find('.js-project-avatar-input').click();
- });
- $('.js-project-avatar-input').bind('change', function() {
- var filename, form;
- form = $(this).closest('form');
- filename = $(this).val().replace(/^.*[\\\/]/, '');
- return form.find('.js-avatar-filename').text(filename);
- });
- }
+function ProjectAvatar() {
+ $('.js-choose-project-avatar-button').bind('click', function() {
+ var form;
+ form = $(this).closest('form');
+ return form.find('.js-project-avatar-input').click();
+ });
+ $('.js-project-avatar-input').bind('change', function() {
+ var filename, form;
+ form = $(this).closest('form');
+ filename = $(this).val().replace(/^.*[\\\/]/, '');
+ return form.find('.js-avatar-filename').text(filename);
+ });
+}
- return ProjectAvatar;
- })();
-}).call(window);
+window.ProjectAvatar = ProjectAvatar;
diff --git a/app/assets/javascripts/project_find_file.js b/app/assets/javascripts/project_find_file.js
index 11f9754780d..e59901d5fc1 100644
--- a/app/assets/javascripts/project_find_file.js
+++ b/app/assets/javascripts/project_find_file.js
@@ -1,169 +1,161 @@
/* eslint-disable func-names, space-before-function-paren, no-var, prefer-rest-params, wrap-iife, quotes, consistent-return, one-var, one-var-declaration-per-line, no-cond-assign, max-len, object-shorthand, no-param-reassign, comma-dangle, prefer-template, no-unused-vars, no-return-assign */
/* global fuzzaldrinPlus */
-(function() {
- this.ProjectFindFile = (function() {
- var highlighter;
+var highlighter;
- function ProjectFindFile(element1, options) {
- this.element = element1;
- this.options = options;
- this.goToBlob = this.goToBlob.bind(this);
- this.goToTree = this.goToTree.bind(this);
- this.selectRowDown = this.selectRowDown.bind(this);
- this.selectRowUp = this.selectRowUp.bind(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);
- }
+function ProjectFindFile(element1, options) {
+ this.element = element1;
+ this.options = options;
+ this.goToBlob = this.goToBlob.bind(this);
+ this.goToTree = this.goToTree.bind(this);
+ this.selectRowDown = this.selectRowDown.bind(this);
+ this.selectRowUp = this.selectRowUp.bind(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);
+}
- ProjectFindFile.prototype.initEvent = function() {
- this.inputElement.off("keyup");
- this.inputElement.on("keyup", (function(_this) {
- return function(event) {
- var oldValue, ref, target, value;
- target = $(event.target);
- value = target.val();
- oldValue = (ref = target.data("oldValue")) != null ? ref : "";
- if (value !== oldValue) {
- target.data("oldValue", value);
- _this.findFile();
- return _this.element.find("tr.tree-item").eq(0).addClass("selected").focus();
- }
- };
- })(this));
- };
+ProjectFindFile.prototype.initEvent = function() {
+ this.inputElement.off("keyup");
+ this.inputElement.on("keyup", (event) => {
+ var oldValue, ref, target, value;
+ target = $(event.target);
+ value = target.val();
+ oldValue = (ref = target.data("oldValue")) != null ? ref : "";
+ if (value !== oldValue) {
+ target.data("oldValue", value);
+ this.findFile();
+ return this.element.find("tr.tree-item").eq(0).addClass("selected").focus();
+ }
+ });
+};
- ProjectFindFile.prototype.findFile = function() {
- var result, searchText;
- searchText = this.inputElement.val();
- result = searchText.length > 0 ? fuzzaldrinPlus.filter(this.filePaths, searchText) : this.filePaths;
- return this.renderList(result, searchText);
- // find file
- };
+ProjectFindFile.prototype.findFile = function() {
+ var result, searchText;
+ 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,
- method: "get",
- dataType: "json",
- success: (function(_this) {
- return function(data) {
- _this.element.find(".loading").hide();
- _this.filePaths = data;
- _this.findFile();
- return _this.element.find(".files-slider tr.tree-item").eq(0).addClass("selected").focus();
- };
- })(this)
- });
- };
+// files pathes load
+ProjectFindFile.prototype.load = function(url) {
+ return $.ajax({
+ url: url,
+ method: "get",
+ dataType: "json",
+ success: (data) => {
+ this.element.find(".loading").hide();
+ this.filePaths = data;
+ this.findFile();
+ return this.element.find(".files-slider tr.tree-item").eq(0).addClass("selected").focus();
+ }
+ });
+};
- // render result
- ProjectFindFile.prototype.renderList = function(filePaths, searchText) {
- var blobItemUrl, filePath, html, i, j, len, matches, results;
- this.element.find(".tree-table > tbody").empty();
- results = [];
- for (i = j = 0, len = filePaths.length; j < len; i = (j += 1)) {
- filePath = filePaths[i];
- if (i === 20) {
- break;
- }
- if (searchText) {
- matches = fuzzaldrinPlus.match(filePath, searchText);
- }
- blobItemUrl = this.options.blobUrlTemplate + "/" + filePath;
- html = this.makeHtml(filePath, matches, blobItemUrl);
- results.push(this.element.find(".tree-table > tbody").append(html));
- }
- return results;
- };
+// render result
+ProjectFindFile.prototype.renderList = function(filePaths, searchText) {
+ var blobItemUrl, filePath, html, i, j, len, matches, results;
+ this.element.find(".tree-table > tbody").empty();
+ results = [];
+ for (i = j = 0, len = filePaths.length; j < len; i = (j += 1)) {
+ filePath = filePaths[i];
+ if (i === 20) {
+ break;
+ }
+ if (searchText) {
+ matches = fuzzaldrinPlus.match(filePath, searchText);
+ }
+ blobItemUrl = this.options.blobUrlTemplate + "/" + filePath;
+ html = this.makeHtml(filePath, matches, blobItemUrl);
+ results.push(this.element.find(".tree-table > tbody").append(html));
+ }
+ 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;
- highlightText = "";
- matchedChars = [];
- for (j = 0, len = matches.length; j < len; j += 1) {
- matchIndex = matches[j];
- unmatched = text.substring(lastIndex, matchIndex);
- if (unmatched) {
- if (matchedChars.length) {
- element.append(matchedChars.join("").bold());
- }
- matchedChars = [];
- element.append(document.createTextNode(unmatched));
- }
- matchedChars.push(text[matchIndex]);
- lastIndex = matchIndex + 1;
- }
+// 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;
+ highlightText = "";
+ matchedChars = [];
+ for (j = 0, len = matches.length; j < len; j += 1) {
+ matchIndex = matches[j];
+ unmatched = text.substring(lastIndex, matchIndex);
+ if (unmatched) {
if (matchedChars.length) {
element.append(matchedChars.join("").bold());
}
- return element.append(document.createTextNode(text.substring(lastIndex)));
- };
+ matchedChars = [];
+ element.append(document.createTextNode(unmatched));
+ }
+ matchedChars.push(text[matchIndex]);
+ lastIndex = matchIndex + 1;
+ }
+ if (matchedChars.length) {
+ element.append(matchedChars.join("").bold());
+ }
+ 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 link-container'><a><i class='fa fa-file-text-o fa-fw'></i><span class='str-truncated'></span></a></td></tr>");
- if (matches) {
- $tr.find("a").replaceWith(highlighter($tr.find("a"), filePath, matches).attr("href", blobItemUrl));
- } else {
- $tr.find("a").attr("href", blobItemUrl);
- $tr.find(".str-truncated").text(filePath);
- }
- return $tr;
- };
+// make tbody row html
+ProjectFindFile.prototype.makeHtml = function(filePath, matches, blobItemUrl) {
+ var $tr;
+ $tr = $("<tr class='tree-item'><td class='tree-item-file-name link-container'><a><i class='fa fa-file-text-o fa-fw'></i><span class='str-truncated'></span></a></td></tr>");
+ if (matches) {
+ $tr.find("a").replaceWith(highlighter($tr.find("a"), filePath, matches).attr("href", blobItemUrl));
+ } else {
+ $tr.find("a").attr("href", blobItemUrl);
+ $tr.find(".str-truncated").text(filePath);
+ }
+ return $tr;
+};
- ProjectFindFile.prototype.selectRow = function(type) {
- var next, rows, selectedRow;
- rows = this.element.find(".files-slider tr.tree-item");
- selectedRow = this.element.find(".files-slider tr.tree-item.selected");
- if (rows && rows.length > 0) {
- if (selectedRow && selectedRow.length > 0) {
- if (type === "UP") {
- next = selectedRow.prev();
- } else if (type === "DOWN") {
- next = selectedRow.next();
- }
- if (next.length > 0) {
- selectedRow.removeClass("selected");
- selectedRow = next;
- }
- } else {
- selectedRow = rows.eq(0);
- }
- return selectedRow.addClass("selected").focus();
+ProjectFindFile.prototype.selectRow = function(type) {
+ var next, rows, selectedRow;
+ rows = this.element.find(".files-slider tr.tree-item");
+ selectedRow = this.element.find(".files-slider tr.tree-item.selected");
+ if (rows && rows.length > 0) {
+ if (selectedRow && selectedRow.length > 0) {
+ if (type === "UP") {
+ next = selectedRow.prev();
+ } else if (type === "DOWN") {
+ next = selectedRow.next();
}
- };
+ if (next.length > 0) {
+ selectedRow.removeClass("selected");
+ selectedRow = next;
+ }
+ } else {
+ selectedRow = rows.eq(0);
+ }
+ return selectedRow.addClass("selected").focus();
+ }
+};
- ProjectFindFile.prototype.selectRowUp = function() {
- return this.selectRow("UP");
- };
+ProjectFindFile.prototype.selectRowUp = function() {
+ return this.selectRow("UP");
+};
- ProjectFindFile.prototype.selectRowDown = function() {
- return this.selectRow("DOWN");
- };
+ProjectFindFile.prototype.selectRowDown = function() {
+ return this.selectRow("DOWN");
+};
- ProjectFindFile.prototype.goToTree = function() {
- return location.href = this.options.treeUrl;
- };
+ProjectFindFile.prototype.goToTree = function() {
+ return location.href = this.options.treeUrl;
+};
- ProjectFindFile.prototype.goToBlob = function() {
- var $link = this.element.find(".tree-item.selected .tree-item-file-name a");
+ProjectFindFile.prototype.goToBlob = function() {
+ var $link = this.element.find(".tree-item.selected .tree-item-file-name a");
- if ($link.length) {
- $link.get(0).click();
- }
- };
+ if ($link.length) {
+ $link.get(0).click();
+ }
+};
- return ProjectFindFile;
- })();
-}).call(window);
+window.ProjectFindFile = ProjectFindFile;
diff --git a/app/assets/javascripts/project_fork.js b/app/assets/javascripts/project_fork.js
index 47197db39d3..51b1a7db108 100644
--- a/app/assets/javascripts/project_fork.js
+++ b/app/assets/javascripts/project_fork.js
@@ -1,13 +1,9 @@
/* eslint-disable func-names, space-before-function-paren, wrap-iife, prefer-arrow-callback, max-len */
-(function() {
- this.ProjectFork = (function() {
- function ProjectFork() {
- $('.fork-thumbnail a').on('click', function() {
- $('.fork-namespaces').hide();
- return $('.save-project-loader').show();
- });
- }
+function ProjectFork() {
+ $('.fork-thumbnail a').on('click', function() {
+ $('.fork-namespaces').hide();
+ return $('.save-project-loader').show();
+ });
+}
- return ProjectFork;
- })();
-}).call(window);
+window.ProjectFork = ProjectFork;
diff --git a/app/assets/javascripts/project_import.js b/app/assets/javascripts/project_import.js
index 08334bf1ec5..f6d4d51d1c7 100644
--- a/app/assets/javascripts/project_import.js
+++ b/app/assets/javascripts/project_import.js
@@ -1,13 +1,9 @@
/* eslint-disable func-names, space-before-function-paren, wrap-iife, prefer-arrow-callback, max-len */
-(function() {
- this.ProjectImport = (function() {
- function ProjectImport() {
- setTimeout(function() {
- return gl.utils.visitUrl(location.href);
- }, 5000);
- }
+function ProjectImport() {
+ setTimeout(function() {
+ return gl.utils.visitUrl(location.href);
+ }, 5000);
+}
- return ProjectImport;
- })();
-}).call(window);
+window.ProjectImport = ProjectImport;
diff --git a/app/assets/javascripts/project_label_subscription.js b/app/assets/javascripts/project_label_subscription.js
index 0a811627600..d17a9bac82b 100644
--- a/app/assets/javascripts/project_label_subscription.js
+++ b/app/assets/javascripts/project_label_subscription.js
@@ -1,55 +1,54 @@
/* eslint-disable wrap-iife, func-names, space-before-function-paren, object-shorthand, comma-dangle, one-var, one-var-declaration-per-line, no-restricted-syntax, max-len, no-param-reassign */
+const global = window.gl || (window.gl = {});
-(function(global) {
- class ProjectLabelSubscription {
- constructor(container) {
- this.$container = $(container);
- this.$buttons = this.$container.find('.js-subscribe-button');
+class ProjectLabelSubscription {
+ constructor(container) {
+ this.$container = $(container);
+ this.$buttons = this.$container.find('.js-subscribe-button');
- this.$buttons.on('click', this.toggleSubscription.bind(this));
- }
+ this.$buttons.on('click', this.toggleSubscription.bind(this));
+ }
- toggleSubscription(event) {
- event.preventDefault();
+ toggleSubscription(event) {
+ event.preventDefault();
- const $btn = $(event.currentTarget);
- const $span = $btn.find('span');
- const url = $btn.attr('data-url');
- const oldStatus = $btn.attr('data-status');
+ const $btn = $(event.currentTarget);
+ const $span = $btn.find('span');
+ const url = $btn.attr('data-url');
+ const oldStatus = $btn.attr('data-status');
- $btn.addClass('disabled');
- $span.toggleClass('hidden');
+ $btn.addClass('disabled');
+ $span.toggleClass('hidden');
- $.ajax({
- type: 'POST',
- url: url
- }).done(() => {
- let newStatus, newAction;
+ $.ajax({
+ type: 'POST',
+ url: url
+ }).done(() => {
+ let newStatus, newAction;
- if (oldStatus === 'unsubscribed') {
- [newStatus, newAction] = ['subscribed', 'Unsubscribe'];
- } else {
- [newStatus, newAction] = ['unsubscribed', 'Subscribe'];
- }
+ if (oldStatus === 'unsubscribed') {
+ [newStatus, newAction] = ['subscribed', 'Unsubscribe'];
+ } else {
+ [newStatus, newAction] = ['unsubscribed', 'Subscribe'];
+ }
- $span.toggleClass('hidden');
- $btn.removeClass('disabled');
+ $span.toggleClass('hidden');
+ $btn.removeClass('disabled');
- this.$buttons.attr('data-status', newStatus);
- this.$buttons.find('> span').text(newAction);
+ this.$buttons.attr('data-status', newStatus);
+ this.$buttons.find('> span').text(newAction);
- this.$buttons.map((button) => {
- const $button = $(button);
+ this.$buttons.map((button) => {
+ const $button = $(button);
- if ($button.attr('data-original-title')) {
- $button.tooltip('hide').attr('data-original-title', newAction).tooltip('fixTitle');
- }
+ if ($button.attr('data-original-title')) {
+ $button.tooltip('hide').attr('data-original-title', newAction).tooltip('fixTitle');
+ }
- return button;
- });
+ return button;
});
- }
+ });
}
+}
- global.ProjectLabelSubscription = ProjectLabelSubscription;
-})(window.gl || (window.gl = {}));
+global.ProjectLabelSubscription = ProjectLabelSubscription;
diff --git a/app/assets/javascripts/project_new.js b/app/assets/javascripts/project_new.js
index fd89a1a85c3..a015ff58411 100644
--- a/app/assets/javascripts/project_new.js
+++ b/app/assets/javascripts/project_new.js
@@ -7,153 +7,149 @@ function highlightChanges($elm) {
setTimeout(() => $elm.removeClass('highlight-changes'), 10);
}
-(function() {
- this.ProjectNew = (function() {
- function ProjectNew() {
- this.toggleSettings = this.toggleSettings.bind(this);
- this.$selects = $('.features select');
- this.$repoSelects = this.$selects.filter('.js-repo-select');
- this.$projectSelects = this.$selects.not('.js-repo-select');
-
- $('.project-edit-container').on('ajax:before', (function(_this) {
- return function() {
- $('.project-edit-container').hide();
- return $('.save-project-loader').show();
- };
- })(this));
-
- this.initVisibilitySelect();
-
- this.toggleSettings();
- this.toggleSettingsOnclick();
- this.toggleRepoVisibility();
- }
+function ProjectNew() {
+ this.toggleSettings = this.toggleSettings.bind(this);
+ this.$selects = $('.features select');
+ this.$repoSelects = this.$selects.filter('.js-repo-select');
+ this.$projectSelects = this.$selects.not('.js-repo-select');
+
+ $('.project-edit-container').on('ajax:before', (function(_this) {
+ return function() {
+ $('.project-edit-container').hide();
+ return $('.save-project-loader').show();
+ };
+ })(this));
+
+ this.initVisibilitySelect();
+
+ this.toggleSettings();
+ this.toggleSettingsOnclick();
+ this.toggleRepoVisibility();
+}
+
+ProjectNew.prototype.initVisibilitySelect = function() {
+ const visibilityContainer = document.querySelector('.js-visibility-select');
+ if (!visibilityContainer) return;
+ const visibilitySelect = new VisibilitySelect(visibilityContainer);
+ visibilitySelect.init();
+
+ const $visibilitySelect = $(visibilityContainer).find('select');
+ let projectVisibility = $visibilitySelect.val();
+ const PROJECT_VISIBILITY_PRIVATE = '0';
+
+ $visibilitySelect.on('change', () => {
+ const newProjectVisibility = $visibilitySelect.val();
+
+ if (projectVisibility !== newProjectVisibility) {
+ this.$projectSelects.each((idx, select) => {
+ const $select = $(select);
+ const $options = $select.find('option');
+ const values = $.map($options, e => e.value);
+
+ // if switched to "private", limit visibility options
+ if (newProjectVisibility === PROJECT_VISIBILITY_PRIVATE) {
+ if ($select.val() !== values[0] && $select.val() !== values[1]) {
+ $select.val(values[1]).trigger('change');
+ highlightChanges($select);
+ }
+ $options.slice(2).disable();
+ }
- ProjectNew.prototype.initVisibilitySelect = function() {
- const visibilityContainer = document.querySelector('.js-visibility-select');
- if (!visibilityContainer) return;
- const visibilitySelect = new VisibilitySelect(visibilityContainer);
- visibilitySelect.init();
-
- const $visibilitySelect = $(visibilityContainer).find('select');
- let projectVisibility = $visibilitySelect.val();
- const PROJECT_VISIBILITY_PRIVATE = '0';
-
- $visibilitySelect.on('change', () => {
- const newProjectVisibility = $visibilitySelect.val();
-
- if (projectVisibility !== newProjectVisibility) {
- this.$projectSelects.each((idx, select) => {
- const $select = $(select);
- const $options = $select.find('option');
- const values = $.map($options, e => e.value);
-
- // if switched to "private", limit visibility options
- if (newProjectVisibility === PROJECT_VISIBILITY_PRIVATE) {
- if ($select.val() !== values[0] && $select.val() !== values[1]) {
- $select.val(values[1]).trigger('change');
- highlightChanges($select);
- }
- $options.slice(2).disable();
- }
-
- // if switched from "private", increase visibility for non-disabled options
- if (projectVisibility === PROJECT_VISIBILITY_PRIVATE) {
- $options.enable();
- if ($select.val() !== values[0] && $select.val() !== values[values.length - 1]) {
- $select.val(values[values.length - 1]).trigger('change');
- highlightChanges($select);
- }
- }
- });
-
- projectVisibility = newProjectVisibility;
+ // if switched from "private", increase visibility for non-disabled options
+ if (projectVisibility === PROJECT_VISIBILITY_PRIVATE) {
+ $options.enable();
+ if ($select.val() !== values[0] && $select.val() !== values[values.length - 1]) {
+ $select.val(values[values.length - 1]).trigger('change');
+ highlightChanges($select);
+ }
}
});
- };
- ProjectNew.prototype.toggleSettings = function() {
- var self = this;
+ projectVisibility = newProjectVisibility;
+ }
+ });
+};
+
+ProjectNew.prototype.toggleSettings = function() {
+ var self = this;
+
+ this.$selects.each(function () {
+ var $select = $(this);
+ var className = $select.data('field')
+ .replace(/_/g, '-')
+ .replace('access-level', 'feature');
+ self._showOrHide($select, '.' + className);
+ });
+};
+
+ProjectNew.prototype.toggleSettingsOnclick = function() {
+ this.$selects.on('change', this.toggleSettings);
+};
+
+ProjectNew.prototype._showOrHide = function(checkElement, container) {
+ var $container = $(container);
+
+ if ($(checkElement).val() !== '0') {
+ return $container.show();
+ } else {
+ return $container.hide();
+ }
+};
+
+ProjectNew.prototype.toggleRepoVisibility = function () {
+ var $repoAccessLevel = $('.js-repo-access-level select');
+ var $lfsEnabledOption = $('.js-lfs-enabled select');
+ var containerRegistry = document.querySelectorAll('.js-container-registry')[0];
+ var containerRegistryCheckbox = document.getElementById('project_container_registry_enabled');
+ var prevSelectedVal = parseInt($repoAccessLevel.val(), 10);
+
+ this.$repoSelects.find("option[value='" + $repoAccessLevel.val() + "']")
+ .nextAll()
+ .hide();
+
+ $repoAccessLevel.off('change')
+ .on('change', function () {
+ var selectedVal = parseInt($repoAccessLevel.val(), 10);
+
+ this.$repoSelects.each(function () {
+ var $this = $(this);
+ var repoSelectVal = parseInt($this.val(), 10);
+
+ $this.find('option').enable();
+
+ if (selectedVal < repoSelectVal || repoSelectVal === prevSelectedVal) {
+ $this.val(selectedVal).trigger('change');
+ highlightChanges($this);
+ }
- this.$selects.each(function () {
- var $select = $(this);
- var className = $select.data('field')
- .replace(/_/g, '-')
- .replace('access-level', 'feature');
- self._showOrHide($select, '.' + className);
+ $this.find("option[value='" + selectedVal + "']").nextAll().disable();
});
- };
-
- ProjectNew.prototype.toggleSettingsOnclick = function() {
- this.$selects.on('change', this.toggleSettings);
- };
- ProjectNew.prototype._showOrHide = function(checkElement, container) {
- var $container = $(container);
+ if (selectedVal) {
+ this.$repoSelects.removeClass('disabled');
- if ($(checkElement).val() !== '0') {
- return $container.show();
+ if ($lfsEnabledOption.length) {
+ $lfsEnabledOption.removeClass('disabled');
+ highlightChanges($lfsEnabledOption);
+ }
+ if (containerRegistry) {
+ containerRegistry.style.display = '';
+ }
} else {
- return $container.hide();
- }
- };
+ this.$repoSelects.addClass('disabled');
- ProjectNew.prototype.toggleRepoVisibility = function () {
- var $repoAccessLevel = $('.js-repo-access-level select');
- var $lfsEnabledOption = $('.js-lfs-enabled select');
- var containerRegistry = document.querySelectorAll('.js-container-registry')[0];
- var containerRegistryCheckbox = document.getElementById('project_container_registry_enabled');
- var prevSelectedVal = parseInt($repoAccessLevel.val(), 10);
-
- this.$repoSelects.find("option[value='" + $repoAccessLevel.val() + "']")
- .nextAll()
- .hide();
-
- $repoAccessLevel.off('change')
- .on('change', function () {
- var selectedVal = parseInt($repoAccessLevel.val(), 10);
-
- this.$repoSelects.each(function () {
- var $this = $(this);
- var repoSelectVal = parseInt($this.val(), 10);
-
- $this.find('option').enable();
-
- if (selectedVal < repoSelectVal || repoSelectVal === prevSelectedVal) {
- $this.val(selectedVal).trigger('change');
- highlightChanges($this);
- }
-
- $this.find("option[value='" + selectedVal + "']").nextAll().disable();
- });
-
- if (selectedVal) {
- this.$repoSelects.removeClass('disabled');
-
- if ($lfsEnabledOption.length) {
- $lfsEnabledOption.removeClass('disabled');
- highlightChanges($lfsEnabledOption);
- }
- if (containerRegistry) {
- containerRegistry.style.display = '';
- }
- } else {
- this.$repoSelects.addClass('disabled');
-
- if ($lfsEnabledOption.length) {
- $lfsEnabledOption.val('false').addClass('disabled');
- highlightChanges($lfsEnabledOption);
- }
- if (containerRegistry) {
- containerRegistry.style.display = 'none';
- containerRegistryCheckbox.checked = false;
- }
- }
+ if ($lfsEnabledOption.length) {
+ $lfsEnabledOption.val('false').addClass('disabled');
+ highlightChanges($lfsEnabledOption);
+ }
+ if (containerRegistry) {
+ containerRegistry.style.display = 'none';
+ containerRegistryCheckbox.checked = false;
+ }
+ }
- prevSelectedVal = selectedVal;
- }.bind(this));
- };
+ prevSelectedVal = selectedVal;
+ }.bind(this));
+};
- return ProjectNew;
- })();
-}).call(window);
+window.ProjectNew = ProjectNew;
diff --git a/app/assets/javascripts/project_select.js b/app/assets/javascripts/project_select.js
index 9896b88d487..c46182126f9 100644
--- a/app/assets/javascripts/project_select.js
+++ b/app/assets/javascripts/project_select.js
@@ -1,111 +1,105 @@
/* eslint-disable func-names, space-before-function-paren, wrap-iife, prefer-arrow-callback, no-var, comma-dangle, object-shorthand, one-var, one-var-declaration-per-line, no-else-return, quotes, max-len */
import Api from './api';
-(function() {
- this.ProjectSelect = (function() {
- function ProjectSelect() {
- $('.js-projects-dropdown-toggle').each(function(i, dropdown) {
- var $dropdown;
- $dropdown = $(dropdown);
- return $dropdown.glDropdown({
- filterable: true,
- filterRemote: true,
- search: {
- fields: ['name_with_namespace']
- },
- data: function(term, callback) {
- var finalCallback, projectsCallback;
- var orderBy = $dropdown.data('order-by');
- finalCallback = function(projects) {
- return callback(projects);
+function ProjectSelect() {
+ $('.js-projects-dropdown-toggle').each(function(i, dropdown) {
+ var $dropdown;
+ $dropdown = $(dropdown);
+ return $dropdown.glDropdown({
+ filterable: true,
+ filterRemote: true,
+ search: {
+ fields: ['name_with_namespace']
+ },
+ data: function(term, callback) {
+ var finalCallback, projectsCallback;
+ var orderBy = $dropdown.data('order-by');
+ finalCallback = function(projects) {
+ return callback(projects);
+ };
+ if (this.includeGroups) {
+ projectsCallback = function(projects) {
+ var groupsCallback;
+ groupsCallback = function(groups) {
+ var data;
+ data = groups.concat(projects);
+ return finalCallback(data);
};
- if (this.includeGroups) {
- projectsCallback = function(projects) {
- var groupsCallback;
- groupsCallback = function(groups) {
- var data;
- data = groups.concat(projects);
- return finalCallback(data);
- };
- return Api.groups(term, {}, groupsCallback);
- };
- } else {
- projectsCallback = finalCallback;
- }
- if (this.groupId) {
- return Api.groupProjects(this.groupId, term, projectsCallback);
- } else {
- return Api.projects(term, { order_by: orderBy }, projectsCallback);
- }
- },
- url: function(project) {
- return project.web_url;
- },
- text: function(project) {
- return project.name_with_namespace;
- }
- });
- });
- $('.ajax-project-select').each(function(i, select) {
- var placeholder;
- this.groupId = $(select).data('group-id');
- this.includeGroups = $(select).data('include-groups');
- this.orderBy = $(select).data('order-by') || 'id';
- this.withIssuesEnabled = $(select).data('with-issues-enabled');
- this.withMergeRequestsEnabled = $(select).data('with-merge-requests-enabled');
+ return Api.groups(term, {}, groupsCallback);
+ };
+ } else {
+ projectsCallback = finalCallback;
+ }
+ if (this.groupId) {
+ return Api.groupProjects(this.groupId, term, projectsCallback);
+ } else {
+ return Api.projects(term, { order_by: orderBy }, projectsCallback);
+ }
+ },
+ url: function(project) {
+ return project.web_url;
+ },
+ text: function(project) {
+ return project.name_with_namespace;
+ }
+ });
+ });
+ $('.ajax-project-select').each(function(i, select) {
+ var placeholder;
+ this.groupId = $(select).data('group-id');
+ this.includeGroups = $(select).data('include-groups');
+ this.orderBy = $(select).data('order-by') || 'id';
+ this.withIssuesEnabled = $(select).data('with-issues-enabled');
+ this.withMergeRequestsEnabled = $(select).data('with-merge-requests-enabled');
- placeholder = "Search for project";
+ placeholder = "Search for project";
+ if (this.includeGroups) {
+ placeholder += " or group";
+ }
+ return $(select).select2({
+ placeholder: placeholder,
+ minimumInputLength: 0,
+ query: (query) => {
+ var finalCallback, projectsCallback;
+ finalCallback = function(projects) {
+ var data;
+ data = {
+ results: projects
+ };
+ return query.callback(data);
+ };
if (this.includeGroups) {
- placeholder += " or group";
- }
- return $(select).select2({
- placeholder: placeholder,
- minimumInputLength: 0,
- query: (function(_this) {
- return function(query) {
- var finalCallback, projectsCallback;
- finalCallback = function(projects) {
- var data;
- data = {
- results: projects
- };
- return query.callback(data);
- };
- if (_this.includeGroups) {
- projectsCallback = function(projects) {
- var groupsCallback;
- groupsCallback = function(groups) {
- var data;
- data = groups.concat(projects);
- return finalCallback(data);
- };
- return Api.groups(query.term, {}, groupsCallback);
- };
- } else {
- projectsCallback = finalCallback;
- }
- if (_this.groupId) {
- return Api.groupProjects(_this.groupId, query.term, projectsCallback);
- } else {
- return Api.projects(query.term, {
- order_by: _this.orderBy,
- with_issues_enabled: _this.withIssuesEnabled,
- with_merge_requests_enabled: _this.withMergeRequestsEnabled
- }, projectsCallback);
- }
+ projectsCallback = function(projects) {
+ var groupsCallback;
+ groupsCallback = function(groups) {
+ var data;
+ data = groups.concat(projects);
+ return finalCallback(data);
};
- })(this),
- id: function(project) {
- return project.web_url;
- },
- text: function(project) {
- return project.name_with_namespace || project.name;
- },
- dropdownCssClass: "ajax-project-dropdown"
- });
- });
- }
+ return Api.groups(query.term, {}, groupsCallback);
+ };
+ } else {
+ projectsCallback = finalCallback;
+ }
+ if (this.groupId) {
+ return Api.groupProjects(this.groupId, query.term, projectsCallback);
+ } else {
+ return Api.projects(query.term, {
+ order_by: this.orderBy,
+ with_issues_enabled: this.withIssuesEnabled,
+ with_merge_requests_enabled: this.withMergeRequestsEnabled
+ }, projectsCallback);
+ }
+ },
+ id: function(project) {
+ return project.web_url;
+ },
+ text: function(project) {
+ return project.name_with_namespace || project.name;
+ },
+ dropdownCssClass: "ajax-project-dropdown"
+ });
+ });
+}
- return ProjectSelect;
- })();
-}).call(window);
+window.ProjectSelect = ProjectSelect;
diff --git a/app/assets/javascripts/project_show.js b/app/assets/javascripts/project_show.js
index 3a51c1f26ac..ff1a923a982 100644
--- a/app/assets/javascripts/project_show.js
+++ b/app/assets/javascripts/project_show.js
@@ -1,11 +1,6 @@
/* eslint-disable func-names, space-before-function-paren, wrap-iife */
-(function() {
- this.ProjectShow = (function() {
- function ProjectShow() {}
-
- return ProjectShow;
- })();
-}).call(window);
-
// I kept class for future
+function ProjectShow() {}
+
+window.ProjectShow = ProjectShow;
diff --git a/app/assets/javascripts/project_variables.js b/app/assets/javascripts/project_variables.js
index 4ee2e49306d..5688ed7ebb3 100644
--- a/app/assets/javascripts/project_variables.js
+++ b/app/assets/javascripts/project_variables.js
@@ -1,43 +1,41 @@
-(() => {
- const HIDDEN_VALUE_TEXT = '******';
+const HIDDEN_VALUE_TEXT = '******';
- class ProjectVariables {
- constructor() {
- this.$revealBtn = $('.js-btn-toggle-reveal-values');
- this.$revealBtn.on('click', this.toggleRevealState.bind(this));
- }
+class ProjectVariables {
+ constructor() {
+ this.$revealBtn = $('.js-btn-toggle-reveal-values');
+ this.$revealBtn.on('click', this.toggleRevealState.bind(this));
+ }
- toggleRevealState(e) {
- e.preventDefault();
+ toggleRevealState(e) {
+ e.preventDefault();
- const oldStatus = this.$revealBtn.attr('data-status');
- let newStatus = 'hidden';
- let newAction = 'Reveal Values';
+ const oldStatus = this.$revealBtn.attr('data-status');
+ let newStatus = 'hidden';
+ let newAction = 'Reveal Values';
- if (oldStatus === 'hidden') {
- newStatus = 'revealed';
- newAction = 'Hide Values';
- }
+ if (oldStatus === 'hidden') {
+ newStatus = 'revealed';
+ newAction = 'Hide Values';
+ }
- this.$revealBtn.attr('data-status', newStatus);
+ this.$revealBtn.attr('data-status', newStatus);
- const $variables = $('.variable-value');
+ const $variables = $('.variable-value');
- $variables.each((_, variable) => {
- const $variable = $(variable);
- let newText = HIDDEN_VALUE_TEXT;
+ $variables.each((_, variable) => {
+ const $variable = $(variable);
+ let newText = HIDDEN_VALUE_TEXT;
- if (newStatus === 'revealed') {
- newText = $variable.attr('data-value');
- }
+ if (newStatus === 'revealed') {
+ newText = $variable.attr('data-value');
+ }
- $variable.text(newText);
- });
+ $variable.text(newText);
+ });
- this.$revealBtn.text(newAction);
- }
+ this.$revealBtn.text(newAction);
}
+}
- window.gl = window.gl || {};
- window.gl.ProjectVariables = ProjectVariables;
-})();
+window.gl = window.gl || {};
+window.gl.ProjectVariables = ProjectVariables;
diff --git a/app/assets/javascripts/render_gfm.js b/app/assets/javascripts/render_gfm.js
index 2c3a9cacd38..d57486e2434 100644
--- a/app/assets/javascripts/render_gfm.js
+++ b/app/assets/javascripts/render_gfm.js
@@ -4,14 +4,12 @@
//
// Delegates to syntax highlight and render math
//
-(function() {
- $.fn.renderGFM = function() {
- this.find('.js-syntax-highlight').syntaxHighlight();
- this.find('.js-render-math').renderMath();
- return this;
- };
+$.fn.renderGFM = function() {
+ this.find('.js-syntax-highlight').syntaxHighlight();
+ this.find('.js-render-math').renderMath();
+ return this;
+};
- $(document).on('ready load', function() {
- return $('body').renderGFM();
- });
-}).call(window);
+$(document).on('ready load', function() {
+ return $('body').renderGFM();
+});
diff --git a/app/assets/javascripts/render_math.js b/app/assets/javascripts/render_math.js
index 8b3fee49cb9..1596cbe266f 100644
--- a/app/assets/javascripts/render_math.js
+++ b/app/assets/javascripts/render_math.js
@@ -8,49 +8,47 @@
//
// <code class="js-render-math"></div>
//
-(function() {
- // Only load once
- var katexLoaded = false;
+// Only load once
+var katexLoaded = false;
- // Loop over all math elements and render math
- var renderWithKaTeX = function (elements) {
- elements.each(function () {
- var mathNode = $('<span></span>');
- var $this = $(this);
+// Loop over all math elements and render math
+var renderWithKaTeX = function (elements) {
+ elements.each(function () {
+ var mathNode = $('<span></span>');
+ var $this = $(this);
- var display = $this.attr('data-math-style') === 'display';
- try {
- katex.render($this.text(), mathNode.get(0), { displayMode: display });
- mathNode.insertAfter($this);
- $this.remove();
- } catch (err) {
- // What can we do??
- console.log(err.message);
- }
- });
- };
-
- $.fn.renderMath = function() {
- var $this = this;
- if ($this.length === 0) return;
+ var display = $this.attr('data-math-style') === 'display';
+ try {
+ katex.render($this.text(), mathNode.get(0), { displayMode: display });
+ mathNode.insertAfter($this);
+ $this.remove();
+ } catch (err) {
+ // What can we do??
+ console.log(err.message);
+ }
+ });
+};
- if (katexLoaded) renderWithKaTeX($this);
- else {
- // Request CSS file so it is in the cache
- $.get(gon.katex_css_url, function() {
- var css = $('<link>',
- { rel: 'stylesheet',
- type: 'text/css',
- href: gon.katex_css_url,
- });
- css.appendTo('head');
+$.fn.renderMath = function() {
+ var $this = this;
+ if ($this.length === 0) return;
- // Load KaTeX js
- $.getScript(gon.katex_js_url, function() {
- katexLoaded = true;
- renderWithKaTeX($this); // Run KaTeX
+ if (katexLoaded) renderWithKaTeX($this);
+ else {
+ // Request CSS file so it is in the cache
+ $.get(gon.katex_css_url, function() {
+ var css = $('<link>',
+ { rel: 'stylesheet',
+ type: 'text/css',
+ href: gon.katex_css_url,
});
+ css.appendTo('head');
+
+ // Load KaTeX js
+ $.getScript(gon.katex_js_url, function() {
+ katexLoaded = true;
+ renderWithKaTeX($this); // Run KaTeX
});
- }
- };
-}).call(window);
+ });
+ }
+};
diff --git a/app/assets/javascripts/right_sidebar.js b/app/assets/javascripts/right_sidebar.js
index d8f1fe10b26..9b16e4cd613 100644
--- a/app/assets/javascripts/right_sidebar.js
+++ b/app/assets/javascripts/right_sidebar.js
@@ -3,218 +3,214 @@
import Cookies from 'js-cookie';
import SidebarHeightManager from './sidebar_height_manager';
-(function() {
- this.Sidebar = (function() {
- function Sidebar(currentUser) {
- this.toggleTodo = this.toggleTodo.bind(this);
- this.sidebar = $('aside');
-
- this.removeListeners();
- this.addEventListeners();
+function Sidebar(currentUser) {
+ this.toggleTodo = this.toggleTodo.bind(this);
+ this.sidebar = $('aside');
+
+ this.removeListeners();
+ this.addEventListeners();
+}
+
+Sidebar.prototype.removeListeners = function () {
+ this.sidebar.off('click', '.sidebar-collapsed-icon');
+ $('.dropdown').off('hidden.gl.dropdown');
+ $('.dropdown').off('loading.gl.dropdown');
+ $('.dropdown').off('loaded.gl.dropdown');
+ $(document).off('click', '.js-sidebar-toggle');
+};
+
+Sidebar.prototype.addEventListeners = function() {
+ SidebarHeightManager.init();
+ const $document = $(document);
+
+ this.sidebar.on('click', '.sidebar-collapsed-icon', this, this.sidebarCollapseClicked);
+ $('.dropdown').on('hidden.gl.dropdown', this, this.onSidebarDropdownHidden);
+ $('.dropdown').on('loading.gl.dropdown', this.sidebarDropdownLoading);
+ $('.dropdown').on('loaded.gl.dropdown', this.sidebarDropdownLoaded);
+
+ $document.on('click', '.js-sidebar-toggle', function(e, triggered) {
+ var $allGutterToggleIcons, $this, $thisIcon;
+ e.preventDefault();
+ $this = $(this);
+ $thisIcon = $this.find('i');
+ $allGutterToggleIcons = $('.js-sidebar-toggle i');
+ if ($thisIcon.hasClass('fa-angle-double-right')) {
+ $allGutterToggleIcons.removeClass('fa-angle-double-right').addClass('fa-angle-double-left');
+ $('aside.right-sidebar').removeClass('right-sidebar-expanded').addClass('right-sidebar-collapsed');
+ $('.page-with-sidebar').removeClass('right-sidebar-expanded').addClass('right-sidebar-collapsed');
+ } else {
+ $allGutterToggleIcons.removeClass('fa-angle-double-left').addClass('fa-angle-double-right');
+ $('aside.right-sidebar').removeClass('right-sidebar-collapsed').addClass('right-sidebar-expanded');
+ $('.page-with-sidebar').removeClass('right-sidebar-collapsed').addClass('right-sidebar-expanded');
}
-
- Sidebar.prototype.removeListeners = function () {
- this.sidebar.off('click', '.sidebar-collapsed-icon');
- $('.dropdown').off('hidden.gl.dropdown');
- $('.dropdown').off('loading.gl.dropdown');
- $('.dropdown').off('loaded.gl.dropdown');
- $(document).off('click', '.js-sidebar-toggle');
- };
-
- Sidebar.prototype.addEventListeners = function() {
- SidebarHeightManager.init();
- const $document = $(document);
-
- this.sidebar.on('click', '.sidebar-collapsed-icon', this, this.sidebarCollapseClicked);
- $('.dropdown').on('hidden.gl.dropdown', this, this.onSidebarDropdownHidden);
- $('.dropdown').on('loading.gl.dropdown', this.sidebarDropdownLoading);
- $('.dropdown').on('loaded.gl.dropdown', this.sidebarDropdownLoaded);
-
- $document.on('click', '.js-sidebar-toggle', function(e, triggered) {
- var $allGutterToggleIcons, $this, $thisIcon;
- e.preventDefault();
- $this = $(this);
- $thisIcon = $this.find('i');
- $allGutterToggleIcons = $('.js-sidebar-toggle i');
- if ($thisIcon.hasClass('fa-angle-double-right')) {
- $allGutterToggleIcons.removeClass('fa-angle-double-right').addClass('fa-angle-double-left');
- $('aside.right-sidebar').removeClass('right-sidebar-expanded').addClass('right-sidebar-collapsed');
- $('.page-with-sidebar').removeClass('right-sidebar-expanded').addClass('right-sidebar-collapsed');
- } else {
- $allGutterToggleIcons.removeClass('fa-angle-double-left').addClass('fa-angle-double-right');
- $('aside.right-sidebar').removeClass('right-sidebar-collapsed').addClass('right-sidebar-expanded');
- $('.page-with-sidebar').removeClass('right-sidebar-collapsed').addClass('right-sidebar-expanded');
- }
- if (!triggered) {
- return Cookies.set("collapsed_gutter", $('.right-sidebar').hasClass('right-sidebar-collapsed'));
- }
- });
- return $(document).off('click', '.js-issuable-todo').on('click', '.js-issuable-todo', this.toggleTodo);
- };
-
- Sidebar.prototype.toggleTodo = function(e) {
- var $btnText, $this, $todoLoading, ajaxType, url;
- $this = $(e.currentTarget);
- ajaxType = $this.attr('data-delete-path') ? 'DELETE' : 'POST';
- if ($this.attr('data-delete-path')) {
- url = "" + ($this.attr('data-delete-path'));
- } else {
- url = "" + ($this.data('url'));
- }
-
- $this.tooltip('hide');
-
- return $.ajax({
- url: url,
- type: ajaxType,
- dataType: 'json',
- data: {
- issuable_id: $this.data('issuable-id'),
- issuable_type: $this.data('issuable-type')
- },
- beforeSend: (function(_this) {
- return function() {
- $('.js-issuable-todo').disable()
- .addClass('is-loading');
- };
- })(this)
- }).done((function(_this) {
- return function(data) {
- return _this.todoUpdateDone(data);
- };
- })(this));
- };
-
- Sidebar.prototype.todoUpdateDone = function(data) {
- const deletePath = data.delete_path ? data.delete_path : null;
- const attrPrefix = deletePath ? 'mark' : 'todo';
- const $todoBtns = $('.js-issuable-todo');
-
- $(document).trigger('todo:toggle', data.count);
-
- $todoBtns.each((i, el) => {
- const $el = $(el);
- const $elText = $el.find('.js-issuable-todo-inner');
-
- $el.removeClass('is-loading')
- .enable()
- .attr('aria-label', $el.data(`${attrPrefix}-text`))
- .attr('data-delete-path', deletePath)
- .attr('title', $el.data(`${attrPrefix}-text`));
-
- if ($el.hasClass('has-tooltip')) {
- $el.tooltip('fixTitle');
- }
-
- if ($el.data(`${attrPrefix}-icon`)) {
- $elText.html($el.data(`${attrPrefix}-icon`));
- } else {
- $elText.text($el.data(`${attrPrefix}-text`));
- }
- });
- };
-
- Sidebar.prototype.sidebarDropdownLoading = function(e) {
- var $loading, $sidebarCollapsedIcon, i, img;
- $sidebarCollapsedIcon = $(this).closest('.block').find('.sidebar-collapsed-icon');
- img = $sidebarCollapsedIcon.find('img');
- i = $sidebarCollapsedIcon.find('i');
- $loading = $('<i class="fa fa-spinner fa-spin"></i>');
- if (img.length) {
- img.before($loading);
- return img.hide();
- } else if (i.length) {
- i.before($loading);
- return i.hide();
- }
- };
-
- Sidebar.prototype.sidebarDropdownLoaded = function(e) {
- var $sidebarCollapsedIcon, i, img;
- $sidebarCollapsedIcon = $(this).closest('.block').find('.sidebar-collapsed-icon');
- img = $sidebarCollapsedIcon.find('img');
- $sidebarCollapsedIcon.find('i.fa-spin').remove();
- i = $sidebarCollapsedIcon.find('i');
- if (img.length) {
- return img.show();
- } else {
- return i.show();
- }
- };
-
- Sidebar.prototype.sidebarCollapseClicked = function(e) {
- var $block, sidebar;
- if ($(e.currentTarget).hasClass('dont-change-state')) {
- return;
- }
- sidebar = e.data;
- e.preventDefault();
- $block = $(this).closest('.block');
- return sidebar.openDropdown($block);
+ if (!triggered) {
+ return Cookies.set("collapsed_gutter", $('.right-sidebar').hasClass('right-sidebar-collapsed'));
+ }
+ });
+ return $(document).off('click', '.js-issuable-todo').on('click', '.js-issuable-todo', this.toggleTodo);
+};
+
+Sidebar.prototype.toggleTodo = function(e) {
+ var $btnText, $this, $todoLoading, ajaxType, url;
+ $this = $(e.currentTarget);
+ ajaxType = $this.attr('data-delete-path') ? 'DELETE' : 'POST';
+ if ($this.attr('data-delete-path')) {
+ url = "" + ($this.attr('data-delete-path'));
+ } else {
+ url = "" + ($this.data('url'));
+ }
+
+ $this.tooltip('hide');
+
+ return $.ajax({
+ url: url,
+ type: ajaxType,
+ dataType: 'json',
+ data: {
+ issuable_id: $this.data('issuable-id'),
+ issuable_type: $this.data('issuable-type')
+ },
+ beforeSend: (function(_this) {
+ return function() {
+ $('.js-issuable-todo').disable()
+ .addClass('is-loading');
+ };
+ })(this)
+ }).done((function(_this) {
+ return function(data) {
+ return _this.todoUpdateDone(data);
};
+ })(this));
+};
- Sidebar.prototype.openDropdown = function(blockOrName) {
- var $block;
- $block = _.isString(blockOrName) ? this.getBlock(blockOrName) : blockOrName;
- $block.find('.edit-link').trigger('click');
- if (!this.isOpen()) {
- this.setCollapseAfterUpdate($block);
- return this.toggleSidebar('open');
- }
- };
+Sidebar.prototype.todoUpdateDone = function(data) {
+ const deletePath = data.delete_path ? data.delete_path : null;
+ const attrPrefix = deletePath ? 'mark' : 'todo';
+ const $todoBtns = $('.js-issuable-todo');
- Sidebar.prototype.setCollapseAfterUpdate = function($block) {
- $block.addClass('collapse-after-update');
- return $('.page-with-sidebar').addClass('with-overlay');
- };
+ $(document).trigger('todo:toggle', data.count);
- Sidebar.prototype.onSidebarDropdownHidden = function(e) {
- var $block, sidebar;
- sidebar = e.data;
- e.preventDefault();
- $block = $(this).closest('.block');
- return sidebar.sidebarDropdownHidden($block);
- };
+ $todoBtns.each((i, el) => {
+ const $el = $(el);
+ const $elText = $el.find('.js-issuable-todo-inner');
- Sidebar.prototype.sidebarDropdownHidden = function($block) {
- if ($block.hasClass('collapse-after-update')) {
- $block.removeClass('collapse-after-update');
- $('.page-with-sidebar').removeClass('with-overlay');
- return this.toggleSidebar('hide');
- }
- };
+ $el.removeClass('is-loading')
+ .enable()
+ .attr('aria-label', $el.data(`${attrPrefix}-text`))
+ .attr('data-delete-path', deletePath)
+ .attr('title', $el.data(`${attrPrefix}-text`));
- Sidebar.prototype.triggerOpenSidebar = function() {
- return this.sidebar.find('.js-sidebar-toggle').trigger('click');
- };
+ if ($el.hasClass('has-tooltip')) {
+ $el.tooltip('fixTitle');
+ }
- Sidebar.prototype.toggleSidebar = function(action) {
- if (action == null) {
- action = 'toggle';
- }
- if (action === 'toggle') {
- this.triggerOpenSidebar();
- }
- if (action === 'open') {
- if (!this.isOpen()) {
- this.triggerOpenSidebar();
- }
- }
- if (action === 'hide') {
- if (this.isOpen()) {
- return this.triggerOpenSidebar();
- }
- }
- };
+ if ($el.data(`${attrPrefix}-icon`)) {
+ $elText.html($el.data(`${attrPrefix}-icon`));
+ } else {
+ $elText.text($el.data(`${attrPrefix}-text`));
+ }
+ });
+};
+
+Sidebar.prototype.sidebarDropdownLoading = function(e) {
+ var $loading, $sidebarCollapsedIcon, i, img;
+ $sidebarCollapsedIcon = $(this).closest('.block').find('.sidebar-collapsed-icon');
+ img = $sidebarCollapsedIcon.find('img');
+ i = $sidebarCollapsedIcon.find('i');
+ $loading = $('<i class="fa fa-spinner fa-spin"></i>');
+ if (img.length) {
+ img.before($loading);
+ return img.hide();
+ } else if (i.length) {
+ i.before($loading);
+ return i.hide();
+ }
+};
+
+Sidebar.prototype.sidebarDropdownLoaded = function(e) {
+ var $sidebarCollapsedIcon, i, img;
+ $sidebarCollapsedIcon = $(this).closest('.block').find('.sidebar-collapsed-icon');
+ img = $sidebarCollapsedIcon.find('img');
+ $sidebarCollapsedIcon.find('i.fa-spin').remove();
+ i = $sidebarCollapsedIcon.find('i');
+ if (img.length) {
+ return img.show();
+ } else {
+ return i.show();
+ }
+};
+
+Sidebar.prototype.sidebarCollapseClicked = function(e) {
+ var $block, sidebar;
+ if ($(e.currentTarget).hasClass('dont-change-state')) {
+ return;
+ }
+ sidebar = e.data;
+ e.preventDefault();
+ $block = $(this).closest('.block');
+ return sidebar.openDropdown($block);
+};
+
+Sidebar.prototype.openDropdown = function(blockOrName) {
+ var $block;
+ $block = _.isString(blockOrName) ? this.getBlock(blockOrName) : blockOrName;
+ $block.find('.edit-link').trigger('click');
+ if (!this.isOpen()) {
+ this.setCollapseAfterUpdate($block);
+ return this.toggleSidebar('open');
+ }
+};
+
+Sidebar.prototype.setCollapseAfterUpdate = function($block) {
+ $block.addClass('collapse-after-update');
+ return $('.page-with-sidebar').addClass('with-overlay');
+};
+
+Sidebar.prototype.onSidebarDropdownHidden = function(e) {
+ var $block, sidebar;
+ sidebar = e.data;
+ e.preventDefault();
+ $block = $(this).closest('.block');
+ return sidebar.sidebarDropdownHidden($block);
+};
+
+Sidebar.prototype.sidebarDropdownHidden = function($block) {
+ if ($block.hasClass('collapse-after-update')) {
+ $block.removeClass('collapse-after-update');
+ $('.page-with-sidebar').removeClass('with-overlay');
+ return this.toggleSidebar('hide');
+ }
+};
+
+Sidebar.prototype.triggerOpenSidebar = function() {
+ return this.sidebar.find('.js-sidebar-toggle').trigger('click');
+};
+
+Sidebar.prototype.toggleSidebar = function(action) {
+ if (action == null) {
+ action = 'toggle';
+ }
+ if (action === 'toggle') {
+ this.triggerOpenSidebar();
+ }
+ if (action === 'open') {
+ if (!this.isOpen()) {
+ this.triggerOpenSidebar();
+ }
+ }
+ if (action === 'hide') {
+ if (this.isOpen()) {
+ return this.triggerOpenSidebar();
+ }
+ }
+};
- Sidebar.prototype.isOpen = function() {
- return this.sidebar.is('.right-sidebar-expanded');
- };
+Sidebar.prototype.isOpen = function() {
+ return this.sidebar.is('.right-sidebar-expanded');
+};
- Sidebar.prototype.getBlock = function(name) {
- return this.sidebar.find(".block." + name);
- };
+Sidebar.prototype.getBlock = function(name) {
+ return this.sidebar.find(".block." + name);
+};
- return Sidebar;
- })();
-}).call(window);
+window.Sidebar = Sidebar;
diff --git a/app/assets/javascripts/search.js b/app/assets/javascripts/search.js
index 05caf177aec..15b7add82c8 100644
--- a/app/assets/javascripts/search.js
+++ b/app/assets/javascripts/search.js
@@ -2,117 +2,113 @@
/* global Flash */
import Api from './api';
-(function() {
- this.Search = (function() {
- function Search() {
- var $groupDropdown, $projectDropdown;
- $groupDropdown = $('.js-search-group-dropdown');
- $projectDropdown = $('.js-search-project-dropdown');
- this.groupId = $groupDropdown.data('group-id');
- this.eventListeners();
- $groupDropdown.glDropdown({
- selectable: true,
- filterable: true,
- fieldName: 'group_id',
- search: {
- fields: ['full_name']
- },
- data: function(term, callback) {
- return Api.groups(term, {}, function(data) {
- data.unshift({
- full_name: 'Any'
- });
- data.splice(1, 0, 'divider');
- return callback(data);
- });
- },
- id: function(obj) {
- return obj.id;
- },
- text: function(obj) {
- return obj.full_name;
- },
- toggleLabel: function(obj) {
- return ($groupDropdown.data('default-label')) + " " + obj.full_name;
- },
- clicked: (function(_this) {
- return function() {
- return _this.submitSearch();
- };
- })(this)
+function Search() {
+ var $groupDropdown, $projectDropdown;
+ $groupDropdown = $('.js-search-group-dropdown');
+ $projectDropdown = $('.js-search-project-dropdown');
+ this.groupId = $groupDropdown.data('group-id');
+ this.eventListeners();
+ $groupDropdown.glDropdown({
+ selectable: true,
+ filterable: true,
+ fieldName: 'group_id',
+ search: {
+ fields: ['full_name']
+ },
+ data: function(term, callback) {
+ return Api.groups(term, {}, function(data) {
+ data.unshift({
+ full_name: 'Any'
+ });
+ data.splice(1, 0, 'divider');
+ return callback(data);
});
- $projectDropdown.glDropdown({
- selectable: true,
- filterable: true,
- fieldName: 'project_id',
- search: {
- fields: ['name']
- },
- data: (term, callback) => {
- this.getProjectsData(term)
- .then((data) => {
- data.unshift({
- name_with_namespace: 'Any'
- });
- data.splice(1, 0, 'divider');
+ },
+ id: function(obj) {
+ return obj.id;
+ },
+ text: function(obj) {
+ return obj.full_name;
+ },
+ toggleLabel: function(obj) {
+ return ($groupDropdown.data('default-label')) + " " + obj.full_name;
+ },
+ clicked: (function(_this) {
+ return function() {
+ return _this.submitSearch();
+ };
+ })(this)
+ });
+ $projectDropdown.glDropdown({
+ selectable: true,
+ filterable: true,
+ fieldName: 'project_id',
+ search: {
+ fields: ['name']
+ },
+ data: (term, callback) => {
+ this.getProjectsData(term)
+ .then((data) => {
+ data.unshift({
+ name_with_namespace: 'Any'
+ });
+ data.splice(1, 0, 'divider');
- return data;
- })
- .then(data => callback(data))
- .catch(() => new Flash('Error fetching projects'));
- },
- id: function(obj) {
- return obj.id;
- },
- text: function(obj) {
- return obj.name_with_namespace;
- },
- toggleLabel: function(obj) {
- return ($projectDropdown.data('default-label')) + " " + obj.name_with_namespace;
- },
- clicked: (function(_this) {
- return function() {
- return _this.submitSearch();
- };
- })(this)
- });
- }
+ return data;
+ })
+ .then(data => callback(data))
+ .catch(() => new Flash('Error fetching projects'));
+ },
+ id: function(obj) {
+ return obj.id;
+ },
+ text: function(obj) {
+ return obj.name_with_namespace;
+ },
+ toggleLabel: function(obj) {
+ return ($projectDropdown.data('default-label')) + " " + obj.name_with_namespace;
+ },
+ clicked: (function(_this) {
+ return function() {
+ return _this.submitSearch();
+ };
+ })(this)
+ });
+}
- Search.prototype.eventListeners = function() {
- $(document).off('keyup', '.js-search-input').on('keyup', '.js-search-input', this.searchKeyUp);
- return $(document).off('click', '.js-search-clear').on('click', '.js-search-clear', this.clearSearchField);
- };
+Search.prototype.eventListeners = function() {
+ $(document).off('keyup', '.js-search-input').on('keyup', '.js-search-input', this.searchKeyUp);
+ return $(document).off('click', '.js-search-clear').on('click', '.js-search-clear', this.clearSearchField);
+};
- Search.prototype.submitSearch = function() {
- return $('.js-search-form').submit();
- };
+Search.prototype.submitSearch = function() {
+ return $('.js-search-form').submit();
+};
- Search.prototype.searchKeyUp = function() {
- var $input;
- $input = $(this);
- if ($input.val() === '') {
- return $('.js-search-clear').addClass('hidden');
- } else {
- return $('.js-search-clear').removeClass('hidden');
- }
- };
+Search.prototype.searchKeyUp = function() {
+ var $input;
+ $input = $(this);
+ if ($input.val() === '') {
+ return $('.js-search-clear').addClass('hidden');
+ } else {
+ return $('.js-search-clear').removeClass('hidden');
+ }
+};
- Search.prototype.clearSearchField = function() {
- return $('.js-search-input').val('').trigger('keyup').focus();
- };
+Search.prototype.clearSearchField = function() {
+ return $('.js-search-input').val('').trigger('keyup').focus();
+};
- Search.prototype.getProjectsData = function(term) {
- return new Promise((resolve) => {
- if (this.groupId) {
- Api.groupProjects(this.groupId, term, resolve);
- } else {
- Api.projects(term, {
- order_by: 'id',
- }, resolve);
- }
- });
- };
+Search.prototype.getProjectsData = function(term) {
+ return new Promise((resolve) => {
+ if (this.groupId) {
+ Api.groupProjects(this.groupId, term, resolve);
+ } else {
+ Api.projects(term, {
+ order_by: 'id',
+ }, resolve);
+ }
+ });
+};
- return Search;
- })();
-}).call(window);
+window.Search = Search;
diff --git a/app/assets/javascripts/search_autocomplete.js b/app/assets/javascripts/search_autocomplete.js
index 6fd5345a0a6..68966c400b3 100644
--- a/app/assets/javascripts/search_autocomplete.js
+++ b/app/assets/javascripts/search_autocomplete.js
@@ -1,432 +1,427 @@
/* eslint-disable comma-dangle, no-return-assign, one-var, no-var, no-underscore-dangle, one-var-declaration-per-line, no-unused-vars, no-cond-assign, consistent-return, object-shorthand, prefer-arrow-callback, func-names, space-before-function-paren, prefer-template, quotes, class-methods-use-this, no-unused-expressions, no-sequences, wrap-iife, no-lonely-if, no-else-return, no-param-reassign, vars-on-top, max-len */
-
-((global) => {
- const KEYCODE = {
- ESCAPE: 27,
- BACKSPACE: 8,
- ENTER: 13,
- UP: 38,
- DOWN: 40
- };
-
- class SearchAutocomplete {
- constructor({ wrap, optsEl, autocompletePath, projectId, projectRef } = {}) {
- this.bindEventContext();
- this.wrap = wrap || $('.search');
- this.optsEl = optsEl || this.wrap.find('.search-autocomplete-opts');
- this.autocompletePath = autocompletePath || this.optsEl.data('autocomplete-path');
- this.projectId = projectId || (this.optsEl.data('autocomplete-project-id') || '');
- this.projectRef = projectRef || (this.optsEl.data('autocomplete-project-ref') || '');
- this.dropdown = this.wrap.find('.dropdown');
- this.dropdownContent = this.dropdown.find('.dropdown-content');
- this.locationBadgeEl = this.getElement('.location-badge');
- this.scopeInputEl = this.getElement('#scope');
- this.searchInput = this.getElement('.search-input');
- this.projectInputEl = this.getElement('#search_project_id');
- this.groupInputEl = this.getElement('#group_id');
- this.searchCodeInputEl = this.getElement('#search_code');
- 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();
- }
- this.searchInput.addClass('disabled');
- this.saveTextLength();
- this.bindEvents();
+const global = window.gl || (window.gl = {});
+
+const KEYCODE = {
+ ESCAPE: 27,
+ BACKSPACE: 8,
+ ENTER: 13,
+ UP: 38,
+ DOWN: 40
+};
+
+class SearchAutocomplete {
+ constructor({ wrap, optsEl, autocompletePath, projectId, projectRef } = {}) {
+ this.bindEventContext();
+ this.wrap = wrap || $('.search');
+ this.optsEl = optsEl || this.wrap.find('.search-autocomplete-opts');
+ this.autocompletePath = autocompletePath || this.optsEl.data('autocomplete-path');
+ this.projectId = projectId || (this.optsEl.data('autocomplete-project-id') || '');
+ this.projectRef = projectRef || (this.optsEl.data('autocomplete-project-ref') || '');
+ this.dropdown = this.wrap.find('.dropdown');
+ this.dropdownContent = this.dropdown.find('.dropdown-content');
+ this.locationBadgeEl = this.getElement('.location-badge');
+ this.scopeInputEl = this.getElement('#scope');
+ this.searchInput = this.getElement('.search-input');
+ this.projectInputEl = this.getElement('#search_project_id');
+ this.groupInputEl = this.getElement('#group_id');
+ this.searchCodeInputEl = this.getElement('#search_code');
+ 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();
}
+ this.searchInput.addClass('disabled');
+ this.saveTextLength();
+ this.bindEvents();
+ }
- // Finds an element inside wrapper element
- bindEventContext() {
- this.onSearchInputBlur = this.onSearchInputBlur.bind(this);
- this.onClearInputClick = this.onClearInputClick.bind(this);
- this.onSearchInputFocus = this.onSearchInputFocus.bind(this);
- this.onSearchInputClick = this.onSearchInputClick.bind(this);
- this.onSearchInputKeyUp = this.onSearchInputKeyUp.bind(this);
- this.onSearchInputKeyDown = this.onSearchInputKeyDown.bind(this);
- }
- getElement(selector) {
- return this.wrap.find(selector);
- }
+ // Finds an element inside wrapper element
+ bindEventContext() {
+ this.onSearchInputBlur = this.onSearchInputBlur.bind(this);
+ this.onClearInputClick = this.onClearInputClick.bind(this);
+ this.onSearchInputFocus = this.onSearchInputFocus.bind(this);
+ this.onSearchInputClick = this.onSearchInputClick.bind(this);
+ this.onSearchInputKeyUp = this.onSearchInputKeyUp.bind(this);
+ this.onSearchInputKeyDown = this.onSearchInputKeyDown.bind(this);
+ }
+ getElement(selector) {
+ return this.wrap.find(selector);
+ }
- saveOriginalState() {
- return this.originalState = this.serializeState();
- }
+ saveOriginalState() {
+ return this.originalState = this.serializeState();
+ }
- saveTextLength() {
- return this.lastTextLength = this.searchInput.val().length;
- }
+ saveTextLength() {
+ return this.lastTextLength = this.searchInput.val().length;
+ }
- createAutocomplete() {
- return this.searchInput.glDropdown({
- filterInputBlur: false,
- filterable: true,
- filterRemote: true,
- highlight: true,
- enterCallback: false,
- filterInput: 'input#search',
- search: {
- fields: ['text']
- },
- id: this.getSearchText,
- data: this.getData.bind(this),
- selectable: true,
- clicked: this.onClick.bind(this)
- });
- }
+ createAutocomplete() {
+ return this.searchInput.glDropdown({
+ filterInputBlur: false,
+ filterable: true,
+ filterRemote: true,
+ highlight: true,
+ enterCallback: false,
+ filterInput: 'input#search',
+ search: {
+ fields: ['text']
+ },
+ id: this.getSearchText,
+ data: this.getData.bind(this),
+ selectable: true,
+ clicked: this.onClick.bind(this)
+ });
+ }
- getSearchText(selectedObject, el) {
- return selectedObject.id ? selectedObject.text : '';
- }
+ getSearchText(selectedObject, el) {
+ return selectedObject.id ? selectedObject.text : '';
+ }
- getData(term, callback) {
- var _this, contents, jqXHR;
- _this = this;
- if (!term) {
- if (contents = this.getCategoryContents()) {
- this.searchInput.data('glDropdown').filter.options.callback(contents);
- this.enableAutocomplete();
- }
- return;
+ getData(term, callback) {
+ var _this, contents, jqXHR;
+ _this = this;
+ if (!term) {
+ if (contents = this.getCategoryContents()) {
+ this.searchInput.data('glDropdown').filter.options.callback(contents);
+ this.enableAutocomplete();
}
- // Prevent multiple ajax calls
- if (this.loadingSuggestions) {
+ return;
+ }
+ // Prevent multiple ajax calls
+ if (this.loadingSuggestions) {
+ return;
+ }
+ this.loadingSuggestions = true;
+ return jqXHR = $.get(this.autocompletePath, {
+ project_id: this.projectId,
+ project_ref: this.projectRef,
+ term: term
+ }, function(response) {
+ var data, firstCategory, i, lastCategory, len, suggestion;
+ // Hide dropdown menu if no suggestions returns
+ if (!response.length) {
+ _this.disableAutocomplete();
return;
}
- this.loadingSuggestions = true;
- return jqXHR = $.get(this.autocompletePath, {
- project_id: this.projectId,
- project_ref: this.projectRef,
- 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 += 1) {
- suggestion = response[i];
- // Add group header before list each group
- if (lastCategory !== suggestion.category) {
- if (!firstCategory) {
- data.push('separator');
- }
- if (firstCategory) {
- firstCategory = false;
- }
- data.push({
- header: suggestion.category
- });
- lastCategory = suggestion.category;
+ data = [];
+ // List results
+ firstCategory = true;
+ for (i = 0, len = response.length; i < len; i += 1) {
+ suggestion = response[i];
+ // Add group header before list each group
+ if (lastCategory !== suggestion.category) {
+ if (!firstCategory) {
+ data.push('separator');
+ }
+ if (firstCategory) {
+ firstCategory = false;
}
data.push({
- id: (suggestion.category.toLowerCase()) + "-" + suggestion.id,
- category: suggestion.category,
- text: suggestion.label,
- url: suggestion.url
- });
- }
- // Add option to proceed with the search
- if (data.length) {
- data.push('separator');
- data.push({
- text: "Result name contains \"" + term + "\"",
- url: "/search?search=" + term + "&project_id=" + (_this.projectInputEl.val()) + "&group_id=" + (_this.groupInputEl.val())
+ header: suggestion.category
});
+ lastCategory = suggestion.category;
}
- return callback(data);
- }).always(function() {
- return _this.loadingSuggestions = false;
- });
- }
-
- getCategoryContents() {
- var dashboardOptions, groupOptions, issuesPath, items, mrPath, name, options, projectOptions, userId, userName, utils;
- userId = gon.current_user_id;
- userName = gon.current_username;
- utils = gl.utils, projectOptions = gl.projectOptions, groupOptions = gl.groupOptions, dashboardOptions = gl.dashboardOptions;
- if (utils.isInGroupsPage() && groupOptions) {
- options = groupOptions[utils.getGroupSlug()];
- } else if (utils.isInProjectPage() && projectOptions) {
- options = projectOptions[utils.getProjectSlug()];
- } else if (dashboardOptions) {
- options = dashboardOptions;
+ data.push({
+ id: (suggestion.category.toLowerCase()) + "-" + suggestion.id,
+ category: suggestion.category,
+ text: suggestion.label,
+ url: suggestion.url
+ });
}
- issuesPath = options.issuesPath, mrPath = options.mrPath, name = options.name;
- items = [
- {
- header: "" + name
- }, {
- text: 'Issues assigned to me',
- url: issuesPath + "/?assignee_username=" + userName
- }, {
- text: "Issues I've created",
- url: issuesPath + "/?author_username=" + userName
- }, 'separator', {
- text: 'Merge requests assigned to me',
- url: mrPath + "/?assignee_username=" + userName
- }, {
- text: "Merge requests I've created",
- url: mrPath + "/?author_username=" + userName
- }
- ];
- if (!name) {
- items.splice(0, 1);
+ // Add option to proceed with the search
+ if (data.length) {
+ data.push('separator');
+ data.push({
+ text: "Result name contains \"" + term + "\"",
+ url: "/search?search=" + term + "&project_id=" + (_this.projectInputEl.val()) + "&group_id=" + (_this.groupInputEl.val())
+ });
}
- return items;
- }
-
- serializeState() {
- 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()
- };
- }
+ return callback(data);
+ }).always(function() {
+ return _this.loadingSuggestions = false;
+ });
+ }
- bindEvents() {
- this.searchInput.on('keydown', this.onSearchInputKeyDown);
- this.searchInput.on('keyup', this.onSearchInputKeyUp);
- this.searchInput.on('click', this.onSearchInputClick);
- this.searchInput.on('focus', this.onSearchInputFocus);
- this.searchInput.on('blur', this.onSearchInputBlur);
- this.clearInput.on('click', this.onClearInputClick);
- return this.locationBadgeEl.on('click', (function(_this) {
- return function() {
- return _this.searchInput.focus();
- };
- })(this));
+ getCategoryContents() {
+ var dashboardOptions, groupOptions, issuesPath, items, mrPath, name, options, projectOptions, userId, userName, utils;
+ userId = gon.current_user_id;
+ userName = gon.current_username;
+ utils = gl.utils, projectOptions = gl.projectOptions, groupOptions = gl.groupOptions, dashboardOptions = gl.dashboardOptions;
+ if (utils.isInGroupsPage() && groupOptions) {
+ options = groupOptions[utils.getGroupSlug()];
+ } else if (utils.isInProjectPage() && projectOptions) {
+ options = projectOptions[utils.getProjectSlug()];
+ } else if (dashboardOptions) {
+ options = dashboardOptions;
}
-
- enableAutocomplete() {
- var _this;
- // No need to enable anything if user is not logged in
- if (!gon.current_user_id) {
- return;
- }
- if (!this.dropdown.hasClass('open')) {
- _this = this;
- this.loadingSuggestions = false;
- this.dropdown.addClass('open').trigger('shown.bs.dropdown');
- return this.searchInput.removeClass('disabled');
+ issuesPath = options.issuesPath, mrPath = options.mrPath, name = options.name;
+ items = [
+ {
+ header: "" + name
+ }, {
+ text: 'Issues assigned to me',
+ url: issuesPath + "/?assignee_username=" + userName
+ }, {
+ text: "Issues I've created",
+ url: issuesPath + "/?author_username=" + userName
+ }, 'separator', {
+ text: 'Merge requests assigned to me',
+ url: mrPath + "/?assignee_username=" + userName
+ }, {
+ text: "Merge requests I've created",
+ url: mrPath + "/?author_username=" + userName
}
+ ];
+ if (!name) {
+ items.splice(0, 1);
}
+ return items;
+ }
- // Saves last length of the entered text
- onSearchInputKeyDown() {
- return this.saveTextLength();
+ serializeState() {
+ 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()
+ };
+ }
+
+ bindEvents() {
+ this.searchInput.on('keydown', this.onSearchInputKeyDown);
+ this.searchInput.on('keyup', this.onSearchInputKeyUp);
+ this.searchInput.on('click', this.onSearchInputClick);
+ this.searchInput.on('focus', this.onSearchInputFocus);
+ this.searchInput.on('blur', this.onSearchInputBlur);
+ this.clearInput.on('click', this.onClearInputClick);
+ return this.locationBadgeEl.on('click', () => this.searchInput.focus());
+ }
+
+ enableAutocomplete() {
+ var _this;
+ // No need to enable anything if user is not logged in
+ if (!gon.current_user_id) {
+ return;
}
+ if (!this.dropdown.hasClass('open')) {
+ _this = this;
+ this.loadingSuggestions = false;
+ this.dropdown.addClass('open').trigger('shown.bs.dropdown');
+ return this.searchInput.removeClass('disabled');
+ }
+ }
- onSearchInputKeyUp(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();
- }
- break;
- case KEYCODE.ESCAPE:
- this.restoreOriginalState();
- break;
- case KEYCODE.ENTER:
+ // Saves last length of the entered text
+ onSearchInputKeyDown() {
+ return this.saveTextLength();
+ }
+
+ onSearchInputKeyUp(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();
- break;
- case KEYCODE.UP:
- 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();
- }
+ }
+ // When removing any character from existin value
+ if (this.lastTextLength > 1) {
+ this.enableAutocomplete();
+ }
+ break;
+ case KEYCODE.ESCAPE:
+ this.restoreOriginalState();
+ break;
+ case KEYCODE.ENTER:
+ this.disableAutocomplete();
+ break;
+ case KEYCODE.UP:
+ 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();
}
- }
- this.wrap.toggleClass('has-value', !!e.target.value);
+ }
}
+ this.wrap.toggleClass('has-value', !!e.target.value);
+ }
- // Avoid falsy value to be returned
- onSearchInputClick(e) {
- return e.stopImmediatePropagation();
- }
+ // Avoid falsy value to be returned
+ onSearchInputClick(e) {
+ return e.stopImmediatePropagation();
+ }
- onSearchInputFocus() {
- this.isFocused = true;
- this.wrap.addClass('search-active');
- if (this.getValue() === '') {
- return this.getData();
- }
+ onSearchInputFocus() {
+ this.isFocused = true;
+ this.wrap.addClass('search-active');
+ if (this.getValue() === '') {
+ return this.getData();
}
+ }
- getValue() {
- return this.searchInput.val();
- }
+ getValue() {
+ return this.searchInput.val();
+ }
- onClearInputClick(e) {
- e.preventDefault();
- return this.searchInput.val('').focus();
- }
+ onClearInputClick(e) {
+ e.preventDefault();
+ return this.searchInput.val('').focus();
+ }
- onSearchInputBlur(e) {
- this.isFocused = false;
- this.wrap.removeClass('search-active');
- // If input is blank then restore state
- if (this.searchInput.val() === '') {
- return this.restoreOriginalState();
- }
+ onSearchInputBlur(e) {
+ this.isFocused = false;
+ this.wrap.removeClass('search-active');
+ // If input is blank then restore state
+ if (this.searchInput.val() === '') {
+ return this.restoreOriginalState();
}
+ }
- addLocationBadge(item) {
- var badgeText, category, value;
- category = item.category != null ? item.category + ": " : '';
- value = item.value != null ? item.value : '';
- badgeText = "" + category + value;
- this.locationBadgeEl.text(badgeText).show();
- return this.wrap.addClass('has-location-badge');
- }
+ addLocationBadge(item) {
+ var badgeText, category, value;
+ category = item.category != null ? item.category + ": " : '';
+ value = item.value != null ? item.value : '';
+ badgeText = "" + category + value;
+ this.locationBadgeEl.text(badgeText).show();
+ return this.wrap.addClass('has-location-badge');
+ }
- hasLocationBadge() {
- return this.wrap.is('.has-location-badge');
- }
+ hasLocationBadge() {
+ return this.wrap.is('.has-location-badge');
+ }
- restoreOriginalState() {
- var i, input, inputs, len;
- inputs = Object.keys(this.originalState);
- for (i = 0, len = inputs.length; i < len; i += 1) {
- input = inputs[i];
- this.getElement("#" + input).val(this.originalState[input]);
- }
- if (this.originalState._location === '') {
- return this.locationBadgeEl.hide();
- } else {
- return this.addLocationBadge({
- value: this.originalState._location
- });
- }
+ restoreOriginalState() {
+ var i, input, inputs, len;
+ inputs = Object.keys(this.originalState);
+ for (i = 0, len = inputs.length; i < len; i += 1) {
+ input = inputs[i];
+ this.getElement("#" + input).val(this.originalState[input]);
}
-
- badgePresent() {
- return this.locationBadgeEl.length;
+ if (this.originalState._location === '') {
+ return this.locationBadgeEl.hide();
+ } else {
+ return this.addLocationBadge({
+ value: this.originalState._location
+ });
}
+ }
- resetSearchState() {
- var i, input, inputs, len, results;
- inputs = Object.keys(this.originalState);
- results = [];
- for (i = 0, len = inputs.length; i < len; i += 1) {
- input = inputs[i];
- // _location isnt a input
- if (input === '_location') {
- break;
- }
- results.push(this.getElement("#" + input).val(''));
+ badgePresent() {
+ return this.locationBadgeEl.length;
+ }
+
+ resetSearchState() {
+ var i, input, inputs, len, results;
+ inputs = Object.keys(this.originalState);
+ results = [];
+ for (i = 0, len = inputs.length; i < len; i += 1) {
+ input = inputs[i];
+ // _location isnt a input
+ if (input === '_location') {
+ break;
}
- return results;
+ results.push(this.getElement("#" + input).val(''));
}
+ return results;
+ }
- removeLocationBadge() {
- this.locationBadgeEl.hide();
- this.resetSearchState();
- this.wrap.removeClass('has-location-badge');
- return this.disableAutocomplete();
- }
+ removeLocationBadge() {
+ this.locationBadgeEl.hide();
+ this.resetSearchState();
+ this.wrap.removeClass('has-location-badge');
+ return this.disableAutocomplete();
+ }
- disableAutocomplete() {
- if (!this.searchInput.hasClass('disabled') && this.dropdown.hasClass('open')) {
- this.searchInput.addClass('disabled');
- this.dropdown.removeClass('open').trigger('hidden.bs.dropdown');
- this.restoreMenu();
- }
+ disableAutocomplete() {
+ if (!this.searchInput.hasClass('disabled') && this.dropdown.hasClass('open')) {
+ this.searchInput.addClass('disabled');
+ this.dropdown.removeClass('open').trigger('hidden.bs.dropdown');
+ this.restoreMenu();
}
+ }
- restoreMenu() {
- var html;
- html = "<ul> <li><a class='dropdown-menu-empty-link is-focused'>Loading...</a></li> </ul>";
- return this.dropdownContent.html(html);
- }
+ restoreMenu() {
+ var html;
+ html = "<ul> <li><a class='dropdown-menu-empty-link is-focused'>Loading...</a></li> </ul>";
+ return this.dropdownContent.html(html);
+ }
- onClick(item, $el, e) {
- if (location.pathname.indexOf(item.url) !== -1) {
- if (!e.metaKey) e.preventDefault();
- if (!this.badgePresent) {
- if (item.category === 'Projects') {
- this.projectInputEl.val(item.id);
- this.addLocationBadge({
- value: 'This project'
- });
- }
- if (item.category === 'Groups') {
- this.groupInputEl.val(item.id);
- this.addLocationBadge({
- value: 'This group'
- });
- }
+ onClick(item, $el, e) {
+ if (location.pathname.indexOf(item.url) !== -1) {
+ if (!e.metaKey) e.preventDefault();
+ if (!this.badgePresent) {
+ if (item.category === 'Projects') {
+ this.projectInputEl.val(item.id);
+ this.addLocationBadge({
+ value: 'This project'
+ });
+ }
+ if (item.category === 'Groups') {
+ this.groupInputEl.val(item.id);
+ this.addLocationBadge({
+ value: 'This group'
+ });
}
- $el.removeClass('is-active');
- this.disableAutocomplete();
- return this.searchInput.val('').focus();
}
+ $el.removeClass('is-active');
+ this.disableAutocomplete();
+ return this.searchInput.val('').focus();
}
}
+}
- global.SearchAutocomplete = SearchAutocomplete;
+global.SearchAutocomplete = SearchAutocomplete;
- $(function() {
- var $projectOptionsDataEl = $('.js-search-project-options');
- var $groupOptionsDataEl = $('.js-search-group-options');
- var $dashboardOptionsDataEl = $('.js-search-dashboard-options');
+$(function() {
+ var $projectOptionsDataEl = $('.js-search-project-options');
+ var $groupOptionsDataEl = $('.js-search-group-options');
+ var $dashboardOptionsDataEl = $('.js-search-dashboard-options');
- if ($projectOptionsDataEl.length) {
- gl.projectOptions = gl.projectOptions || {};
+ if ($projectOptionsDataEl.length) {
+ gl.projectOptions = gl.projectOptions || {};
- var projectPath = $projectOptionsDataEl.data('project-path');
+ var projectPath = $projectOptionsDataEl.data('project-path');
- gl.projectOptions[projectPath] = {
- name: $projectOptionsDataEl.data('name'),
- issuesPath: $projectOptionsDataEl.data('issues-path'),
- mrPath: $projectOptionsDataEl.data('mr-path')
- };
- }
+ gl.projectOptions[projectPath] = {
+ name: $projectOptionsDataEl.data('name'),
+ issuesPath: $projectOptionsDataEl.data('issues-path'),
+ mrPath: $projectOptionsDataEl.data('mr-path')
+ };
+ }
- if ($groupOptionsDataEl.length) {
- gl.groupOptions = gl.groupOptions || {};
+ if ($groupOptionsDataEl.length) {
+ gl.groupOptions = gl.groupOptions || {};
- var groupPath = $groupOptionsDataEl.data('group-path');
+ var groupPath = $groupOptionsDataEl.data('group-path');
- gl.groupOptions[groupPath] = {
- name: $groupOptionsDataEl.data('name'),
- issuesPath: $groupOptionsDataEl.data('issues-path'),
- mrPath: $groupOptionsDataEl.data('mr-path')
- };
- }
+ gl.groupOptions[groupPath] = {
+ name: $groupOptionsDataEl.data('name'),
+ issuesPath: $groupOptionsDataEl.data('issues-path'),
+ mrPath: $groupOptionsDataEl.data('mr-path')
+ };
+ }
- if ($dashboardOptionsDataEl.length) {
- gl.dashboardOptions = {
- issuesPath: $dashboardOptionsDataEl.data('issues-path'),
- mrPath: $dashboardOptionsDataEl.data('mr-path')
- };
- }
- });
-})(window.gl || (window.gl = {}));
+ if ($dashboardOptionsDataEl.length) {
+ gl.dashboardOptions = {
+ issuesPath: $dashboardOptionsDataEl.data('issues-path'),
+ mrPath: $dashboardOptionsDataEl.data('mr-path')
+ };
+ }
+});
diff --git a/app/assets/javascripts/shortcuts.js b/app/assets/javascripts/shortcuts.js
index e3daa8cf949..e9575fda369 100644
--- a/app/assets/javascripts/shortcuts.js
+++ b/app/assets/javascripts/shortcuts.js
@@ -4,139 +4,135 @@ import Cookies from 'js-cookie';
import findAndFollowLink from './shortcuts_dashboard_navigation';
-(function() {
- this.Shortcuts = (function() {
- function Shortcuts(skipResetBindings) {
- this.onToggleHelp = this.onToggleHelp.bind(this);
- this.enabledHelp = [];
- if (!skipResetBindings) {
- Mousetrap.reset();
- }
- Mousetrap.bind('?', this.onToggleHelp);
- Mousetrap.bind('s', Shortcuts.focusSearch);
- Mousetrap.bind('f', (e => this.focusFilter(e)));
- Mousetrap.bind('p b', this.onTogglePerfBar);
-
- const $globalDropdownMenu = $('.global-dropdown-menu');
- const $globalDropdownToggle = $('.global-dropdown-toggle');
- const findFileURL = document.body.dataset.findFile;
-
- $('.global-dropdown').on('hide.bs.dropdown', () => {
- $globalDropdownMenu.removeClass('shortcuts');
- });
+function Shortcuts(skipResetBindings) {
+ this.onToggleHelp = this.onToggleHelp.bind(this);
+ this.enabledHelp = [];
+ if (!skipResetBindings) {
+ Mousetrap.reset();
+ }
+ Mousetrap.bind('?', this.onToggleHelp);
+ Mousetrap.bind('s', Shortcuts.focusSearch);
+ Mousetrap.bind('f', (e => this.focusFilter(e)));
+ Mousetrap.bind('p b', this.onTogglePerfBar);
+
+ const $globalDropdownMenu = $('.global-dropdown-menu');
+ const $globalDropdownToggle = $('.global-dropdown-toggle');
+ const findFileURL = document.body.dataset.findFile;
+
+ $('.global-dropdown').on('hide.bs.dropdown', () => {
+ $globalDropdownMenu.removeClass('shortcuts');
+ });
- Mousetrap.bind('n', () => {
- $globalDropdownMenu.toggleClass('shortcuts');
- $globalDropdownToggle.trigger('click');
+ Mousetrap.bind('n', () => {
+ $globalDropdownMenu.toggleClass('shortcuts');
+ $globalDropdownToggle.trigger('click');
- if (!$globalDropdownMenu.is(':visible')) {
- $globalDropdownToggle.blur();
- }
- });
-
- Mousetrap.bind('shift+t', () => findAndFollowLink('.shortcuts-todos'));
- Mousetrap.bind('shift+a', () => findAndFollowLink('.dashboard-shortcuts-activity'));
- Mousetrap.bind('shift+i', () => findAndFollowLink('.dashboard-shortcuts-issues'));
- Mousetrap.bind('shift+m', () => findAndFollowLink('.dashboard-shortcuts-merge_requests'));
- Mousetrap.bind('shift+p', () => findAndFollowLink('.dashboard-shortcuts-projects'));
- Mousetrap.bind('shift+g', () => findAndFollowLink('.dashboard-shortcuts-groups'));
- Mousetrap.bind('shift+l', () => findAndFollowLink('.dashboard-shortcuts-milestones'));
- Mousetrap.bind('shift+s', () => findAndFollowLink('.dashboard-shortcuts-snippets'));
-
- Mousetrap.bind(['ctrl+shift+p', 'command+shift+p'], this.toggleMarkdownPreview);
- if (typeof findFileURL !== "undefined" && findFileURL !== null) {
- Mousetrap.bind('t', function() {
- return gl.utils.visitUrl(findFileURL);
- });
- }
+ if (!$globalDropdownMenu.is(':visible')) {
+ $globalDropdownToggle.blur();
}
-
- Shortcuts.prototype.onToggleHelp = function(e) {
- e.preventDefault();
- return Shortcuts.toggleHelp(this.enabledHelp);
- };
-
- Shortcuts.prototype.onTogglePerfBar = function(e) {
- e.preventDefault();
- const performanceBarCookieName = 'perf_bar_enabled';
- if (Cookies.get(performanceBarCookieName) === 'true') {
- Cookies.remove(performanceBarCookieName, { path: '/' });
- } else {
- Cookies.set(performanceBarCookieName, 'true', { path: '/' });
- }
- gl.utils.refreshCurrentPage();
- };
-
- Shortcuts.prototype.toggleMarkdownPreview = function(e) {
- // Check if short-cut was triggered while in Write Mode
- const $target = $(e.target);
- const $form = $target.closest('form');
-
- if ($target.hasClass('js-note-text')) {
- $('.js-md-preview-button', $form).focus();
- }
- return $(document).triggerHandler('markdown-preview:toggle', [e]);
- };
-
- Shortcuts.toggleHelp = function(location) {
- var $modal;
- $modal = $('#modal-shortcuts');
- if ($modal.length) {
- $modal.modal('toggle');
- return;
- }
- return $.ajax({
- url: gon.shortcuts_path,
- dataType: 'script',
- success: function(e) {
- var i, l, len, results;
- if (location && location.length > 0) {
- results = [];
- for (i = 0, len = location.length; i < len; i += 1) {
- l = location[i];
- results.push($(l).show());
- }
- return results;
- } else {
- $('.hidden-shortcut').show();
- return $('.js-more-help-button').remove();
- }
- }
- });
- };
-
- Shortcuts.prototype.focusFilter = function(e) {
- if (this.filterInput == null) {
- this.filterInput = $('input[type=search]', '.nav-controls');
- }
- this.filterInput.focus();
- return e.preventDefault();
- };
-
- Shortcuts.focusSearch = function(e) {
- $('#search').focus();
- return e.preventDefault();
- };
-
- return Shortcuts;
- })();
-
- $(document).on('click.more_help', '.js-more-help-button', function(e) {
- $(this).remove();
- $('.hidden-shortcut').show();
- return e.preventDefault();
});
- Mousetrap.stopCallback = (function() {
- 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;
+ Mousetrap.bind('shift+t', () => findAndFollowLink('.shortcuts-todos'));
+ Mousetrap.bind('shift+a', () => findAndFollowLink('.dashboard-shortcuts-activity'));
+ Mousetrap.bind('shift+i', () => findAndFollowLink('.dashboard-shortcuts-issues'));
+ Mousetrap.bind('shift+m', () => findAndFollowLink('.dashboard-shortcuts-merge_requests'));
+ Mousetrap.bind('shift+p', () => findAndFollowLink('.dashboard-shortcuts-projects'));
+ Mousetrap.bind('shift+g', () => findAndFollowLink('.dashboard-shortcuts-groups'));
+ Mousetrap.bind('shift+l', () => findAndFollowLink('.dashboard-shortcuts-milestones'));
+ Mousetrap.bind('shift+s', () => findAndFollowLink('.dashboard-shortcuts-snippets'));
+
+ Mousetrap.bind(['ctrl+shift+p', 'command+shift+p'], this.toggleMarkdownPreview);
+ if (typeof findFileURL !== "undefined" && findFileURL !== null) {
+ Mousetrap.bind('t', function() {
+ return gl.utils.visitUrl(findFileURL);
+ });
+ }
+}
+
+Shortcuts.prototype.onToggleHelp = function(e) {
+ e.preventDefault();
+ return Shortcuts.toggleHelp(this.enabledHelp);
+};
+
+Shortcuts.prototype.onTogglePerfBar = function(e) {
+ e.preventDefault();
+ const performanceBarCookieName = 'perf_bar_enabled';
+ if (Cookies.get(performanceBarCookieName) === 'true') {
+ Cookies.remove(performanceBarCookieName, { path: '/' });
+ } else {
+ Cookies.set(performanceBarCookieName, 'true', { path: '/' });
+ }
+ gl.utils.refreshCurrentPage();
+};
+
+Shortcuts.prototype.toggleMarkdownPreview = function(e) {
+ // Check if short-cut was triggered while in Write Mode
+ const $target = $(e.target);
+ const $form = $target.closest('form');
+
+ if ($target.hasClass('js-note-text')) {
+ $('.js-md-preview-button', $form).focus();
+ }
+ return $(document).triggerHandler('markdown-preview:toggle', [e]);
+};
+
+Shortcuts.toggleHelp = function(location) {
+ var $modal;
+ $modal = $('#modal-shortcuts');
+ if ($modal.length) {
+ $modal.modal('toggle');
+ return;
+ }
+ return $.ajax({
+ url: gon.shortcuts_path,
+ dataType: 'script',
+ success: function(e) {
+ var i, l, len, results;
+ if (location && location.length > 0) {
+ results = [];
+ for (i = 0, len = location.length; i < len; i += 1) {
+ l = location[i];
+ results.push($(l).show());
+ }
+ return results;
} else {
- return defaultStopCallback.apply(this, arguments);
+ $('.hidden-shortcut').show();
+ return $('.js-more-help-button').remove();
}
- };
- })();
-}).call(window);
+ }
+ });
+};
+
+Shortcuts.prototype.focusFilter = function(e) {
+ if (this.filterInput == null) {
+ this.filterInput = $('input[type=search]', '.nav-controls');
+ }
+ this.filterInput.focus();
+ return e.preventDefault();
+};
+
+Shortcuts.focusSearch = function(e) {
+ $('#search').focus();
+ return e.preventDefault();
+};
+
+window.Shortcuts = Shortcuts;
+
+$(document).on('click.more_help', '.js-more-help-button', function(e) {
+ $(this).remove();
+ $('.hidden-shortcut').show();
+ return e.preventDefault();
+});
+
+Mousetrap.stopCallback = (function() {
+ 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 {
+ return defaultStopCallback.apply(this, arguments);
+ }
+ };
+})();
diff --git a/app/assets/javascripts/shortcuts_find_file.js b/app/assets/javascripts/shortcuts_find_file.js
index b18b6139b35..dd41c070c8d 100644
--- a/app/assets/javascripts/shortcuts_find_file.js
+++ b/app/assets/javascripts/shortcuts_find_file.js
@@ -4,35 +4,31 @@
import './shortcuts_navigation';
-(function() {
- var extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
- hasProp = {}.hasOwnProperty;
+var extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
+ hasProp = {}.hasOwnProperty;
- this.ShortcutsFindFile = (function(superClass) {
- extend(ShortcutsFindFile, superClass);
+function ShortcutsFindFile(projectFindFile) {
+ var _oldStopCallback;
+ this.projectFindFile = projectFindFile;
+ ShortcutsFindFile.__super__.constructor.call(this);
+ _oldStopCallback = Mousetrap.stopCallback;
- function ShortcutsFindFile(projectFindFile) {
- var _oldStopCallback;
- this.projectFindFile = projectFindFile;
- 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;
- }
- return _oldStopCallback(event, element, combo);
- };
- })(this);
- Mousetrap.bind('up', this.projectFindFile.selectRowUp);
- Mousetrap.bind('down', this.projectFindFile.selectRowDown);
- Mousetrap.bind('esc', this.projectFindFile.goToTree);
- Mousetrap.bind('enter', this.projectFindFile.goToBlob);
+ // override to fire shortcuts action when focus in textbox
+ Mousetrap.stopCallback = 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;
}
+ return _oldStopCallback(event, element, combo);
+ }.bind(this);
- return ShortcutsFindFile;
- })(ShortcutsNavigation);
-}).call(window);
+ Mousetrap.bind('up', this.projectFindFile.selectRowUp);
+ Mousetrap.bind('down', this.projectFindFile.selectRowDown);
+ Mousetrap.bind('esc', this.projectFindFile.goToTree);
+ Mousetrap.bind('enter', this.projectFindFile.goToBlob);
+}
+
+extend(ShortcutsFindFile, ShortcutsNavigation);
+
+window.ShortcutsFindFile = ShortcutsFindFile;
diff --git a/app/assets/javascripts/shortcuts_issuable.js b/app/assets/javascripts/shortcuts_issuable.js
index 51448252c0f..138b9768735 100644
--- a/app/assets/javascripts/shortcuts_issuable.js
+++ b/app/assets/javascripts/shortcuts_issuable.js
@@ -6,87 +6,81 @@
import 'mousetrap';
import './shortcuts_navigation';
-(function() {
- var extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
- hasProp = {}.hasOwnProperty;
+var extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
+ hasProp = {}.hasOwnProperty;
- this.ShortcutsIssuable = (function(superClass) {
- extend(ShortcutsIssuable, superClass);
+var ShortcutsIssuable = {};
- function ShortcutsIssuable(isMergeRequest) {
- ShortcutsIssuable.__super__.constructor.call(this);
- Mousetrap.bind('a', this.openSidebarDropdown.bind(this, 'assignee'));
- Mousetrap.bind('m', this.openSidebarDropdown.bind(this, 'milestone'));
- Mousetrap.bind('r', (function(_this) {
- return function() {
- _this.replyWithSelectedText();
- return false;
- };
- })(this));
- Mousetrap.bind('e', (function(_this) {
- return function() {
- _this.editIssue();
- return false;
- };
- })(this));
- Mousetrap.bind('l', this.openSidebarDropdown.bind(this, 'labels'));
- if (isMergeRequest) {
- this.enabledHelp.push('.hidden-shortcut.merge_requests');
- } else {
- this.enabledHelp.push('.hidden-shortcut.issues');
- }
- }
+extend(ShortcutsIssuable, ShortcutsNavigation);
- ShortcutsIssuable.prototype.replyWithSelectedText = function() {
- var quote, documentFragment, el, selected, separator;
- var replyField = $('.js-main-target-form #note_note');
+ShortcutsIssuable = function(isMergeRequest) {
+ ShortcutsIssuable.__super__.constructor.call(this);
+ Mousetrap.bind('a', this.openSidebarDropdown.bind(this, 'assignee'));
+ Mousetrap.bind('m', this.openSidebarDropdown.bind(this, 'milestone'));
+ Mousetrap.bind('r', function() {
+ this.replyWithSelectedText();
+ return false;
+ }.bind(this));
+ Mousetrap.bind('e', function() {
+ this.editIssue();
+ return false;
+ }.bind(this));
+ Mousetrap.bind('l', this.openSidebarDropdown.bind(this, 'labels'));
+ if (isMergeRequest) {
+ this.enabledHelp.push('.hidden-shortcut.merge_requests');
+ } else {
+ this.enabledHelp.push('.hidden-shortcut.issues');
+ }
+};
- documentFragment = window.gl.utils.getSelectedFragment();
- if (!documentFragment) {
- replyField.focus();
- return;
- }
+ShortcutsIssuable.prototype.replyWithSelectedText = function() {
+ var quote, documentFragment, el, selected, separator;
+ var replyField = $('.js-main-target-form #note_note');
- el = window.gl.CopyAsGFM.transformGFMSelection(documentFragment.cloneNode(true));
- selected = window.gl.CopyAsGFM.nodeToGFM(el);
+ documentFragment = window.gl.utils.getSelectedFragment();
+ if (!documentFragment) {
+ replyField.focus();
+ return;
+ }
- if (selected.trim() === "") {
- return;
- }
- quote = _.map(selected.split("\n"), function(val) {
- return ("> " + val).trim() + "\n";
- });
- // If replyField already has some content, add a newline before our quote
- separator = replyField.val().trim() !== "" && "\n\n" || '';
- replyField.val(function(_, current) {
- return current + separator + quote.join('') + "\n";
- });
+ el = window.gl.CopyAsGFM.transformGFMSelection(documentFragment.cloneNode(true));
+ selected = window.gl.CopyAsGFM.nodeToGFM(el);
- // Trigger autosave
- replyField.trigger('input');
+ if (selected.trim() === "") {
+ return;
+ }
+ quote = _.map(selected.split("\n"), function(val) {
+ return ("> " + val).trim() + "\n";
+ });
+ // If replyField already has some content, add a newline before our quote
+ separator = replyField.val().trim() !== "" && "\n\n" || '';
+ replyField.val(function(_, current) {
+ return current + separator + quote.join('') + "\n";
+ });
- // Trigger autosize
- var event = document.createEvent('Event');
- event.initEvent('autosize:update', true, false);
- replyField.get(0).dispatchEvent(event);
+ // Trigger autosave
+ replyField.trigger('input');
- // Focus the input field
- return replyField.focus();
- };
+ // Trigger autosize
+ var event = document.createEvent('Event');
+ event.initEvent('autosize:update', true, false);
+ replyField.get(0).dispatchEvent(event);
- ShortcutsIssuable.prototype.editIssue = function() {
- var $editBtn;
- $editBtn = $('.issuable-edit');
- // Need to click the element as on issues, editing is inline
- // on merge request, editing is on a different page
- $editBtn.get(0).click();
- };
+ // Focus the input field
+ return replyField.focus();
+};
- ShortcutsIssuable.prototype.openSidebarDropdown = function(name) {
- sidebar.openDropdown(name);
- return false;
- };
+ShortcutsIssuable.prototype.editIssue = function() {
+ var $editBtn;
+ $editBtn = $('.issuable-edit');
+ // Need to click the element as on issues, editing is inline
+ // on merge request, editing is on a different page
+ $editBtn.get(0).click();
+};
- return ShortcutsIssuable;
- })(ShortcutsNavigation);
-}).call(window);
+ShortcutsIssuable.prototype.openSidebarDropdown = function(name) {
+ sidebar.openDropdown(name);
+ return false;
+};
+
+window.ShortcutsIssuable = ShortcutsIssuable;
diff --git a/app/assets/javascripts/shortcuts_navigation.js b/app/assets/javascripts/shortcuts_navigation.js
index 55bae0c08a1..bba292cac2b 100644
--- a/app/assets/javascripts/shortcuts_navigation.js
+++ b/app/assets/javascripts/shortcuts_navigation.js
@@ -5,32 +5,30 @@
import findAndFollowLink from './shortcuts_dashboard_navigation';
import './shortcuts';
-(function() {
- var extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
- hasProp = {}.hasOwnProperty;
+var extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
+ hasProp = {}.hasOwnProperty;
- this.ShortcutsNavigation = (function(superClass) {
- extend(ShortcutsNavigation, superClass);
+var ShortcutsNavigation = {};
- function ShortcutsNavigation() {
- ShortcutsNavigation.__super__.constructor.call(this);
- Mousetrap.bind('g p', () => findAndFollowLink('.shortcuts-project'));
- Mousetrap.bind('g e', () => findAndFollowLink('.shortcuts-project-activity'));
- Mousetrap.bind('g f', () => findAndFollowLink('.shortcuts-tree'));
- Mousetrap.bind('g c', () => findAndFollowLink('.shortcuts-commits'));
- Mousetrap.bind('g j', () => findAndFollowLink('.shortcuts-builds'));
- Mousetrap.bind('g n', () => findAndFollowLink('.shortcuts-network'));
- Mousetrap.bind('g d', () => findAndFollowLink('.shortcuts-repository-charts'));
- Mousetrap.bind('g i', () => findAndFollowLink('.shortcuts-issues'));
- Mousetrap.bind('g b', () => findAndFollowLink('.shortcuts-issue-boards'));
- Mousetrap.bind('g m', () => findAndFollowLink('.shortcuts-merge_requests'));
- Mousetrap.bind('g t', () => findAndFollowLink('.shortcuts-todos'));
- Mousetrap.bind('g w', () => findAndFollowLink('.shortcuts-wiki'));
- Mousetrap.bind('g s', () => findAndFollowLink('.shortcuts-snippets'));
- Mousetrap.bind('i', () => findAndFollowLink('.shortcuts-new-issue'));
- this.enabledHelp.push('.hidden-shortcut.project');
- }
+extend(ShortcutsNavigation, Shortcuts);
- return ShortcutsNavigation;
- })(Shortcuts);
-}).call(window);
+ShortcutsNavigation = function() {
+ ShortcutsNavigation.__super__.constructor.call(this);
+ Mousetrap.bind('g p', () => findAndFollowLink('.shortcuts-project'));
+ Mousetrap.bind('g e', () => findAndFollowLink('.shortcuts-project-activity'));
+ Mousetrap.bind('g f', () => findAndFollowLink('.shortcuts-tree'));
+ Mousetrap.bind('g c', () => findAndFollowLink('.shortcuts-commits'));
+ Mousetrap.bind('g j', () => findAndFollowLink('.shortcuts-builds'));
+ Mousetrap.bind('g n', () => findAndFollowLink('.shortcuts-network'));
+ Mousetrap.bind('g d', () => findAndFollowLink('.shortcuts-repository-charts'));
+ Mousetrap.bind('g i', () => findAndFollowLink('.shortcuts-issues'));
+ Mousetrap.bind('g b', () => findAndFollowLink('.shortcuts-issue-boards'));
+ Mousetrap.bind('g m', () => findAndFollowLink('.shortcuts-merge_requests'));
+ Mousetrap.bind('g t', () => findAndFollowLink('.shortcuts-todos'));
+ Mousetrap.bind('g w', () => findAndFollowLink('.shortcuts-wiki'));
+ Mousetrap.bind('g s', () => findAndFollowLink('.shortcuts-snippets'));
+ Mousetrap.bind('i', () => findAndFollowLink('.shortcuts-new-issue'));
+ this.enabledHelp.push('.hidden-shortcut.project');
+};
+
+window.ShortcutsNavigation = ShortcutsNavigation;
diff --git a/app/assets/javascripts/shortcuts_network.js b/app/assets/javascripts/shortcuts_network.js
index cc44082efa9..8ff5b86939a 100644
--- a/app/assets/javascripts/shortcuts_network.js
+++ b/app/assets/javascripts/shortcuts_network.js
@@ -4,25 +4,23 @@
import './shortcuts_navigation';
-(function() {
- var extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
- hasProp = {}.hasOwnProperty;
+var extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
+ hasProp = {}.hasOwnProperty;
- this.ShortcutsNetwork = (function(superClass) {
- extend(ShortcutsNetwork, superClass);
+var ShortcutsNetwork = {};
- function ShortcutsNetwork(graph) {
- this.graph = graph;
- ShortcutsNetwork.__super__.constructor.call(this);
- Mousetrap.bind(['left', 'h'], this.graph.scrollLeft);
- Mousetrap.bind(['right', 'l'], this.graph.scrollRight);
- Mousetrap.bind(['up', 'k'], this.graph.scrollUp);
- Mousetrap.bind(['down', 'j'], this.graph.scrollDown);
- Mousetrap.bind(['shift+up', 'shift+k'], this.graph.scrollTop);
- Mousetrap.bind(['shift+down', 'shift+j'], this.graph.scrollBottom);
- this.enabledHelp.push('.hidden-shortcut.network');
- }
+extend(ShortcutsNetwork, ShortcutsNavigation);
- return ShortcutsNetwork;
- })(ShortcutsNavigation);
-}).call(window);
+ShortcutsNetwork = function(graph) {
+ this.graph = graph;
+ ShortcutsNetwork.__super__.constructor.call(this);
+ Mousetrap.bind(['left', 'h'], this.graph.scrollLeft);
+ Mousetrap.bind(['right', 'l'], this.graph.scrollRight);
+ Mousetrap.bind(['up', 'k'], this.graph.scrollUp);
+ Mousetrap.bind(['down', 'j'], this.graph.scrollDown);
+ Mousetrap.bind(['shift+up', 'shift+k'], this.graph.scrollTop);
+ Mousetrap.bind(['shift+down', 'shift+j'], this.graph.scrollBottom);
+ this.enabledHelp.push('.hidden-shortcut.network');
+};
+
+window.ShortcutsNetwork = ShortcutsNetwork;
diff --git a/app/assets/javascripts/templates/issuable_template_selector.js b/app/assets/javascripts/templates/issuable_template_selector.js
index 9dd14488f22..4d81402d12c 100644
--- a/app/assets/javascripts/templates/issuable_template_selector.js
+++ b/app/assets/javascripts/templates/issuable_template_selector.js
@@ -3,58 +3,58 @@ import Api from '../api';
import TemplateSelector from '../blob/template_selector';
-((global) => {
- class IssuableTemplateSelector extends TemplateSelector {
- constructor(...args) {
- super(...args);
- this.projectPath = this.dropdown.data('project-path');
- this.namespacePath = this.dropdown.data('namespace-path');
- this.issuableType = this.$dropdownContainer.data('issuable-type');
- this.titleInput = $(`#${this.issuableType}_title`);
-
- const initialQuery = {
- name: this.dropdown.data('selected')
- };
-
- if (initialQuery.name) this.requestFile(initialQuery);
-
- $('.reset-template', this.dropdown.parent()).on('click', () => {
- this.setInputValueToTemplateContent();
- });
-
- $('.no-template', this.dropdown.parent()).on('click', () => {
- this.currentTemplate.content = '';
- this.setInputValueToTemplateContent();
- $('.dropdown-toggle-text', this.dropdown).text('Choose a template');
- });
- }
+const global = window.gl || (window.gl = {});
+
+class IssuableTemplateSelector extends TemplateSelector {
+ constructor(...args) {
+ super(...args);
+ this.projectPath = this.dropdown.data('project-path');
+ this.namespacePath = this.dropdown.data('namespace-path');
+ this.issuableType = this.$dropdownContainer.data('issuable-type');
+ this.titleInput = $(`#${this.issuableType}_title`);
+
+ const initialQuery = {
+ name: this.dropdown.data('selected')
+ };
+
+ if (initialQuery.name) this.requestFile(initialQuery);
+
+ $('.reset-template', this.dropdown.parent()).on('click', () => {
+ this.setInputValueToTemplateContent();
+ });
+
+ $('.no-template', this.dropdown.parent()).on('click', () => {
+ this.currentTemplate.content = '';
+ this.setInputValueToTemplateContent();
+ $('.dropdown-toggle-text', this.dropdown).text('Choose a template');
+ });
+ }
- requestFile(query) {
- this.startLoadingSpinner();
- Api.issueTemplate(this.namespacePath, this.projectPath, query.name, this.issuableType, (err, currentTemplate) => {
- this.currentTemplate = currentTemplate;
- if (err) return; // Error handled by global AJAX error handler
- this.stopLoadingSpinner();
- this.setInputValueToTemplateContent();
- });
- return;
- }
+ requestFile(query) {
+ this.startLoadingSpinner();
+ Api.issueTemplate(this.namespacePath, this.projectPath, query.name, this.issuableType, (err, currentTemplate) => {
+ this.currentTemplate = currentTemplate;
+ if (err) return; // Error handled by global AJAX error handler
+ this.stopLoadingSpinner();
+ this.setInputValueToTemplateContent();
+ });
+ return;
+ }
- setInputValueToTemplateContent() {
- // `this.setEditorContent` sets the value of the description input field
- // to the content of the template selected.
- if (this.titleInput.val() === '') {
- // If the title has not yet been set, focus the title input and
- // skip focusing the description input by setting `true` as the
- // `skipFocus` option to `setEditorContent`.
- this.setEditorContent(this.currentTemplate, { skipFocus: true });
- this.titleInput.focus();
- } else {
- this.setEditorContent(this.currentTemplate, { skipFocus: false });
- }
- return;
+ setInputValueToTemplateContent() {
+ // `this.setEditorContent` sets the value of the description input field
+ // to the content of the template selected.
+ if (this.titleInput.val() === '') {
+ // If the title has not yet been set, focus the title input and
+ // skip focusing the description input by setting `true` as the
+ // `skipFocus` option to `setEditorContent`.
+ this.setEditorContent(this.currentTemplate, { skipFocus: true });
+ this.titleInput.focus();
+ } else {
+ this.setEditorContent(this.currentTemplate, { skipFocus: false });
}
+ return;
}
+}
- global.IssuableTemplateSelector = IssuableTemplateSelector;
-})(window.gl || (window.gl = {}));
+global.IssuableTemplateSelector = IssuableTemplateSelector;
diff --git a/app/assets/javascripts/templates/issuable_template_selectors.js b/app/assets/javascripts/templates/issuable_template_selectors.js
index 97f6d37364d..5eb516c16f0 100644
--- a/app/assets/javascripts/templates/issuable_template_selectors.js
+++ b/app/assets/javascripts/templates/issuable_template_selectors.js
@@ -1,31 +1,31 @@
/* eslint-disable no-new, comma-dangle, class-methods-use-this, no-param-reassign */
-((global) => {
- class IssuableTemplateSelectors {
- constructor({ $dropdowns, editor } = {}) {
- this.$dropdowns = $dropdowns || $('.js-issuable-selector');
- this.editor = editor || this.initEditor();
+const global = window.gl || (window.gl = {});
- this.$dropdowns.each((i, dropdown) => {
- const $dropdown = $(dropdown);
- new gl.IssuableTemplateSelector({
- pattern: /(\.md)/,
- data: $dropdown.data('data'),
- wrapper: $dropdown.closest('.js-issuable-selector-wrap'),
- dropdown: $dropdown,
- editor: this.editor
- });
+class IssuableTemplateSelectors {
+ constructor({ $dropdowns, editor } = {}) {
+ this.$dropdowns = $dropdowns || $('.js-issuable-selector');
+ this.editor = editor || this.initEditor();
+
+ this.$dropdowns.each((i, dropdown) => {
+ const $dropdown = $(dropdown);
+ new gl.IssuableTemplateSelector({
+ pattern: /(\.md)/,
+ data: $dropdown.data('data'),
+ wrapper: $dropdown.closest('.js-issuable-selector-wrap'),
+ dropdown: $dropdown,
+ editor: this.editor
});
- }
+ });
+ }
- initEditor() {
- const editor = $('.markdown-area');
- // Proxy ace-editor's .setValue to jQuery's .val
- editor.setValue = editor.val;
- editor.getValue = editor.val;
- return editor;
- }
+ initEditor() {
+ const editor = $('.markdown-area');
+ // Proxy ace-editor's .setValue to jQuery's .val
+ editor.setValue = editor.val;
+ editor.getValue = editor.val;
+ return editor;
}
+}
- global.IssuableTemplateSelectors = IssuableTemplateSelectors;
-})(window.gl || (window.gl = {}));
+global.IssuableTemplateSelectors = IssuableTemplateSelectors;
diff --git a/app/assets/javascripts/u2f/authenticate.js b/app/assets/javascripts/u2f/authenticate.js
index cd5280948fd..04e943ca581 100644
--- a/app/assets/javascripts/u2f/authenticate.js
+++ b/app/assets/javascripts/u2f/authenticate.js
@@ -7,110 +7,104 @@
//
// State Flow #1: setup -> in_progress -> authenticated -> POST to server
// State Flow #2: setup -> in_progress -> error -> setup
-(function() {
- const global = window.gl || (window.gl = {});
+const global = window.gl || (window.gl = {});
- global.U2FAuthenticate = (function() {
- function U2FAuthenticate(container, form, u2fParams, fallbackButton, fallbackUI) {
- this.container = container;
- this.renderNotSupported = this.renderNotSupported.bind(this);
- this.renderAuthenticated = this.renderAuthenticated.bind(this);
- this.renderError = this.renderError.bind(this);
- this.renderInProgress = this.renderInProgress.bind(this);
- this.renderTemplate = this.renderTemplate.bind(this);
- this.authenticate = this.authenticate.bind(this);
- this.start = this.start.bind(this);
- this.appId = u2fParams.app_id;
- this.challenge = u2fParams.challenge;
- this.form = form;
- this.fallbackButton = fallbackButton;
- this.fallbackUI = fallbackUI;
- if (this.fallbackButton) this.fallbackButton.addEventListener('click', this.switchToFallbackUI.bind(this));
- 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');
- });
- }
+function U2FAuthenticate(container, form, u2fParams, fallbackButton, fallbackUI) {
+ this.container = container;
+ this.renderNotSupported = this.renderNotSupported.bind(this);
+ this.renderAuthenticated = this.renderAuthenticated.bind(this);
+ this.renderError = this.renderError.bind(this);
+ this.renderInProgress = this.renderInProgress.bind(this);
+ this.renderTemplate = this.renderTemplate.bind(this);
+ this.authenticate = this.authenticate.bind(this);
+ this.start = this.start.bind(this);
+ this.appId = u2fParams.app_id;
+ this.challenge = u2fParams.challenge;
+ this.form = form;
+ this.fallbackButton = fallbackButton;
+ this.fallbackUI = fallbackUI;
+ if (this.fallbackButton) this.fallbackButton.addEventListener('click', this.switchToFallbackUI.bind(this));
+ 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');
+ });
+}
- U2FAuthenticate.prototype.start = function() {
- if (U2FUtil.isU2FSupported()) {
- return this.renderInProgress();
- } else {
- return this.renderNotSupported();
- }
- };
+U2FAuthenticate.prototype.start = function() {
+ if (U2FUtil.isU2FSupported()) {
+ return this.renderInProgress();
+ } else {
+ return this.renderNotSupported();
+ }
+};
- U2FAuthenticate.prototype.authenticate = function() {
- return u2f.sign(this.appId, this.challenge, this.signRequests, (function(_this) {
- return function(response) {
- var error;
- if (response.errorCode) {
- error = new U2FError(response.errorCode, 'authenticate');
- return _this.renderError(error);
- } else {
- return _this.renderAuthenticated(JSON.stringify(response));
- }
- };
- })(this), 10);
- };
+U2FAuthenticate.prototype.authenticate = function() {
+ return u2f.sign(this.appId, this.challenge, this.signRequests, function(response) {
+ var error;
+ if (response.errorCode) {
+ error = new U2FError(response.errorCode, 'authenticate');
+ return this.renderError(error);
+ } else {
+ return this.renderAuthenticated(JSON.stringify(response));
+ }
+ }.bind(this), 10);
+};
- // Rendering #
- U2FAuthenticate.prototype.templates = {
- "notSupported": "#js-authenticate-u2f-not-supported",
- "setup": '#js-authenticate-u2f-setup',
- "inProgress": '#js-authenticate-u2f-in-progress',
- "error": '#js-authenticate-u2f-error',
- "authenticated": '#js-authenticate-u2f-authenticated'
- };
+// Rendering #
+U2FAuthenticate.prototype.templates = {
+ "notSupported": "#js-authenticate-u2f-not-supported",
+ "setup": '#js-authenticate-u2f-setup',
+ "inProgress": '#js-authenticate-u2f-in-progress',
+ "error": '#js-authenticate-u2f-error',
+ "authenticated": '#js-authenticate-u2f-authenticated'
+};
- U2FAuthenticate.prototype.renderTemplate = function(name, params) {
- var template, templateString;
- templateString = $(this.templates[name]).html();
- template = _.template(templateString);
- return this.container.html(template(params));
- };
+U2FAuthenticate.prototype.renderTemplate = function(name, params) {
+ var template, templateString;
+ templateString = $(this.templates[name]).html();
+ template = _.template(templateString);
+ return this.container.html(template(params));
+};
- U2FAuthenticate.prototype.renderInProgress = function() {
- this.renderTemplate('inProgress');
- return this.authenticate();
- };
+U2FAuthenticate.prototype.renderInProgress = function() {
+ this.renderTemplate('inProgress');
+ return this.authenticate();
+};
- U2FAuthenticate.prototype.renderError = function(error) {
- this.renderTemplate('error', {
- error_message: error.message(),
- error_code: error.errorCode
- });
- return this.container.find('#js-u2f-try-again').on('click', this.renderInProgress);
- };
+U2FAuthenticate.prototype.renderError = function(error) {
+ this.renderTemplate('error', {
+ error_message: error.message(),
+ error_code: error.errorCode
+ });
+ return this.container.find('#js-u2f-try-again').on('click', this.renderInProgress);
+};
- U2FAuthenticate.prototype.renderAuthenticated = function(deviceResponse) {
- this.renderTemplate('authenticated');
- const container = this.container[0];
- container.querySelector('#js-device-response').value = deviceResponse;
- container.querySelector(this.form).submit();
- this.fallbackButton.classList.add('hidden');
- };
+U2FAuthenticate.prototype.renderAuthenticated = function(deviceResponse) {
+ this.renderTemplate('authenticated');
+ const container = this.container[0];
+ container.querySelector('#js-device-response').value = deviceResponse;
+ container.querySelector(this.form).submit();
+ this.fallbackButton.classList.add('hidden');
+};
- U2FAuthenticate.prototype.renderNotSupported = function() {
- return this.renderTemplate('notSupported');
- };
+U2FAuthenticate.prototype.renderNotSupported = function() {
+ return this.renderTemplate('notSupported');
+};
- U2FAuthenticate.prototype.switchToFallbackUI = function() {
- this.fallbackButton.classList.add('hidden');
- this.container[0].classList.add('hidden');
- this.fallbackUI.classList.remove('hidden');
- };
+U2FAuthenticate.prototype.switchToFallbackUI = function() {
+ this.fallbackButton.classList.add('hidden');
+ this.container[0].classList.add('hidden');
+ this.fallbackUI.classList.remove('hidden');
+};
- return U2FAuthenticate;
- })();
-})();
+global.U2FAuthenticate = U2FAuthenticate;
diff --git a/app/assets/javascripts/u2f/error.js b/app/assets/javascripts/u2f/error.js
index 3119b3480c3..f4a436c9f76 100644
--- a/app/assets/javascripts/u2f/error.js
+++ b/app/assets/javascripts/u2f/error.js
@@ -1,25 +1,21 @@
/* eslint-disable func-names, space-before-function-paren, no-var, prefer-rest-params, wrap-iife, no-console, quotes, prefer-template, max-len */
/* global u2f */
-(function() {
- this.U2FError = (function() {
- function U2FError(errorCode, u2fFlowType) {
- this.errorCode = errorCode;
- this.message = this.message.bind(this);
- this.httpsDisabled = window.location.protocol !== 'https:';
- this.u2fFlowType = u2fFlowType;
- }
+function U2FError(errorCode, u2fFlowType) {
+ this.errorCode = errorCode;
+ this.message = this.message.bind(this);
+ this.httpsDisabled = window.location.protocol !== 'https:';
+ this.u2fFlowType = u2fFlowType;
+}
- U2FError.prototype.message = function() {
- if (this.errorCode === u2f.ErrorCodes.BAD_REQUEST && this.httpsDisabled) {
- return 'U2F only works with HTTPS-enabled websites. Contact your administrator for more details.';
- } else if (this.errorCode === u2f.ErrorCodes.DEVICE_INELIGIBLE) {
- if (this.u2fFlowType === 'authenticate') return 'This device has not been registered with us.';
- if (this.u2fFlowType === 'register') return 'This device has already been registered with us.';
- }
- return "There was a problem communicating with your device.";
- };
+U2FError.prototype.message = function() {
+ if (this.errorCode === u2f.ErrorCodes.BAD_REQUEST && this.httpsDisabled) {
+ return 'U2F only works with HTTPS-enabled websites. Contact your administrator for more details.';
+ } else if (this.errorCode === u2f.ErrorCodes.DEVICE_INELIGIBLE) {
+ if (this.u2fFlowType === 'authenticate') return 'This device has not been registered with us.';
+ if (this.u2fFlowType === 'register') return 'This device has already been registered with us.';
+ }
+ return "There was a problem communicating with your device.";
+};
- return U2FError;
- })();
-}).call(window);
+window.U2FError = U2FError;
diff --git a/app/assets/javascripts/u2f/register.js b/app/assets/javascripts/u2f/register.js
index 1234d17b8fd..38395710ad4 100644
--- a/app/assets/javascripts/u2f/register.js
+++ b/app/assets/javascripts/u2f/register.js
@@ -7,90 +7,84 @@
//
// State Flow #1: setup -> in_progress -> registered -> POST to server
// State Flow #2: setup -> in_progress -> error -> setup
-(function() {
- this.U2FRegister = (function() {
- function U2FRegister(container, u2fParams) {
- this.container = container;
- this.renderNotSupported = this.renderNotSupported.bind(this);
- this.renderRegistered = this.renderRegistered.bind(this);
- this.renderError = this.renderError.bind(this);
- this.renderInProgress = this.renderInProgress.bind(this);
- this.renderSetup = this.renderSetup.bind(this);
- this.renderTemplate = this.renderTemplate.bind(this);
- this.register = this.register.bind(this);
- this.start = this.start.bind(this);
- this.appId = u2fParams.app_id;
- this.registerRequests = u2fParams.register_requests;
- this.signRequests = u2fParams.sign_requests;
- }
+function U2FRegister(container, u2fParams) {
+ this.container = container;
+ this.renderNotSupported = this.renderNotSupported.bind(this);
+ this.renderRegistered = this.renderRegistered.bind(this);
+ this.renderError = this.renderError.bind(this);
+ this.renderInProgress = this.renderInProgress.bind(this);
+ this.renderSetup = this.renderSetup.bind(this);
+ this.renderTemplate = this.renderTemplate.bind(this);
+ this.register = this.register.bind(this);
+ this.start = this.start.bind(this);
+ this.appId = u2fParams.app_id;
+ this.registerRequests = u2fParams.register_requests;
+ this.signRequests = u2fParams.sign_requests;
+}
- U2FRegister.prototype.start = function() {
- if (U2FUtil.isU2FSupported()) {
- return this.renderSetup();
- } else {
- return this.renderNotSupported();
- }
- };
+U2FRegister.prototype.start = function() {
+ if (U2FUtil.isU2FSupported()) {
+ return this.renderSetup();
+ } else {
+ return this.renderNotSupported();
+ }
+};
- U2FRegister.prototype.register = function() {
- return u2f.register(this.appId, this.registerRequests, this.signRequests, (function(_this) {
- return function(response) {
- var error;
- if (response.errorCode) {
- error = new U2FError(response.errorCode, 'register');
- return _this.renderError(error);
- } else {
- return _this.renderRegistered(JSON.stringify(response));
- }
- };
- })(this), 10);
- };
+U2FRegister.prototype.register = function() {
+ return u2f.register(this.appId, this.registerRequests, this.signRequests, (response) => {
+ var error;
+ if (response.errorCode) {
+ error = new U2FError(response.errorCode, 'register');
+ return this.renderError(error);
+ } else {
+ return this.renderRegistered(JSON.stringify(response));
+ }
+ }, 10);
+};
- // Rendering #
- U2FRegister.prototype.templates = {
- "notSupported": "#js-register-u2f-not-supported",
- "setup": '#js-register-u2f-setup',
- "inProgress": '#js-register-u2f-in-progress',
- "error": '#js-register-u2f-error',
- "registered": '#js-register-u2f-registered'
- };
+// Rendering #
+U2FRegister.prototype.templates = {
+ "notSupported": "#js-register-u2f-not-supported",
+ "setup": '#js-register-u2f-setup',
+ "inProgress": '#js-register-u2f-in-progress',
+ "error": '#js-register-u2f-error',
+ "registered": '#js-register-u2f-registered'
+};
- U2FRegister.prototype.renderTemplate = function(name, params) {
- var template, templateString;
- templateString = $(this.templates[name]).html();
- template = _.template(templateString);
- return this.container.html(template(params));
- };
+U2FRegister.prototype.renderTemplate = function(name, params) {
+ var template, templateString;
+ templateString = $(this.templates[name]).html();
+ template = _.template(templateString);
+ return this.container.html(template(params));
+};
- U2FRegister.prototype.renderSetup = function() {
- this.renderTemplate('setup');
- return this.container.find('#js-setup-u2f-device').on('click', this.renderInProgress);
- };
+U2FRegister.prototype.renderSetup = function() {
+ this.renderTemplate('setup');
+ return this.container.find('#js-setup-u2f-device').on('click', this.renderInProgress);
+};
- U2FRegister.prototype.renderInProgress = function() {
- this.renderTemplate('inProgress');
- return this.register();
- };
+U2FRegister.prototype.renderInProgress = function() {
+ this.renderTemplate('inProgress');
+ return this.register();
+};
- U2FRegister.prototype.renderError = function(error) {
- this.renderTemplate('error', {
- error_message: error.message(),
- error_code: error.errorCode
- });
- return this.container.find('#js-u2f-try-again').on('click', this.renderSetup);
- };
+U2FRegister.prototype.renderError = function(error) {
+ this.renderTemplate('error', {
+ error_message: error.message(),
+ error_code: error.errorCode
+ });
+ return this.container.find('#js-u2f-try-again').on('click', this.renderSetup);
+};
- 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);
- };
+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);
+};
- U2FRegister.prototype.renderNotSupported = function() {
- return this.renderTemplate('notSupported');
- };
+U2FRegister.prototype.renderNotSupported = function() {
+ return this.renderTemplate('notSupported');
+};
- return U2FRegister;
- })();
-}).call(window);
+window.U2FRegister = U2FRegister;
diff --git a/app/assets/javascripts/u2f/util.js b/app/assets/javascripts/u2f/util.js
index 813d363db00..bcf62276ccf 100644
--- a/app/assets/javascripts/u2f/util.js
+++ b/app/assets/javascripts/u2f/util.js
@@ -1,12 +1,8 @@
/* eslint-disable func-names, space-before-function-paren, wrap-iife */
-(function() {
- this.U2FUtil = (function() {
- function U2FUtil() {}
+function U2FUtil() {}
- U2FUtil.isU2FSupported = function() {
- return window.u2f;
- };
+U2FUtil.isU2FSupported = function() {
+ return window.u2f;
+};
- return U2FUtil;
- })();
-}).call(window);
+window.U2FUtil = U2FUtil;
diff --git a/spec/javascripts/abuse_reports_spec.js b/spec/javascripts/abuse_reports_spec.js
index 069d857eab6..99bae5858ae 100644
--- a/spec/javascripts/abuse_reports_spec.js
+++ b/spec/javascripts/abuse_reports_spec.js
@@ -1,43 +1,43 @@
import '~/lib/utils/text_utility';
import '~/abuse_reports';
-((global) => {
- describe('Abuse Reports', () => {
- const FIXTURE = 'abuse_reports/abuse_reports_list.html.raw';
- const MAX_MESSAGE_LENGTH = 500;
-
- let messages;
-
- const assertMaxLength = $message => expect($message.text().length).toEqual(MAX_MESSAGE_LENGTH);
- const findMessage = searchText => messages.filter(
- (index, element) => element.innerText.indexOf(searchText) > -1,
- ).first();
-
- preloadFixtures(FIXTURE);
-
- beforeEach(function () {
- loadFixtures(FIXTURE);
- this.abuseReports = new global.AbuseReports();
- messages = $('.abuse-reports .message');
- });
-
- it('should truncate long messages', () => {
- const $longMessage = findMessage('LONG MESSAGE');
- expect($longMessage.data('original-message')).toEqual(jasmine.anything());
- assertMaxLength($longMessage);
- });
-
- it('should not truncate short messages', () => {
- const $shortMessage = findMessage('SHORT MESSAGE');
- expect($shortMessage.data('original-message')).not.toEqual(jasmine.anything());
- });
-
- it('should allow clicking a truncated message to expand and collapse the full message', () => {
- const $longMessage = findMessage('LONG MESSAGE');
- $longMessage.click();
- expect($longMessage.data('original-message').length).toEqual($longMessage.text().length);
- $longMessage.click();
- assertMaxLength($longMessage);
- });
+const global = window.gl || (window.gl = {});
+
+describe('Abuse Reports', () => {
+ const FIXTURE = 'abuse_reports/abuse_reports_list.html.raw';
+ const MAX_MESSAGE_LENGTH = 500;
+
+ let messages;
+
+ const assertMaxLength = $message => expect($message.text().length).toEqual(MAX_MESSAGE_LENGTH);
+ const findMessage = searchText => messages.filter(
+ (index, element) => element.innerText.indexOf(searchText) > -1,
+ ).first();
+
+ preloadFixtures(FIXTURE);
+
+ beforeEach(function () {
+ loadFixtures(FIXTURE);
+ this.abuseReports = new global.AbuseReports();
+ messages = $('.abuse-reports .message');
+ });
+
+ it('should truncate long messages', () => {
+ const $longMessage = findMessage('LONG MESSAGE');
+ expect($longMessage.data('original-message')).toEqual(jasmine.anything());
+ assertMaxLength($longMessage);
+ });
+
+ it('should not truncate short messages', () => {
+ const $shortMessage = findMessage('SHORT MESSAGE');
+ expect($shortMessage.data('original-message')).not.toEqual(jasmine.anything());
+ });
+
+ it('should allow clicking a truncated message to expand and collapse the full message', () => {
+ const $longMessage = findMessage('LONG MESSAGE');
+ $longMessage.click();
+ expect($longMessage.data('original-message').length).toEqual($longMessage.text().length);
+ $longMessage.click();
+ assertMaxLength($longMessage);
});
-})(window.gl);
+});
diff --git a/spec/javascripts/activities_spec.js b/spec/javascripts/activities_spec.js
index e8c5f721423..a1ee4c9383a 100644
--- a/spec/javascripts/activities_spec.js
+++ b/spec/javascripts/activities_spec.js
@@ -4,59 +4,57 @@ import 'vendor/jquery.endless-scroll';
import '~/pager';
import '~/activities';
-(() => {
- window.gon || (window.gon = {});
- const fixtureTemplate = 'static/event_filter.html.raw';
- const filters = [
- {
- id: 'all',
- }, {
- id: 'push',
- name: 'push events',
- }, {
- id: 'merged',
- name: 'merge events',
- }, {
- id: 'comments',
- }, {
- id: 'team',
- }];
-
- function getEventName(index) {
- const filter = filters[index];
- return filter.hasOwnProperty('name') ? filter.name : filter.id;
- }
-
- function getSelector(index) {
- const filter = filters[index];
- return `#${filter.id}_event_filter`;
- }
+window.gon || (window.gon = {});
+const fixtureTemplate = 'static/event_filter.html.raw';
+const filters = [
+ {
+ id: 'all',
+ }, {
+ id: 'push',
+ name: 'push events',
+ }, {
+ id: 'merged',
+ name: 'merge events',
+ }, {
+ id: 'comments',
+ }, {
+ id: 'team',
+ }];
+
+function getEventName(index) {
+ const filter = filters[index];
+ return filter.hasOwnProperty('name') ? filter.name : filter.id;
+}
+
+function getSelector(index) {
+ const filter = filters[index];
+ return `#${filter.id}_event_filter`;
+}
+
+describe('Activities', () => {
+ beforeEach(() => {
+ loadFixtures(fixtureTemplate);
+ new gl.Activities();
+ });
- describe('Activities', () => {
- beforeEach(() => {
- loadFixtures(fixtureTemplate);
- new gl.Activities();
- });
-
- for (let i = 0; i < filters.length; i += 1) {
- ((i) => {
- describe(`when selecting ${getEventName(i)}`, () => {
- beforeEach(() => {
- $(getSelector(i)).click();
- });
-
- for (let x = 0; x < filters.length; x += 1) {
- ((x) => {
- const shouldHighlight = i === x;
- const testName = shouldHighlight ? 'should highlight' : 'should not highlight';
-
- it(`${testName} ${getEventName(x)}`, () => {
- expect($(getSelector(x)).parent().hasClass('active')).toEqual(shouldHighlight);
- });
- })(x);
- }
+ for (let i = 0; i < filters.length; i += 1) {
+ ((i) => {
+ describe(`when selecting ${getEventName(i)}`, () => {
+ beforeEach(() => {
+ $(getSelector(i)).click();
});
- })(i);
- }
- });
-})();
+
+ for (let x = 0; x < filters.length; x += 1) {
+ ((x) => {
+ const shouldHighlight = i === x;
+ const testName = shouldHighlight ? 'should highlight' : 'should not highlight';
+
+ it(`${testName} ${getEventName(x)}`, () => {
+ expect($(getSelector(x)).parent().hasClass('active')).toEqual(shouldHighlight);
+ });
+ })(x);
+ }
+ });
+ })(i);
+ }
+});
diff --git a/spec/javascripts/behaviors/autosize_spec.js b/spec/javascripts/behaviors/autosize_spec.js
index 67afba19190..3bc1e9d2c88 100644
--- a/spec/javascripts/behaviors/autosize_spec.js
+++ b/spec/javascripts/behaviors/autosize_spec.js
@@ -2,20 +2,18 @@
import '~/behaviors/autosize';
-(function() {
- describe('Autosize behavior', function() {
- var load;
- beforeEach(function() {
- return setFixtures('<textarea class="js-autosize" style="resize: vertical"></textarea>');
- });
- it('does not overwrite the resize property', function() {
- load();
- return expect($('textarea')).toHaveCss({
- resize: 'vertical'
- });
+describe('Autosize behavior', function() {
+ var load;
+ beforeEach(function() {
+ return setFixtures('<textarea class="js-autosize" style="resize: vertical"></textarea>');
+ });
+ it('does not overwrite the resize property', function() {
+ load();
+ return expect($('textarea')).toHaveCss({
+ resize: 'vertical'
});
- return load = function() {
- return $(document).trigger('load');
- };
});
-}).call(window);
+ return load = function() {
+ return $(document).trigger('load');
+ };
+});
diff --git a/spec/javascripts/behaviors/quick_submit_spec.js b/spec/javascripts/behaviors/quick_submit_spec.js
index 6dc48f9a293..3546bd698eb 100644
--- a/spec/javascripts/behaviors/quick_submit_spec.js
+++ b/spec/javascripts/behaviors/quick_submit_spec.js
@@ -2,118 +2,116 @@
import '~/behaviors/quick_submit';
-(function() {
- describe('Quick Submit behavior', function() {
- var keydownEvent;
- preloadFixtures('issues/open-issue.html.raw');
- beforeEach(function() {
- loadFixtures('issues/open-issue.html.raw');
- $('form').submit(function(e) {
- // Prevent a form submit from moving us off the testing page
- return e.preventDefault();
- });
- this.spies = {
- submit: spyOnEvent('form', 'submit')
- };
+describe('Quick Submit behavior', function() {
+ var keydownEvent;
+ preloadFixtures('issues/open-issue.html.raw');
+ beforeEach(function() {
+ loadFixtures('issues/open-issue.html.raw');
+ $('form').submit(function(e) {
+ // Prevent a form submit from moving us off the testing page
+ return e.preventDefault();
+ });
+ this.spies = {
+ submit: spyOnEvent('form', 'submit')
+ };
+
+ this.textarea = $('.js-quick-submit textarea').first();
+ });
+ it('does not respond to other keyCodes', function() {
+ this.textarea.trigger(keydownEvent({
+ keyCode: 32
+ }));
+ return expect(this.spies.submit).not.toHaveBeenTriggered();
+ });
+ it('does not respond to Enter alone', function() {
+ this.textarea.trigger(keydownEvent({
+ ctrlKey: false,
+ metaKey: false
+ }));
+ return expect(this.spies.submit).not.toHaveBeenTriggered();
+ });
+ it('does not respond to repeated events', function() {
+ this.textarea.trigger(keydownEvent({
+ repeat: true
+ }));
+ return expect(this.spies.submit).not.toHaveBeenTriggered();
+ });
+ it('disables input of type submit', function() {
+ const submitButton = $('.js-quick-submit input[type=submit]');
+ this.textarea.trigger(keydownEvent());
+
+ expect(submitButton).toBeDisabled();
+ });
+ it('disables button of type submit', function() {
+ const submitButton = $('.js-quick-submit input[type=submit]');
+ this.textarea.trigger(keydownEvent());
- this.textarea = $('.js-quick-submit textarea').first();
+ expect(submitButton).toBeDisabled();
+ });
+ it('only clicks one submit', function() {
+ const existingSubmit = $('.js-quick-submit input[type=submit]');
+ // Add an extra submit button
+ const newSubmit = $('<button type="submit">Submit it</button>');
+ newSubmit.insertAfter(this.textarea);
+
+ const oldClick = spyOnEvent(existingSubmit, 'click');
+ const newClick = spyOnEvent(newSubmit, 'click');
+
+ this.textarea.trigger(keydownEvent());
+
+ expect(oldClick).not.toHaveBeenTriggered();
+ expect(newClick).toHaveBeenTriggered();
+ });
+ // We cannot stub `navigator.userAgent` for CI's `rake karma` 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() {
+ this.textarea.trigger(keydownEvent());
+ return expect(this.spies.submit).toHaveBeenTriggered();
});
- it('does not respond to other keyCodes', function() {
+ it('excludes other modifier keys', function() {
this.textarea.trigger(keydownEvent({
- keyCode: 32
+ altKey: true
}));
- return expect(this.spies.submit).not.toHaveBeenTriggered();
- });
- it('does not respond to Enter alone', function() {
this.textarea.trigger(keydownEvent({
- ctrlKey: false,
- metaKey: false
+ ctrlKey: true
}));
- return expect(this.spies.submit).not.toHaveBeenTriggered();
- });
- it('does not respond to repeated events', function() {
this.textarea.trigger(keydownEvent({
- repeat: true
+ shiftKey: true
}));
return expect(this.spies.submit).not.toHaveBeenTriggered();
});
- it('disables input of type submit', function() {
- const submitButton = $('.js-quick-submit input[type=submit]');
+ } else {
+ it('responds to Ctrl+Enter', function() {
this.textarea.trigger(keydownEvent());
-
- expect(submitButton).toBeDisabled();
+ return expect(this.spies.submit).toHaveBeenTriggered();
});
- it('disables button of type submit', function() {
- const submitButton = $('.js-quick-submit input[type=submit]');
- this.textarea.trigger(keydownEvent());
-
- expect(submitButton).toBeDisabled();
- });
- it('only clicks one submit', function() {
- const existingSubmit = $('.js-quick-submit input[type=submit]');
- // Add an extra submit button
- const newSubmit = $('<button type="submit">Submit it</button>');
- newSubmit.insertAfter(this.textarea);
-
- const oldClick = spyOnEvent(existingSubmit, 'click');
- const newClick = spyOnEvent(newSubmit, 'click');
-
- this.textarea.trigger(keydownEvent());
-
- expect(oldClick).not.toHaveBeenTriggered();
- expect(newClick).toHaveBeenTriggered();
+ it('excludes other modifier keys', function() {
+ this.textarea.trigger(keydownEvent({
+ altKey: true
+ }));
+ this.textarea.trigger(keydownEvent({
+ metaKey: true
+ }));
+ this.textarea.trigger(keydownEvent({
+ shiftKey: true
+ }));
+ return expect(this.spies.submit).not.toHaveBeenTriggered();
});
- // We cannot stub `navigator.userAgent` for CI's `rake karma` task, so we'll
- // only run the tests that apply to the current platform
+ }
+ return keydownEvent = function(options) {
+ var defaults;
if (navigator.userAgent.match(/Macintosh/)) {
- it('responds to Meta+Enter', function() {
- this.textarea.trigger(keydownEvent());
- return expect(this.spies.submit).toHaveBeenTriggered();
- });
- it('excludes other modifier keys', function() {
- this.textarea.trigger(keydownEvent({
- altKey: true
- }));
- this.textarea.trigger(keydownEvent({
- ctrlKey: true
- }));
- this.textarea.trigger(keydownEvent({
- shiftKey: true
- }));
- return expect(this.spies.submit).not.toHaveBeenTriggered();
- });
+ defaults = {
+ keyCode: 13,
+ metaKey: true
+ };
} else {
- it('responds to Ctrl+Enter', function() {
- this.textarea.trigger(keydownEvent());
- return expect(this.spies.submit).toHaveBeenTriggered();
- });
- it('excludes other modifier keys', function() {
- this.textarea.trigger(keydownEvent({
- altKey: true
- }));
- this.textarea.trigger(keydownEvent({
- metaKey: true
- }));
- this.textarea.trigger(keydownEvent({
- shiftKey: true
- }));
- return expect(this.spies.submit).not.toHaveBeenTriggered();
- });
+ defaults = {
+ keyCode: 13,
+ ctrlKey: true
+ };
}
- return keydownEvent = function(options) {
- var defaults;
- if (navigator.userAgent.match(/Macintosh/)) {
- defaults = {
- keyCode: 13,
- metaKey: true
- };
- } else {
- defaults = {
- keyCode: 13,
- ctrlKey: true
- };
- }
- return $.Event('keydown', $.extend({}, defaults, options));
- };
- });
-}).call(window);
+ return $.Event('keydown', $.extend({}, defaults, options));
+ };
+});
diff --git a/spec/javascripts/behaviors/requires_input_spec.js b/spec/javascripts/behaviors/requires_input_spec.js
index f9fa814b801..22d6504f917 100644
--- a/spec/javascripts/behaviors/requires_input_spec.js
+++ b/spec/javascripts/behaviors/requires_input_spec.js
@@ -2,38 +2,36 @@
import '~/behaviors/requires_input';
-(function() {
- describe('requiresInput', function() {
- preloadFixtures('branches/new_branch.html.raw');
- beforeEach(function() {
- loadFixtures('branches/new_branch.html.raw');
- this.submitButton = $('button[type="submit"]');
- });
- it('disables submit when any field is required', function() {
- $('.js-requires-input').requiresInput();
- return expect(this.submitButton).toBeDisabled();
- });
- it('enables submit when no field is required', function() {
- $('*[required=required]').removeAttr('required');
- $('.js-requires-input').requiresInput();
- return expect(this.submitButton).not.toBeDisabled();
- });
- it('enables submit when all required fields are pre-filled', function() {
- $('*[required=required]').remove();
- $('.js-requires-input').requiresInput();
- return expect($('.submit')).not.toBeDisabled();
- });
- it('enables submit when all required fields receive input', function() {
- $('.js-requires-input').requiresInput();
- $('#required1').val('input1').change();
- expect(this.submitButton).toBeDisabled();
- $('#optional1').val('input1').change();
- expect(this.submitButton).toBeDisabled();
- $('#required2').val('input2').change();
- $('#required3').val('input3').change();
- $('#required4').val('input4').change();
- $('#required5').val('1').change();
- return expect($('.submit')).not.toBeDisabled();
- });
+describe('requiresInput', function() {
+ preloadFixtures('branches/new_branch.html.raw');
+ beforeEach(function() {
+ loadFixtures('branches/new_branch.html.raw');
+ this.submitButton = $('button[type="submit"]');
});
-}).call(window);
+ it('disables submit when any field is required', function() {
+ $('.js-requires-input').requiresInput();
+ return expect(this.submitButton).toBeDisabled();
+ });
+ it('enables submit when no field is required', function() {
+ $('*[required=required]').removeAttr('required');
+ $('.js-requires-input').requiresInput();
+ return expect(this.submitButton).not.toBeDisabled();
+ });
+ it('enables submit when all required fields are pre-filled', function() {
+ $('*[required=required]').remove();
+ $('.js-requires-input').requiresInput();
+ return expect($('.submit')).not.toBeDisabled();
+ });
+ it('enables submit when all required fields receive input', function() {
+ $('.js-requires-input').requiresInput();
+ $('#required1').val('input1').change();
+ expect(this.submitButton).toBeDisabled();
+ $('#optional1').val('input1').change();
+ expect(this.submitButton).toBeDisabled();
+ $('#required2').val('input2').change();
+ $('#required3').val('input3').change();
+ $('#required4').val('input4').change();
+ $('#required5').val('1').change();
+ return expect($('.submit')).not.toBeDisabled();
+ });
+});
diff --git a/spec/javascripts/commits_spec.js b/spec/javascripts/commits_spec.js
index ace95000468..c0154d102d0 100644
--- a/spec/javascripts/commits_spec.js
+++ b/spec/javascripts/commits_spec.js
@@ -4,74 +4,72 @@ import 'vendor/jquery.endless-scroll';
import '~/pager';
import '~/commits';
-(() => {
- describe('Commits List', () => {
- beforeEach(() => {
- setFixtures(`
- <form class="commits-search-form" action="/h5bp/html5-boilerplate/commits/master">
- <input id="commits-search">
- </form>
- <ol id="commits-list"></ol>
- `);
- });
-
- it('should be defined', () => {
- expect(CommitsList).toBeDefined();
- });
+describe('Commits List', () => {
+ beforeEach(() => {
+ setFixtures(`
+ <form class="commits-search-form" action="/h5bp/html5-boilerplate/commits/master">
+ <input id="commits-search">
+ </form>
+ <ol id="commits-list"></ol>
+ `);
+ });
- describe('processCommits', () => {
- it('should join commit headers', () => {
- CommitsList.$contentList = $(`
- <div>
- <li class="commit-header" data-day="2016-09-20">
- <span class="day">20 Sep, 2016</span>
- <span class="commits-count">1 commit</span>
- </li>
- <li class="commit"></li>
- </div>
- `);
+ it('should be defined', () => {
+ expect(CommitsList).toBeDefined();
+ });
- const data = `
+ describe('processCommits', () => {
+ it('should join commit headers', () => {
+ CommitsList.$contentList = $(`
+ <div>
<li class="commit-header" data-day="2016-09-20">
<span class="day">20 Sep, 2016</span>
<span class="commits-count">1 commit</span>
</li>
<li class="commit"></li>
- `;
+ </div>
+ `);
- // The last commit header should be removed
- // since the previous one has the same data-day value.
- expect(CommitsList.processCommits(data).find('li.commit-header').length).toBe(0);
- });
+ const data = `
+ <li class="commit-header" data-day="2016-09-20">
+ <span class="day">20 Sep, 2016</span>
+ <span class="commits-count">1 commit</span>
+ </li>
+ <li class="commit"></li>
+ `;
+
+ // The last commit header should be removed
+ // since the previous one has the same data-day value.
+ expect(CommitsList.processCommits(data).find('li.commit-header').length).toBe(0);
});
+ });
- describe('on entering input', () => {
- let ajaxSpy;
+ describe('on entering input', () => {
+ let ajaxSpy;
- beforeEach(() => {
- CommitsList.init(25);
- CommitsList.searchField.val('');
+ beforeEach(() => {
+ CommitsList.init(25);
+ CommitsList.searchField.val('');
- spyOn(history, 'replaceState').and.stub();
- ajaxSpy = spyOn(jQuery, 'ajax').and.callFake((req) => {
- req.success({
- data: '<li>Result</li>',
- });
+ spyOn(history, 'replaceState').and.stub();
+ ajaxSpy = spyOn(jQuery, 'ajax').and.callFake((req) => {
+ req.success({
+ data: '<li>Result</li>',
});
});
+ });
- it('should save the last search string', () => {
- CommitsList.searchField.val('GitLab');
- CommitsList.filterResults();
- expect(ajaxSpy).toHaveBeenCalled();
- expect(CommitsList.lastSearch).toEqual('GitLab');
- });
+ it('should save the last search string', () => {
+ CommitsList.searchField.val('GitLab');
+ CommitsList.filterResults();
+ expect(ajaxSpy).toHaveBeenCalled();
+ expect(CommitsList.lastSearch).toEqual('GitLab');
+ });
- it('should not make ajax call if the input does not change', () => {
- CommitsList.filterResults();
- expect(ajaxSpy).not.toHaveBeenCalled();
- expect(CommitsList.lastSearch).toEqual('');
- });
+ it('should not make ajax call if the input does not change', () => {
+ CommitsList.filterResults();
+ expect(ajaxSpy).not.toHaveBeenCalled();
+ expect(CommitsList.lastSearch).toEqual('');
});
});
-})();
+});
diff --git a/spec/javascripts/copy_as_gfm_spec.js b/spec/javascripts/copy_as_gfm_spec.js
index ded450749d3..b8994d565ab 100644
--- a/spec/javascripts/copy_as_gfm_spec.js
+++ b/spec/javascripts/copy_as_gfm_spec.js
@@ -1,49 +1,47 @@
import '~/copy_as_gfm';
-(() => {
- describe('gl.CopyAsGFM', () => {
- describe('gl.CopyAsGFM.pasteGFM', () => {
- function callPasteGFM() {
- const e = {
- originalEvent: {
- clipboardData: {
- getData(mimeType) {
- // When GFM code is copied, we put the regular plain text
- // on the clipboard as `text/plain`, and the GFM as `text/x-gfm`.
- // This emulates the behavior of `getData` with that data.
- if (mimeType === 'text/plain') {
- return 'code';
- }
- if (mimeType === 'text/x-gfm') {
- return '`code`';
- }
- return null;
- },
+describe('gl.CopyAsGFM', () => {
+ describe('gl.CopyAsGFM.pasteGFM', () => {
+ function callPasteGFM() {
+ const e = {
+ originalEvent: {
+ clipboardData: {
+ getData(mimeType) {
+ // When GFM code is copied, we put the regular plain text
+ // on the clipboard as `text/plain`, and the GFM as `text/x-gfm`.
+ // This emulates the behavior of `getData` with that data.
+ if (mimeType === 'text/plain') {
+ return 'code';
+ }
+ if (mimeType === 'text/x-gfm') {
+ return '`code`';
+ }
+ return null;
},
},
- preventDefault() {},
- };
+ },
+ preventDefault() {},
+ };
- window.gl.CopyAsGFM.pasteGFM(e);
- }
+ window.gl.CopyAsGFM.pasteGFM(e);
+ }
- it('wraps pasted code when not already in code tags', () => {
- spyOn(window.gl.utils, 'insertText').and.callFake((el, textFunc) => {
- const insertedText = textFunc('This is code: ', '');
- expect(insertedText).toEqual('`code`');
- });
-
- callPasteGFM();
+ it('wraps pasted code when not already in code tags', () => {
+ spyOn(window.gl.utils, 'insertText').and.callFake((el, textFunc) => {
+ const insertedText = textFunc('This is code: ', '');
+ expect(insertedText).toEqual('`code`');
});
- it('does not wrap pasted code when already in code tags', () => {
- spyOn(window.gl.utils, 'insertText').and.callFake((el, textFunc) => {
- const insertedText = textFunc('This is code: `', '`');
- expect(insertedText).toEqual('code');
- });
+ callPasteGFM();
+ });
- callPasteGFM();
+ it('does not wrap pasted code when already in code tags', () => {
+ spyOn(window.gl.utils, 'insertText').and.callFake((el, textFunc) => {
+ const insertedText = textFunc('This is code: `', '`');
+ expect(insertedText).toEqual('code');
});
+
+ callPasteGFM();
});
});
-})();
+});
diff --git a/spec/javascripts/datetime_utility_spec.js b/spec/javascripts/datetime_utility_spec.js
index 3391cade541..e2a9ab62b48 100644
--- a/spec/javascripts/datetime_utility_spec.js
+++ b/spec/javascripts/datetime_utility_spec.js
@@ -1,98 +1,96 @@
import { timeIntervalInWords } from '~/lib/utils/datetime_utility';
-(() => {
- describe('Date time utils', () => {
- describe('timeFor', () => {
- it('returns `past due` when in past', () => {
- const date = new Date();
- date.setFullYear(date.getFullYear() - 1);
-
- expect(
- gl.utils.timeFor(date),
- ).toBe('Past due');
- });
-
- it('returns remaining time when in the future', () => {
- const date = new Date();
- date.setFullYear(date.getFullYear() + 1);
-
- // Add a day to prevent a transient error. If date is even 1 second
- // short of a full year, timeFor will return '11 months remaining'
- date.setDate(date.getDate() + 1);
-
- expect(
- gl.utils.timeFor(date),
- ).toBe('1 year remaining');
- });
+describe('Date time utils', () => {
+ describe('timeFor', () => {
+ it('returns `past due` when in past', () => {
+ const date = new Date();
+ date.setFullYear(date.getFullYear() - 1);
+
+ expect(
+ gl.utils.timeFor(date),
+ ).toBe('Past due');
});
- describe('get day name', () => {
- it('should return Sunday', () => {
- const day = gl.utils.getDayName(new Date('07/17/2016'));
- expect(day).toBe('Sunday');
- });
-
- it('should return Monday', () => {
- const day = gl.utils.getDayName(new Date('07/18/2016'));
- expect(day).toBe('Monday');
- });
-
- it('should return Tuesday', () => {
- const day = gl.utils.getDayName(new Date('07/19/2016'));
- expect(day).toBe('Tuesday');
- });
-
- it('should return Wednesday', () => {
- const day = gl.utils.getDayName(new Date('07/20/2016'));
- expect(day).toBe('Wednesday');
- });
-
- it('should return Thursday', () => {
- const day = gl.utils.getDayName(new Date('07/21/2016'));
- expect(day).toBe('Thursday');
- });
-
- it('should return Friday', () => {
- const day = gl.utils.getDayName(new Date('07/22/2016'));
- expect(day).toBe('Friday');
- });
-
- it('should return Saturday', () => {
- const day = gl.utils.getDayName(new Date('07/23/2016'));
- expect(day).toBe('Saturday');
- });
+ it('returns remaining time when in the future', () => {
+ const date = new Date();
+ date.setFullYear(date.getFullYear() + 1);
+
+ // Add a day to prevent a transient error. If date is even 1 second
+ // short of a full year, timeFor will return '11 months remaining'
+ date.setDate(date.getDate() + 1);
+
+ expect(
+ gl.utils.timeFor(date),
+ ).toBe('1 year remaining');
+ });
+ });
+
+ describe('get day name', () => {
+ it('should return Sunday', () => {
+ const day = gl.utils.getDayName(new Date('07/17/2016'));
+ expect(day).toBe('Sunday');
+ });
+
+ it('should return Monday', () => {
+ const day = gl.utils.getDayName(new Date('07/18/2016'));
+ expect(day).toBe('Monday');
+ });
+
+ it('should return Tuesday', () => {
+ const day = gl.utils.getDayName(new Date('07/19/2016'));
+ expect(day).toBe('Tuesday');
+ });
+
+ it('should return Wednesday', () => {
+ const day = gl.utils.getDayName(new Date('07/20/2016'));
+ expect(day).toBe('Wednesday');
+ });
+
+ it('should return Thursday', () => {
+ const day = gl.utils.getDayName(new Date('07/21/2016'));
+ expect(day).toBe('Thursday');
+ });
+
+ it('should return Friday', () => {
+ const day = gl.utils.getDayName(new Date('07/22/2016'));
+ expect(day).toBe('Friday');
});
- describe('get day difference', () => {
- it('should return 7', () => {
- const firstDay = new Date('07/01/2016');
- const secondDay = new Date('07/08/2016');
- const difference = gl.utils.getDayDifference(firstDay, secondDay);
- expect(difference).toBe(7);
- });
-
- it('should return 31', () => {
- const firstDay = new Date('07/01/2016');
- const secondDay = new Date('08/01/2016');
- const difference = gl.utils.getDayDifference(firstDay, secondDay);
- expect(difference).toBe(31);
- });
-
- it('should return 365', () => {
- const firstDay = new Date('07/02/2015');
- const secondDay = new Date('07/01/2016');
- const difference = gl.utils.getDayDifference(firstDay, secondDay);
- expect(difference).toBe(365);
- });
+ it('should return Saturday', () => {
+ const day = gl.utils.getDayName(new Date('07/23/2016'));
+ expect(day).toBe('Saturday');
});
});
- describe('timeIntervalInWords', () => {
- it('should return string with number of minutes and seconds', () => {
- expect(timeIntervalInWords(9.54)).toEqual('9 seconds');
- expect(timeIntervalInWords(1)).toEqual('1 second');
- expect(timeIntervalInWords(200)).toEqual('3 minutes 20 seconds');
- expect(timeIntervalInWords(6008)).toEqual('100 minutes 8 seconds');
+ describe('get day difference', () => {
+ it('should return 7', () => {
+ const firstDay = new Date('07/01/2016');
+ const secondDay = new Date('07/08/2016');
+ const difference = gl.utils.getDayDifference(firstDay, secondDay);
+ expect(difference).toBe(7);
});
+
+ it('should return 31', () => {
+ const firstDay = new Date('07/01/2016');
+ const secondDay = new Date('08/01/2016');
+ const difference = gl.utils.getDayDifference(firstDay, secondDay);
+ expect(difference).toBe(31);
+ });
+
+ it('should return 365', () => {
+ const firstDay = new Date('07/02/2015');
+ const secondDay = new Date('07/01/2016');
+ const difference = gl.utils.getDayDifference(firstDay, secondDay);
+ expect(difference).toBe(365);
+ });
+ });
+});
+
+describe('timeIntervalInWords', () => {
+ it('should return string with number of minutes and seconds', () => {
+ expect(timeIntervalInWords(9.54)).toEqual('9 seconds');
+ expect(timeIntervalInWords(1)).toEqual('1 second');
+ expect(timeIntervalInWords(200)).toEqual('3 minutes 20 seconds');
+ expect(timeIntervalInWords(6008)).toEqual('100 minutes 8 seconds');
});
-})();
+});
diff --git a/spec/javascripts/extensions/array_spec.js b/spec/javascripts/extensions/array_spec.js
index b1b81b4efc2..20dae79785c 100644
--- a/spec/javascripts/extensions/array_spec.js
+++ b/spec/javascripts/extensions/array_spec.js
@@ -2,21 +2,19 @@
import '~/extensions/array';
-(function() {
- describe('Array extensions', function() {
- describe('first', function() {
- return it('returns the first item', function() {
- var arr;
- arr = [0, 1, 2, 3, 4, 5];
- return expect(arr.first()).toBe(0);
- });
+describe('Array extensions', function() {
+ describe('first', function() {
+ return it('returns the first item', function() {
+ var arr;
+ arr = [0, 1, 2, 3, 4, 5];
+ return expect(arr.first()).toBe(0);
});
- describe('last', function() {
- return it('returns the last item', function() {
- var arr;
- arr = [0, 1, 2, 3, 4, 5];
- return expect(arr.last()).toBe(5);
- });
+ });
+ describe('last', function() {
+ return it('returns the last item', function() {
+ var arr;
+ arr = [0, 1, 2, 3, 4, 5];
+ return expect(arr.last()).toBe(5);
});
});
-}).call(window);
+});
diff --git a/spec/javascripts/lib/utils/common_utils_spec.js b/spec/javascripts/lib/utils/common_utils_spec.js
index 55037bbbf73..3f18b1d57ec 100644
--- a/spec/javascripts/lib/utils/common_utils_spec.js
+++ b/spec/javascripts/lib/utils/common_utils_spec.js
@@ -2,395 +2,393 @@
import '~/lib/utils/common_utils';
-(() => {
- describe('common_utils', () => {
- describe('gl.utils.parseUrl', () => {
- it('returns an anchor tag with url', () => {
- expect(gl.utils.parseUrl('/some/absolute/url').pathname).toContain('some/absolute/url');
- });
- it('url is escaped', () => {
- // IE11 will return a relative pathname while other browsers will return a full pathname.
- // parseUrl uses an anchor element for parsing an url. With relative urls, the anchor
- // element will create an absolute url relative to the current execution context.
- // The JavaScript test suite is executed at '/' which will lead to an absolute url
- // starting with '/'.
- expect(gl.utils.parseUrl('" test="asf"').pathname).toContain('/%22%20test=%22asf%22');
- });
+describe('common_utils', () => {
+ describe('gl.utils.parseUrl', () => {
+ it('returns an anchor tag with url', () => {
+ expect(gl.utils.parseUrl('/some/absolute/url').pathname).toContain('some/absolute/url');
+ });
+ it('url is escaped', () => {
+ // IE11 will return a relative pathname while other browsers will return a full pathname.
+ // parseUrl uses an anchor element for parsing an url. With relative urls, the anchor
+ // element will create an absolute url relative to the current execution context.
+ // The JavaScript test suite is executed at '/' which will lead to an absolute url
+ // starting with '/'.
+ expect(gl.utils.parseUrl('" test="asf"').pathname).toContain('/%22%20test=%22asf%22');
});
+ });
- describe('gl.utils.parseUrlPathname', () => {
- beforeEach(() => {
- spyOn(gl.utils, 'parseUrl').and.callFake(url => ({
- pathname: url,
- }));
- });
- it('returns an absolute url when given an absolute url', () => {
- expect(gl.utils.parseUrlPathname('/some/absolute/url')).toEqual('/some/absolute/url');
- });
- it('returns an absolute url when given a relative url', () => {
- expect(gl.utils.parseUrlPathname('some/relative/url')).toEqual('/some/relative/url');
- });
+ describe('gl.utils.parseUrlPathname', () => {
+ beforeEach(() => {
+ spyOn(gl.utils, 'parseUrl').and.callFake(url => ({
+ pathname: url,
+ }));
+ });
+ it('returns an absolute url when given an absolute url', () => {
+ expect(gl.utils.parseUrlPathname('/some/absolute/url')).toEqual('/some/absolute/url');
});
+ it('returns an absolute url when given a relative url', () => {
+ expect(gl.utils.parseUrlPathname('some/relative/url')).toEqual('/some/relative/url');
+ });
+ });
- describe('gl.utils.getUrlParamsArray', () => {
- it('should return params array', () => {
- expect(gl.utils.getUrlParamsArray() instanceof Array).toBe(true);
- });
+ describe('gl.utils.getUrlParamsArray', () => {
+ it('should return params array', () => {
+ expect(gl.utils.getUrlParamsArray() instanceof Array).toBe(true);
+ });
- it('should remove the question mark from the search params', () => {
- const paramsArray = gl.utils.getUrlParamsArray();
- expect(paramsArray[0][0] !== '?').toBe(true);
- });
+ it('should remove the question mark from the search params', () => {
+ const paramsArray = gl.utils.getUrlParamsArray();
+ expect(paramsArray[0][0] !== '?').toBe(true);
+ });
- it('should decode params', () => {
- history.pushState('', '', '?label_name%5B%5D=test');
+ it('should decode params', () => {
+ history.pushState('', '', '?label_name%5B%5D=test');
- expect(
- gl.utils.getUrlParamsArray()[0],
- ).toBe('label_name[]=test');
+ expect(
+ gl.utils.getUrlParamsArray()[0],
+ ).toBe('label_name[]=test');
- history.pushState('', '', '?');
- });
+ history.pushState('', '', '?');
});
+ });
- describe('gl.utils.handleLocationHash', () => {
- beforeEach(() => {
- spyOn(window.document, 'getElementById').and.callThrough();
- });
+ describe('gl.utils.handleLocationHash', () => {
+ beforeEach(() => {
+ spyOn(window.document, 'getElementById').and.callThrough();
+ });
- afterEach(() => {
- window.history.pushState({}, null, '');
- });
+ afterEach(() => {
+ window.history.pushState({}, null, '');
+ });
- function expectGetElementIdToHaveBeenCalledWith(elementId) {
- expect(window.document.getElementById).toHaveBeenCalledWith(elementId);
- }
+ function expectGetElementIdToHaveBeenCalledWith(elementId) {
+ expect(window.document.getElementById).toHaveBeenCalledWith(elementId);
+ }
- it('decodes hash parameter', () => {
- window.history.pushState({}, null, '#random-hash');
- gl.utils.handleLocationHash();
+ it('decodes hash parameter', () => {
+ window.history.pushState({}, null, '#random-hash');
+ gl.utils.handleLocationHash();
- expectGetElementIdToHaveBeenCalledWith('random-hash');
- expectGetElementIdToHaveBeenCalledWith('user-content-random-hash');
- });
+ expectGetElementIdToHaveBeenCalledWith('random-hash');
+ expectGetElementIdToHaveBeenCalledWith('user-content-random-hash');
+ });
- it('decodes cyrillic hash parameter', () => {
- window.history.pushState({}, null, '#definição');
- gl.utils.handleLocationHash();
+ it('decodes cyrillic hash parameter', () => {
+ window.history.pushState({}, null, '#definição');
+ gl.utils.handleLocationHash();
- expectGetElementIdToHaveBeenCalledWith('definição');
- expectGetElementIdToHaveBeenCalledWith('user-content-definição');
- });
+ expectGetElementIdToHaveBeenCalledWith('definição');
+ expectGetElementIdToHaveBeenCalledWith('user-content-definição');
+ });
- it('decodes encoded cyrillic hash parameter', () => {
- window.history.pushState({}, null, '#defini%C3%A7%C3%A3o');
- gl.utils.handleLocationHash();
+ it('decodes encoded cyrillic hash parameter', () => {
+ window.history.pushState({}, null, '#defini%C3%A7%C3%A3o');
+ gl.utils.handleLocationHash();
- expectGetElementIdToHaveBeenCalledWith('definição');
- expectGetElementIdToHaveBeenCalledWith('user-content-definição');
- });
+ expectGetElementIdToHaveBeenCalledWith('definição');
+ expectGetElementIdToHaveBeenCalledWith('user-content-definição');
});
+ });
- describe('gl.utils.setParamInURL', () => {
- afterEach(() => {
- window.history.pushState({}, null, '');
- });
+ describe('gl.utils.setParamInURL', () => {
+ afterEach(() => {
+ window.history.pushState({}, null, '');
+ });
- it('should return the parameter', () => {
- window.history.replaceState({}, null, '');
+ it('should return the parameter', () => {
+ window.history.replaceState({}, null, '');
- expect(gl.utils.setParamInURL('page', 156)).toBe('?page=156');
- expect(gl.utils.setParamInURL('page', '156')).toBe('?page=156');
- });
+ expect(gl.utils.setParamInURL('page', 156)).toBe('?page=156');
+ expect(gl.utils.setParamInURL('page', '156')).toBe('?page=156');
+ });
- it('should update the existing parameter when its a number', () => {
- window.history.pushState({}, null, '?page=15');
+ it('should update the existing parameter when its a number', () => {
+ window.history.pushState({}, null, '?page=15');
- expect(gl.utils.setParamInURL('page', 16)).toBe('?page=16');
- expect(gl.utils.setParamInURL('page', '16')).toBe('?page=16');
- expect(gl.utils.setParamInURL('page', true)).toBe('?page=true');
- });
+ expect(gl.utils.setParamInURL('page', 16)).toBe('?page=16');
+ expect(gl.utils.setParamInURL('page', '16')).toBe('?page=16');
+ expect(gl.utils.setParamInURL('page', true)).toBe('?page=true');
+ });
- it('should update the existing parameter when its a string', () => {
- window.history.pushState({}, null, '?scope=all');
+ it('should update the existing parameter when its a string', () => {
+ window.history.pushState({}, null, '?scope=all');
- expect(gl.utils.setParamInURL('scope', 'finished')).toBe('?scope=finished');
- });
+ expect(gl.utils.setParamInURL('scope', 'finished')).toBe('?scope=finished');
+ });
- it('should update the existing parameter when more than one parameter exists', () => {
- window.history.pushState({}, null, '?scope=all&page=15');
+ it('should update the existing parameter when more than one parameter exists', () => {
+ window.history.pushState({}, null, '?scope=all&page=15');
- expect(gl.utils.setParamInURL('scope', 'finished')).toBe('?scope=finished&page=15');
- });
+ expect(gl.utils.setParamInURL('scope', 'finished')).toBe('?scope=finished&page=15');
+ });
- it('should add a new parameter to the end of the existing ones', () => {
- window.history.pushState({}, null, '?scope=all');
+ it('should add a new parameter to the end of the existing ones', () => {
+ window.history.pushState({}, null, '?scope=all');
- expect(gl.utils.setParamInURL('page', 16)).toBe('?scope=all&page=16');
- expect(gl.utils.setParamInURL('page', '16')).toBe('?scope=all&page=16');
- expect(gl.utils.setParamInURL('page', true)).toBe('?scope=all&page=true');
- });
+ expect(gl.utils.setParamInURL('page', 16)).toBe('?scope=all&page=16');
+ expect(gl.utils.setParamInURL('page', '16')).toBe('?scope=all&page=16');
+ expect(gl.utils.setParamInURL('page', true)).toBe('?scope=all&page=true');
});
+ });
- describe('gl.utils.getParameterByName', () => {
- beforeEach(() => {
- window.history.pushState({}, null, '?scope=all&p=2');
- });
+ describe('gl.utils.getParameterByName', () => {
+ beforeEach(() => {
+ window.history.pushState({}, null, '?scope=all&p=2');
+ });
- afterEach(() => {
- window.history.replaceState({}, null, null);
- });
+ afterEach(() => {
+ window.history.replaceState({}, null, null);
+ });
- it('should return valid parameter', () => {
- const value = gl.utils.getParameterByName('scope');
- expect(gl.utils.getParameterByName('p')).toEqual('2');
- expect(value).toBe('all');
- });
+ it('should return valid parameter', () => {
+ const value = gl.utils.getParameterByName('scope');
+ expect(gl.utils.getParameterByName('p')).toEqual('2');
+ expect(value).toBe('all');
+ });
- it('should return invalid parameter', () => {
- const value = gl.utils.getParameterByName('fakeParameter');
- expect(value).toBe(null);
- });
+ it('should return invalid parameter', () => {
+ const value = gl.utils.getParameterByName('fakeParameter');
+ expect(value).toBe(null);
+ });
- it('should return valid paramentes if URL is provided', () => {
- let value = gl.utils.getParameterByName('foo', 'http://cocteau.twins/?foo=bar');
- expect(value).toBe('bar');
+ it('should return valid paramentes if URL is provided', () => {
+ let value = gl.utils.getParameterByName('foo', 'http://cocteau.twins/?foo=bar');
+ expect(value).toBe('bar');
- value = gl.utils.getParameterByName('manan', 'http://cocteau.twins/?foo=bar&manan=canchu');
- expect(value).toBe('canchu');
- });
+ value = gl.utils.getParameterByName('manan', 'http://cocteau.twins/?foo=bar&manan=canchu');
+ expect(value).toBe('canchu');
});
+ });
- describe('gl.utils.normalizedHeaders', () => {
- it('should upperCase all the header keys to keep them consistent', () => {
- const apiHeaders = {
- 'X-Something-Workhorse': { workhorse: 'ok' },
- 'x-something-nginx': { nginx: 'ok' },
- };
+ describe('gl.utils.normalizedHeaders', () => {
+ it('should upperCase all the header keys to keep them consistent', () => {
+ const apiHeaders = {
+ 'X-Something-Workhorse': { workhorse: 'ok' },
+ 'x-something-nginx': { nginx: 'ok' },
+ };
- const normalized = gl.utils.normalizeHeaders(apiHeaders);
+ const normalized = gl.utils.normalizeHeaders(apiHeaders);
- const WORKHORSE = 'X-SOMETHING-WORKHORSE';
- const NGINX = 'X-SOMETHING-NGINX';
+ const WORKHORSE = 'X-SOMETHING-WORKHORSE';
+ const NGINX = 'X-SOMETHING-NGINX';
- expect(normalized[WORKHORSE].workhorse).toBe('ok');
- expect(normalized[NGINX].nginx).toBe('ok');
- });
+ expect(normalized[WORKHORSE].workhorse).toBe('ok');
+ expect(normalized[NGINX].nginx).toBe('ok');
});
+ });
- describe('gl.utils.normalizeCRLFHeaders', () => {
- beforeEach(function () {
- this.CLRFHeaders = 'a-header: a-value\nAnother-Header: ANOTHER-VALUE\nLaSt-HeAdEr: last-VALUE';
+ describe('gl.utils.normalizeCRLFHeaders', () => {
+ beforeEach(function () {
+ this.CLRFHeaders = 'a-header: a-value\nAnother-Header: ANOTHER-VALUE\nLaSt-HeAdEr: last-VALUE';
- spyOn(String.prototype, 'split').and.callThrough();
- spyOn(gl.utils, 'normalizeHeaders').and.callThrough();
+ spyOn(String.prototype, 'split').and.callThrough();
+ spyOn(gl.utils, 'normalizeHeaders').and.callThrough();
- this.normalizeCRLFHeaders = gl.utils.normalizeCRLFHeaders(this.CLRFHeaders);
- });
+ this.normalizeCRLFHeaders = gl.utils.normalizeCRLFHeaders(this.CLRFHeaders);
+ });
- it('should split by newline', function () {
- expect(String.prototype.split).toHaveBeenCalledWith('\n');
- });
+ it('should split by newline', function () {
+ expect(String.prototype.split).toHaveBeenCalledWith('\n');
+ });
- it('should split by colon+space for each header', function () {
- expect(String.prototype.split.calls.allArgs().filter(args => args[0] === ': ').length).toBe(3);
- });
+ it('should split by colon+space for each header', function () {
+ expect(String.prototype.split.calls.allArgs().filter(args => args[0] === ': ').length).toBe(3);
+ });
- it('should call gl.utils.normalizeHeaders with a parsed headers object', function () {
- expect(gl.utils.normalizeHeaders).toHaveBeenCalledWith(jasmine.any(Object));
- });
+ it('should call gl.utils.normalizeHeaders with a parsed headers object', function () {
+ expect(gl.utils.normalizeHeaders).toHaveBeenCalledWith(jasmine.any(Object));
+ });
- it('should return a normalized headers object', function () {
- expect(this.normalizeCRLFHeaders).toEqual({
- 'A-HEADER': 'a-value',
- 'ANOTHER-HEADER': 'ANOTHER-VALUE',
- 'LAST-HEADER': 'last-VALUE',
- });
+ it('should return a normalized headers object', function () {
+ expect(this.normalizeCRLFHeaders).toEqual({
+ 'A-HEADER': 'a-value',
+ 'ANOTHER-HEADER': 'ANOTHER-VALUE',
+ 'LAST-HEADER': 'last-VALUE',
});
});
+ });
- describe('gl.utils.parseIntPagination', () => {
- it('should parse to integers all string values and return pagination object', () => {
- const pagination = {
- 'X-PER-PAGE': 10,
- 'X-PAGE': 2,
- 'X-TOTAL': 30,
- 'X-TOTAL-PAGES': 3,
- 'X-NEXT-PAGE': 3,
- 'X-PREV-PAGE': 1,
- };
-
- const expectedPagination = {
- perPage: 10,
- page: 2,
- total: 30,
- totalPages: 3,
- nextPage: 3,
- previousPage: 1,
- };
-
- expect(gl.utils.parseIntPagination(pagination)).toEqual(expectedPagination);
- });
+ describe('gl.utils.parseIntPagination', () => {
+ it('should parse to integers all string values and return pagination object', () => {
+ const pagination = {
+ 'X-PER-PAGE': 10,
+ 'X-PAGE': 2,
+ 'X-TOTAL': 30,
+ 'X-TOTAL-PAGES': 3,
+ 'X-NEXT-PAGE': 3,
+ 'X-PREV-PAGE': 1,
+ };
+
+ const expectedPagination = {
+ perPage: 10,
+ page: 2,
+ total: 30,
+ totalPages: 3,
+ nextPage: 3,
+ previousPage: 1,
+ };
+
+ expect(gl.utils.parseIntPagination(pagination)).toEqual(expectedPagination);
});
+ });
- describe('gl.utils.isMetaClick', () => {
- it('should identify meta click on Windows/Linux', () => {
- const e = {
- metaKey: false,
- ctrlKey: true,
- which: 1,
- };
+ describe('gl.utils.isMetaClick', () => {
+ it('should identify meta click on Windows/Linux', () => {
+ const e = {
+ metaKey: false,
+ ctrlKey: true,
+ which: 1,
+ };
- expect(gl.utils.isMetaClick(e)).toBe(true);
- });
+ expect(gl.utils.isMetaClick(e)).toBe(true);
+ });
- it('should identify meta click on macOS', () => {
- const e = {
- metaKey: true,
- ctrlKey: false,
- which: 1,
- };
+ it('should identify meta click on macOS', () => {
+ const e = {
+ metaKey: true,
+ ctrlKey: false,
+ which: 1,
+ };
- expect(gl.utils.isMetaClick(e)).toBe(true);
- });
+ expect(gl.utils.isMetaClick(e)).toBe(true);
+ });
- it('should identify as meta click on middle-click or Mouse-wheel click', () => {
- const e = {
- metaKey: false,
- ctrlKey: false,
- which: 2,
- };
+ it('should identify as meta click on middle-click or Mouse-wheel click', () => {
+ const e = {
+ metaKey: false,
+ ctrlKey: false,
+ which: 2,
+ };
- expect(gl.utils.isMetaClick(e)).toBe(true);
+ expect(gl.utils.isMetaClick(e)).toBe(true);
+ });
+ });
+
+ describe('gl.utils.backOff', () => {
+ it('solves the promise from the callback', (done) => {
+ const expectedResponseValue = 'Success!';
+ gl.utils.backOff((next, stop) => (
+ new Promise((resolve) => {
+ resolve(expectedResponseValue);
+ }).then((resp) => {
+ stop(resp);
+ })
+ )).then((respBackoff) => {
+ expect(respBackoff).toBe(expectedResponseValue);
+ done();
});
});
- describe('gl.utils.backOff', () => {
- it('solves the promise from the callback', (done) => {
- const expectedResponseValue = 'Success!';
- gl.utils.backOff((next, stop) => (
- new Promise((resolve) => {
- resolve(expectedResponseValue);
- }).then((resp) => {
- stop(resp);
- })
- )).then((respBackoff) => {
- expect(respBackoff).toBe(expectedResponseValue);
- done();
- });
+ it('catches the rejected promise from the callback ', (done) => {
+ const errorMessage = 'Mistakes were made!';
+ gl.utils.backOff((next, stop) => {
+ new Promise((resolve, reject) => {
+ reject(new Error(errorMessage));
+ }).then((resp) => {
+ stop(resp);
+ }).catch(err => stop(err));
+ }).catch((errBackoffResp) => {
+ expect(errBackoffResp instanceof Error).toBe(true);
+ expect(errBackoffResp.message).toBe(errorMessage);
+ done();
});
+ });
- it('catches the rejected promise from the callback ', (done) => {
- const errorMessage = 'Mistakes were made!';
- gl.utils.backOff((next, stop) => {
- new Promise((resolve, reject) => {
- reject(new Error(errorMessage));
- }).then((resp) => {
+ it('solves the promise correctly after retrying a third time', (done) => {
+ let numberOfCalls = 1;
+ const expectedResponseValue = 'Success!';
+ gl.utils.backOff((next, stop) => (
+ new Promise((resolve) => {
+ resolve(expectedResponseValue);
+ }).then((resp) => {
+ if (numberOfCalls < 3) {
+ numberOfCalls += 1;
+ next();
+ } else {
stop(resp);
- }).catch(err => stop(err));
- }).catch((errBackoffResp) => {
- expect(errBackoffResp instanceof Error).toBe(true);
- expect(errBackoffResp.message).toBe(errorMessage);
- done();
- });
- });
+ }
+ })
+ )).then((respBackoff) => {
+ expect(respBackoff).toBe(expectedResponseValue);
+ expect(numberOfCalls).toBe(3);
+ done();
+ });
+ }, 10000);
+
+ it('rejects the backOff promise after timing out', (done) => {
+ const expectedResponseValue = 'Success!';
+ gl.utils.backOff(next => (
+ new Promise((resolve) => {
+ resolve(expectedResponseValue);
+ }).then(() => {
+ setTimeout(next(), 5000); // it will time out
+ })
+ ), 3000).catch((errBackoffResp) => {
+ expect(errBackoffResp instanceof Error).toBe(true);
+ expect(errBackoffResp.message).toBe('BACKOFF_TIMEOUT');
+ done();
+ });
+ }, 10000);
+ });
- it('solves the promise correctly after retrying a third time', (done) => {
- let numberOfCalls = 1;
- const expectedResponseValue = 'Success!';
- gl.utils.backOff((next, stop) => (
- new Promise((resolve) => {
- resolve(expectedResponseValue);
- }).then((resp) => {
- if (numberOfCalls < 3) {
- numberOfCalls += 1;
- next();
- } else {
- stop(resp);
- }
- })
- )).then((respBackoff) => {
- expect(respBackoff).toBe(expectedResponseValue);
- expect(numberOfCalls).toBe(3);
- done();
- });
- }, 10000);
-
- it('rejects the backOff promise after timing out', (done) => {
- const expectedResponseValue = 'Success!';
- gl.utils.backOff(next => (
- new Promise((resolve) => {
- resolve(expectedResponseValue);
- }).then(() => {
- setTimeout(next(), 5000); // it will time out
- })
- ), 3000).catch((errBackoffResp) => {
- expect(errBackoffResp instanceof Error).toBe(true);
- expect(errBackoffResp.message).toBe('BACKOFF_TIMEOUT');
- done();
- });
- }, 10000);
- });
-
- describe('gl.utils.setFavicon', () => {
- it('should set page favicon to provided favicon', () => {
- const faviconPath = '//custom_favicon';
- const fakeLink = {
- setAttribute() {},
- };
-
- spyOn(window.document, 'getElementById').and.callFake(() => fakeLink);
- spyOn(fakeLink, 'setAttribute').and.callFake((attr, val) => {
- expect(attr).toEqual('href');
- expect(val.indexOf(faviconPath) > -1).toBe(true);
- });
- gl.utils.setFavicon(faviconPath);
+ describe('gl.utils.setFavicon', () => {
+ it('should set page favicon to provided favicon', () => {
+ const faviconPath = '//custom_favicon';
+ const fakeLink = {
+ setAttribute() {},
+ };
+
+ spyOn(window.document, 'getElementById').and.callFake(() => fakeLink);
+ spyOn(fakeLink, 'setAttribute').and.callFake((attr, val) => {
+ expect(attr).toEqual('href');
+ expect(val.indexOf(faviconPath) > -1).toBe(true);
});
+ gl.utils.setFavicon(faviconPath);
});
+ });
- describe('gl.utils.resetFavicon', () => {
- it('should reset page favicon to tanuki', () => {
- const fakeLink = {
- setAttribute() {},
- };
+ describe('gl.utils.resetFavicon', () => {
+ it('should reset page favicon to tanuki', () => {
+ const fakeLink = {
+ setAttribute() {},
+ };
- spyOn(window.document, 'getElementById').and.callFake(() => fakeLink);
- spyOn(fakeLink, 'setAttribute').and.callFake((attr, val) => {
- expect(attr).toEqual('href');
- expect(val).toMatch(/favicon/);
- });
- gl.utils.resetFavicon();
+ spyOn(window.document, 'getElementById').and.callFake(() => fakeLink);
+ spyOn(fakeLink, 'setAttribute').and.callFake((attr, val) => {
+ expect(attr).toEqual('href');
+ expect(val).toMatch(/favicon/);
});
+ gl.utils.resetFavicon();
});
+ });
- describe('gl.utils.setCiStatusFavicon', () => {
- it('should set page favicon to CI status favicon based on provided status', () => {
- const BUILD_URL = `${gl.TEST_HOST}/frontend-fixtures/builds-project/-/jobs/1/status.json`;
- const FAVICON_PATH = '//icon_status_success';
- const spySetFavicon = spyOn(gl.utils, 'setFavicon').and.stub();
- const spyResetFavicon = spyOn(gl.utils, 'resetFavicon').and.stub();
- spyOn($, 'ajax').and.callFake(function (options) {
- options.success({ favicon: FAVICON_PATH });
- expect(spySetFavicon).toHaveBeenCalledWith(FAVICON_PATH);
- options.success();
- expect(spyResetFavicon).toHaveBeenCalled();
- options.error();
- expect(spyResetFavicon).toHaveBeenCalled();
- });
-
- gl.utils.setCiStatusFavicon(BUILD_URL);
- });
+ describe('gl.utils.setCiStatusFavicon', () => {
+ it('should set page favicon to CI status favicon based on provided status', () => {
+ const BUILD_URL = `${gl.TEST_HOST}/frontend-fixtures/builds-project/-/jobs/1/status.json`;
+ const FAVICON_PATH = '//icon_status_success';
+ const spySetFavicon = spyOn(gl.utils, 'setFavicon').and.stub();
+ const spyResetFavicon = spyOn(gl.utils, 'resetFavicon').and.stub();
+ spyOn($, 'ajax').and.callFake(function (options) {
+ options.success({ favicon: FAVICON_PATH });
+ expect(spySetFavicon).toHaveBeenCalledWith(FAVICON_PATH);
+ options.success();
+ expect(spyResetFavicon).toHaveBeenCalled();
+ options.error();
+ expect(spyResetFavicon).toHaveBeenCalled();
+ });
+
+ gl.utils.setCiStatusFavicon(BUILD_URL);
});
+ });
- describe('gl.utils.ajaxPost', () => {
- it('should perform `$.ajax` call and do `POST` request', () => {
- const requestURL = '/some/random/api';
- const data = { keyname: 'value' };
- const ajaxSpy = spyOn($, 'ajax').and.callFake(() => {});
+ describe('gl.utils.ajaxPost', () => {
+ it('should perform `$.ajax` call and do `POST` request', () => {
+ const requestURL = '/some/random/api';
+ const data = { keyname: 'value' };
+ const ajaxSpy = spyOn($, 'ajax').and.callFake(() => {});
- gl.utils.ajaxPost(requestURL, data);
- expect(ajaxSpy.calls.allArgs()[0][0].type).toEqual('POST');
- });
+ gl.utils.ajaxPost(requestURL, data);
+ expect(ajaxSpy.calls.allArgs()[0][0].type).toEqual('POST');
});
});
-})();
+});
diff --git a/spec/javascripts/merge_request_spec.js b/spec/javascripts/merge_request_spec.js
index 6ff42e2378d..6897074512e 100644
--- a/spec/javascripts/merge_request_spec.js
+++ b/spec/javascripts/merge_request_spec.js
@@ -5,58 +5,56 @@ import '~/merge_request';
import CloseReopenReportToggle from '~/close_reopen_report_toggle';
import IssuablesHelper from '~/helpers/issuables_helper';
-(function() {
- describe('MergeRequest', function() {
- describe('task lists', function() {
- preloadFixtures('merge_requests/merge_request_with_task_list.html.raw');
- beforeEach(function() {
- loadFixtures('merge_requests/merge_request_with_task_list.html.raw');
- return this.merge = new MergeRequest();
- });
- it('modifies the Markdown field', function() {
- spyOn(jQuery, 'ajax').and.stub();
- const changeEvent = document.createEvent('HTMLEvents');
- changeEvent.initEvent('change', true, true);
- $('input[type=checkbox]').attr('checked', true)[0].dispatchEvent(changeEvent);
- return expect($('.js-task-list-field').val()).toBe('- [x] Task List Item');
- });
- return it('submits an ajax request on tasklist:changed', function() {
- spyOn(jQuery, 'ajax').and.callFake(function(req) {
- expect(req.type).toBe('PATCH');
- expect(req.url).toBe(`${gl.TEST_HOST}/frontend-fixtures/merge-requests-project/merge_requests/1.json`);
- return expect(req.data.merge_request.description).not.toBe(null);
- });
- return $('.js-task-list-field').trigger('tasklist:changed');
+describe('MergeRequest', function() {
+ describe('task lists', function() {
+ preloadFixtures('merge_requests/merge_request_with_task_list.html.raw');
+ beforeEach(function() {
+ loadFixtures('merge_requests/merge_request_with_task_list.html.raw');
+ return this.merge = new MergeRequest();
+ });
+ it('modifies the Markdown field', function() {
+ spyOn(jQuery, 'ajax').and.stub();
+ const changeEvent = document.createEvent('HTMLEvents');
+ changeEvent.initEvent('change', true, true);
+ $('input[type=checkbox]').attr('checked', true)[0].dispatchEvent(changeEvent);
+ return expect($('.js-task-list-field').val()).toBe('- [x] Task List Item');
+ });
+ return it('submits an ajax request on tasklist:changed', function() {
+ spyOn(jQuery, 'ajax').and.callFake(function(req) {
+ expect(req.type).toBe('PATCH');
+ expect(req.url).toBe(`${gl.TEST_HOST}/frontend-fixtures/merge-requests-project/merge_requests/1.json`);
+ return expect(req.data.merge_request.description).not.toBe(null);
});
+ return $('.js-task-list-field').trigger('tasklist:changed');
});
+ });
- describe('class constructor', () => {
- it('calls .initCloseReopenReport', () => {
- spyOn(IssuablesHelper, 'initCloseReopenReport');
+ describe('class constructor', () => {
+ it('calls .initCloseReopenReport', () => {
+ spyOn(IssuablesHelper, 'initCloseReopenReport');
- new MergeRequest(); // eslint-disable-line no-new
+ new MergeRequest(); // eslint-disable-line no-new
- expect(IssuablesHelper.initCloseReopenReport).toHaveBeenCalled();
- });
+ expect(IssuablesHelper.initCloseReopenReport).toHaveBeenCalled();
+ });
- it('calls .initDroplab', () => {
- const container = jasmine.createSpyObj('container', ['querySelector']);
- const dropdownTrigger = {};
- const dropdownList = {};
- const button = {};
+ it('calls .initDroplab', () => {
+ const container = jasmine.createSpyObj('container', ['querySelector']);
+ const dropdownTrigger = {};
+ const dropdownList = {};
+ const button = {};
- spyOn(CloseReopenReportToggle.prototype, 'initDroplab');
- spyOn(document, 'querySelector').and.returnValue(container);
- container.querySelector.and.returnValues(dropdownTrigger, dropdownList, button);
+ spyOn(CloseReopenReportToggle.prototype, 'initDroplab');
+ spyOn(document, 'querySelector').and.returnValue(container);
+ container.querySelector.and.returnValues(dropdownTrigger, dropdownList, button);
- new MergeRequest(); // eslint-disable-line no-new
+ new MergeRequest(); // eslint-disable-line no-new
- expect(document.querySelector).toHaveBeenCalledWith('.js-issuable-close-dropdown');
- expect(container.querySelector).toHaveBeenCalledWith('.js-issuable-close-toggle');
- expect(container.querySelector).toHaveBeenCalledWith('.js-issuable-close-menu');
- expect(container.querySelector).toHaveBeenCalledWith('.js-issuable-close-button');
- expect(CloseReopenReportToggle.prototype.initDroplab).toHaveBeenCalled();
- });
+ expect(document.querySelector).toHaveBeenCalledWith('.js-issuable-close-dropdown');
+ expect(container.querySelector).toHaveBeenCalledWith('.js-issuable-close-toggle');
+ expect(container.querySelector).toHaveBeenCalledWith('.js-issuable-close-menu');
+ expect(container.querySelector).toHaveBeenCalledWith('.js-issuable-close-button');
+ expect(CloseReopenReportToggle.prototype.initDroplab).toHaveBeenCalled();
});
});
-}).call(window);
+});
diff --git a/spec/javascripts/merge_request_tabs_spec.js b/spec/javascripts/merge_request_tabs_spec.js
index dc40244c20e..accc10ce7ec 100644
--- a/spec/javascripts/merge_request_tabs_spec.js
+++ b/spec/javascripts/merge_request_tabs_spec.js
@@ -10,399 +10,397 @@ import '~/files_comment_button';
import '~/notes';
import 'vendor/jquery.scrollTo';
-(function () {
- describe('MergeRequestTabs', function () {
- var stubLocation = {};
- var setLocation = function (stubs) {
- var defaults = {
- pathname: '',
- search: '',
- hash: ''
- };
- $.extend(stubLocation, defaults, stubs || {});
+describe('MergeRequestTabs', function () {
+ var stubLocation = {};
+ var setLocation = function (stubs) {
+ var defaults = {
+ pathname: '',
+ search: '',
+ hash: ''
};
+ $.extend(stubLocation, defaults, stubs || {});
+ };
+
+ const inlineChangesTabJsonFixture = 'merge_request_diffs/inline_changes_tab_with_comments.json';
+ const parallelChangesTabJsonFixture = 'merge_request_diffs/parallel_changes_tab_with_comments.json';
+ preloadFixtures(
+ 'merge_requests/merge_request_with_task_list.html.raw',
+ 'merge_requests/diff_comment.html.raw',
+ inlineChangesTabJsonFixture,
+ parallelChangesTabJsonFixture
+ );
+
+ beforeEach(function () {
+ this.class = new gl.MergeRequestTabs({ stubLocation: stubLocation });
+ setLocation();
+
+ this.spies = {
+ history: spyOn(window.history, 'replaceState').and.callFake(function () {})
+ };
+ });
- const inlineChangesTabJsonFixture = 'merge_request_diffs/inline_changes_tab_with_comments.json';
- const parallelChangesTabJsonFixture = 'merge_request_diffs/parallel_changes_tab_with_comments.json';
- preloadFixtures(
- 'merge_requests/merge_request_with_task_list.html.raw',
- 'merge_requests/diff_comment.html.raw',
- inlineChangesTabJsonFixture,
- parallelChangesTabJsonFixture
- );
+ afterEach(function () {
+ this.class.unbindEvents();
+ this.class.destroyPipelinesView();
+ });
+ describe('activateTab', function () {
beforeEach(function () {
- this.class = new gl.MergeRequestTabs({ stubLocation: stubLocation });
- setLocation();
-
- this.spies = {
- history: spyOn(window.history, 'replaceState').and.callFake(function () {})
- };
+ spyOn($, 'ajax').and.callFake(function () {});
+ loadFixtures('merge_requests/merge_request_with_task_list.html.raw');
+ this.subject = this.class.activateTab;
});
-
- afterEach(function () {
- this.class.unbindEvents();
- this.class.destroyPipelinesView();
+ it('shows the notes tab when action is show', function () {
+ this.subject('show');
+ expect($('#notes')).toHaveClass('active');
});
-
- describe('activateTab', function () {
- beforeEach(function () {
- spyOn($, 'ajax').and.callFake(function () {});
- loadFixtures('merge_requests/merge_request_with_task_list.html.raw');
- this.subject = this.class.activateTab;
- });
- it('shows the notes tab when action is show', function () {
- this.subject('show');
- expect($('#notes')).toHaveClass('active');
- });
- it('shows the commits tab when action is commits', function () {
- this.subject('commits');
- expect($('#commits')).toHaveClass('active');
- });
- it('shows the diffs tab when action is diffs', function () {
- this.subject('diffs');
- expect($('#diffs')).toHaveClass('active');
- });
+ it('shows the commits tab when action is commits', function () {
+ this.subject('commits');
+ expect($('#commits')).toHaveClass('active');
});
+ it('shows the diffs tab when action is diffs', function () {
+ this.subject('diffs');
+ expect($('#diffs')).toHaveClass('active');
+ });
+ });
- describe('opensInNewTab', function () {
- var tabUrl;
- var windowTarget = '_blank';
-
- beforeEach(function () {
- loadFixtures('merge_requests/merge_request_with_task_list.html.raw');
-
- tabUrl = $('.commits-tab a').attr('href');
-
- spyOn($.fn, 'attr').and.returnValue(tabUrl);
- });
-
- describe('meta click', () => {
- beforeEach(function () {
- spyOn(gl.utils, 'isMetaClick').and.returnValue(true);
- });
+ describe('opensInNewTab', function () {
+ var tabUrl;
+ var windowTarget = '_blank';
- it('opens page when commits link is clicked', function () {
- spyOn(window, 'open').and.callFake(function (url, name) {
- expect(url).toEqual(tabUrl);
- expect(name).toEqual(windowTarget);
- });
+ beforeEach(function () {
+ loadFixtures('merge_requests/merge_request_with_task_list.html.raw');
- this.class.bindEvents();
- document.querySelector('.merge-request-tabs .commits-tab a').click();
- });
+ tabUrl = $('.commits-tab a').attr('href');
- it('opens page when commits badge is clicked', function () {
- spyOn(window, 'open').and.callFake(function (url, name) {
- expect(url).toEqual(tabUrl);
- expect(name).toEqual(windowTarget);
- });
+ spyOn($.fn, 'attr').and.returnValue(tabUrl);
+ });
- this.class.bindEvents();
- document.querySelector('.merge-request-tabs .commits-tab a .badge').click();
- });
+ describe('meta click', () => {
+ beforeEach(function () {
+ spyOn(gl.utils, 'isMetaClick').and.returnValue(true);
});
- it('opens page tab in a new browser tab with Ctrl+Click - Windows/Linux', function () {
+ it('opens page when commits link is clicked', function () {
spyOn(window, 'open').and.callFake(function (url, name) {
expect(url).toEqual(tabUrl);
expect(name).toEqual(windowTarget);
});
- this.class.clickTab({
- metaKey: false,
- ctrlKey: true,
- which: 1,
- stopImmediatePropagation: function () {}
- });
+ this.class.bindEvents();
+ document.querySelector('.merge-request-tabs .commits-tab a').click();
});
- it('opens page tab in a new browser tab with Cmd+Click - Mac', function () {
+ it('opens page when commits badge is clicked', function () {
spyOn(window, 'open').and.callFake(function (url, name) {
expect(url).toEqual(tabUrl);
expect(name).toEqual(windowTarget);
});
- this.class.clickTab({
- metaKey: true,
- ctrlKey: false,
- which: 1,
- stopImmediatePropagation: function () {}
- });
+ this.class.bindEvents();
+ document.querySelector('.merge-request-tabs .commits-tab a .badge').click();
});
+ });
- it('opens page tab in a new browser tab with Middle-click - Mac/PC', function () {
- spyOn(window, 'open').and.callFake(function (url, name) {
- expect(url).toEqual(tabUrl);
- expect(name).toEqual(windowTarget);
- });
+ it('opens page tab in a new browser tab with Ctrl+Click - Windows/Linux', function () {
+ spyOn(window, 'open').and.callFake(function (url, name) {
+ expect(url).toEqual(tabUrl);
+ expect(name).toEqual(windowTarget);
+ });
- this.class.clickTab({
- metaKey: false,
- ctrlKey: false,
- which: 2,
- stopImmediatePropagation: function () {}
- });
+ this.class.clickTab({
+ metaKey: false,
+ ctrlKey: true,
+ which: 1,
+ stopImmediatePropagation: function () {}
});
});
- describe('setCurrentAction', function () {
- beforeEach(function () {
- spyOn($, 'ajax').and.callFake(function () {});
- this.subject = this.class.setCurrentAction;
+ it('opens page tab in a new browser tab with Cmd+Click - Mac', function () {
+ spyOn(window, 'open').and.callFake(function (url, name) {
+ expect(url).toEqual(tabUrl);
+ expect(name).toEqual(windowTarget);
});
- it('changes from commits', function () {
- setLocation({
- pathname: '/foo/bar/merge_requests/1/commits'
- });
- expect(this.subject('show')).toBe('/foo/bar/merge_requests/1');
- expect(this.subject('diffs')).toBe('/foo/bar/merge_requests/1/diffs');
+ this.class.clickTab({
+ metaKey: true,
+ ctrlKey: false,
+ which: 1,
+ stopImmediatePropagation: function () {}
});
+ });
- it('changes from diffs', function () {
- setLocation({
- pathname: '/foo/bar/merge_requests/1/diffs'
- });
+ it('opens page tab in a new browser tab with Middle-click - Mac/PC', function () {
+ spyOn(window, 'open').and.callFake(function (url, name) {
+ expect(url).toEqual(tabUrl);
+ expect(name).toEqual(windowTarget);
+ });
- expect(this.subject('show')).toBe('/foo/bar/merge_requests/1');
- expect(this.subject('commits')).toBe('/foo/bar/merge_requests/1/commits');
+ this.class.clickTab({
+ metaKey: false,
+ ctrlKey: false,
+ which: 2,
+ stopImmediatePropagation: function () {}
});
+ });
+ });
- it('changes from diffs.html', function () {
- setLocation({
- pathname: '/foo/bar/merge_requests/1/diffs.html'
- });
- expect(this.subject('show')).toBe('/foo/bar/merge_requests/1');
- expect(this.subject('commits')).toBe('/foo/bar/merge_requests/1/commits');
+ describe('setCurrentAction', function () {
+ beforeEach(function () {
+ spyOn($, 'ajax').and.callFake(function () {});
+ this.subject = this.class.setCurrentAction;
+ });
+
+ it('changes from commits', function () {
+ setLocation({
+ pathname: '/foo/bar/merge_requests/1/commits'
});
+ expect(this.subject('show')).toBe('/foo/bar/merge_requests/1');
+ expect(this.subject('diffs')).toBe('/foo/bar/merge_requests/1/diffs');
+ });
- it('changes from notes', function () {
- setLocation({
- pathname: '/foo/bar/merge_requests/1'
- });
- expect(this.subject('diffs')).toBe('/foo/bar/merge_requests/1/diffs');
- expect(this.subject('commits')).toBe('/foo/bar/merge_requests/1/commits');
+ it('changes from diffs', function () {
+ setLocation({
+ pathname: '/foo/bar/merge_requests/1/diffs'
});
- it('includes search parameters and hash string', function () {
- setLocation({
- pathname: '/foo/bar/merge_requests/1/diffs',
- search: '?view=parallel',
- hash: '#L15-35'
- });
- expect(this.subject('show')).toBe('/foo/bar/merge_requests/1?view=parallel#L15-35');
+ expect(this.subject('show')).toBe('/foo/bar/merge_requests/1');
+ expect(this.subject('commits')).toBe('/foo/bar/merge_requests/1/commits');
+ });
+
+ it('changes from diffs.html', function () {
+ setLocation({
+ pathname: '/foo/bar/merge_requests/1/diffs.html'
});
+ expect(this.subject('show')).toBe('/foo/bar/merge_requests/1');
+ expect(this.subject('commits')).toBe('/foo/bar/merge_requests/1/commits');
+ });
- it('replaces the current history state', function () {
- var newState;
- setLocation({
- pathname: '/foo/bar/merge_requests/1'
- });
- newState = this.subject('commits');
- expect(this.spies.history).toHaveBeenCalledWith({
- url: newState
- }, document.title, newState);
+ it('changes from notes', function () {
+ setLocation({
+ pathname: '/foo/bar/merge_requests/1'
});
+ expect(this.subject('diffs')).toBe('/foo/bar/merge_requests/1/diffs');
+ expect(this.subject('commits')).toBe('/foo/bar/merge_requests/1/commits');
+ });
- it('treats "show" like "notes"', function () {
- setLocation({
- pathname: '/foo/bar/merge_requests/1/commits'
- });
- expect(this.subject('show')).toBe('/foo/bar/merge_requests/1');
+ it('includes search parameters and hash string', function () {
+ setLocation({
+ pathname: '/foo/bar/merge_requests/1/diffs',
+ search: '?view=parallel',
+ hash: '#L15-35'
});
+ expect(this.subject('show')).toBe('/foo/bar/merge_requests/1?view=parallel#L15-35');
});
- describe('tabShown', () => {
- beforeEach(function () {
- spyOn($, 'ajax').and.callFake(function (options) {
- options.success({ html: '' });
- });
- loadFixtures('merge_requests/merge_request_with_task_list.html.raw');
+ it('replaces the current history state', function () {
+ var newState;
+ setLocation({
+ pathname: '/foo/bar/merge_requests/1'
});
+ newState = this.subject('commits');
+ expect(this.spies.history).toHaveBeenCalledWith({
+ url: newState
+ }, document.title, newState);
+ });
- describe('with "Side-by-side"/parallel diff view', () => {
- beforeEach(function () {
- this.class.diffViewType = () => 'parallel';
- gl.Diff.prototype.diffViewType = () => 'parallel';
- });
+ it('treats "show" like "notes"', function () {
+ setLocation({
+ pathname: '/foo/bar/merge_requests/1/commits'
+ });
+ expect(this.subject('show')).toBe('/foo/bar/merge_requests/1');
+ });
+ });
- it('maintains `container-limited` for pipelines tab', function (done) {
- const asyncClick = function (selector) {
- return new Promise((resolve) => {
- setTimeout(() => {
- document.querySelector(selector).click();
- resolve();
- });
- });
- };
- asyncClick('.merge-request-tabs .pipelines-tab a')
- .then(() => asyncClick('.merge-request-tabs .diffs-tab a'))
- .then(() => asyncClick('.merge-request-tabs .pipelines-tab a'))
- .then(() => {
- const hasContainerLimitedClass = document.querySelector('.content-wrapper .container-fluid').classList.contains('container-limited');
- expect(hasContainerLimitedClass).toBe(true);
- })
- .then(done)
- .catch((err) => {
- done.fail(`Something went wrong clicking MR tabs: ${err.message}\n${err.stack}`);
- });
- });
+ describe('tabShown', () => {
+ beforeEach(function () {
+ spyOn($, 'ajax').and.callFake(function (options) {
+ options.success({ html: '' });
+ });
+ loadFixtures('merge_requests/merge_request_with_task_list.html.raw');
+ });
- it('maintains `container-limited` when switching from "Changes" tab before it loads', function (done) {
- const asyncClick = function (selector) {
- return new Promise((resolve) => {
- setTimeout(() => {
- document.querySelector(selector).click();
- resolve();
- });
+ describe('with "Side-by-side"/parallel diff view', () => {
+ beforeEach(function () {
+ this.class.diffViewType = () => 'parallel';
+ gl.Diff.prototype.diffViewType = () => 'parallel';
+ });
+
+ it('maintains `container-limited` for pipelines tab', function (done) {
+ const asyncClick = function (selector) {
+ return new Promise((resolve) => {
+ setTimeout(() => {
+ document.querySelector(selector).click();
+ resolve();
});
- };
-
- asyncClick('.merge-request-tabs .diffs-tab a')
- .then(() => asyncClick('.merge-request-tabs .notes-tab a'))
- .then(() => {
- const hasContainerLimitedClass = document.querySelector('.content-wrapper .container-fluid').classList.contains('container-limited');
- expect(hasContainerLimitedClass).toBe(true);
- })
- .then(done)
- .catch((err) => {
- done.fail(`Something went wrong clicking MR tabs: ${err.message}\n${err.stack}`);
+ });
+ };
+ asyncClick('.merge-request-tabs .pipelines-tab a')
+ .then(() => asyncClick('.merge-request-tabs .diffs-tab a'))
+ .then(() => asyncClick('.merge-request-tabs .pipelines-tab a'))
+ .then(() => {
+ const hasContainerLimitedClass = document.querySelector('.content-wrapper .container-fluid').classList.contains('container-limited');
+ expect(hasContainerLimitedClass).toBe(true);
+ })
+ .then(done)
+ .catch((err) => {
+ done.fail(`Something went wrong clicking MR tabs: ${err.message}\n${err.stack}`);
+ });
+ });
+
+ it('maintains `container-limited` when switching from "Changes" tab before it loads', function (done) {
+ const asyncClick = function (selector) {
+ return new Promise((resolve) => {
+ setTimeout(() => {
+ document.querySelector(selector).click();
+ resolve();
});
- });
+ });
+ };
+
+ asyncClick('.merge-request-tabs .diffs-tab a')
+ .then(() => asyncClick('.merge-request-tabs .notes-tab a'))
+ .then(() => {
+ const hasContainerLimitedClass = document.querySelector('.content-wrapper .container-fluid').classList.contains('container-limited');
+ expect(hasContainerLimitedClass).toBe(true);
+ })
+ .then(done)
+ .catch((err) => {
+ done.fail(`Something went wrong clicking MR tabs: ${err.message}\n${err.stack}`);
+ });
});
});
+ });
- describe('loadDiff', function () {
- beforeEach(() => {
- loadFixtures('merge_requests/diff_comment.html.raw');
- spyOn(window.gl.utils, 'getPagePath').and.returnValue('merge_requests');
- window.gl.ImageFile = () => {};
- window.notes = new Notes('', []);
- spyOn(window.notes, 'toggleDiffNote').and.callThrough();
- });
+ describe('loadDiff', function () {
+ beforeEach(() => {
+ loadFixtures('merge_requests/diff_comment.html.raw');
+ spyOn(window.gl.utils, 'getPagePath').and.returnValue('merge_requests');
+ window.gl.ImageFile = () => {};
+ window.notes = new Notes('', []);
+ spyOn(window.notes, 'toggleDiffNote').and.callThrough();
+ });
- afterEach(() => {
- delete window.gl.ImageFile;
- delete window.notes;
+ afterEach(() => {
+ delete window.gl.ImageFile;
+ delete window.notes;
+ });
+
+ it('requires an absolute pathname', function () {
+ spyOn($, 'ajax').and.callFake(function (options) {
+ expect(options.url).toEqual('/foo/bar/merge_requests/1/diffs.json');
});
- it('requires an absolute pathname', function () {
- spyOn($, 'ajax').and.callFake(function (options) {
- expect(options.url).toEqual('/foo/bar/merge_requests/1/diffs.json');
- });
+ this.class.loadDiff('/foo/bar/merge_requests/1/diffs');
+ });
- this.class.loadDiff('/foo/bar/merge_requests/1/diffs');
- });
+ describe('with inline diff', () => {
+ let noteId;
+ let noteLineNumId;
- describe('with inline diff', () => {
- let noteId;
- let noteLineNumId;
-
- beforeEach(() => {
- const diffsResponse = getJSONFixture(inlineChangesTabJsonFixture);
-
- const $html = $(diffsResponse.html);
- noteId = $html.find('.note').attr('id');
- noteLineNumId = $html
- .find('.note')
- .closest('.notes_holder')
- .prev('.line_holder')
- .find('a[data-linenumber]')
- .attr('href')
- .replace('#', '');
-
- spyOn($, 'ajax').and.callFake(function (options) {
- options.success(diffsResponse);
- });
+ beforeEach(() => {
+ const diffsResponse = getJSONFixture(inlineChangesTabJsonFixture);
+
+ const $html = $(diffsResponse.html);
+ noteId = $html.find('.note').attr('id');
+ noteLineNumId = $html
+ .find('.note')
+ .closest('.notes_holder')
+ .prev('.line_holder')
+ .find('a[data-linenumber]')
+ .attr('href')
+ .replace('#', '');
+
+ spyOn($, 'ajax').and.callFake(function (options) {
+ options.success(diffsResponse);
});
+ });
- describe('with note fragment hash', () => {
- it('should expand and scroll to linked fragment hash #note_xxx', function () {
- spyOn(window.gl.utils, 'getLocationHash').and.returnValue(noteId);
- this.class.loadDiff('/foo/bar/merge_requests/1/diffs');
+ describe('with note fragment hash', () => {
+ it('should expand and scroll to linked fragment hash #note_xxx', function () {
+ spyOn(window.gl.utils, 'getLocationHash').and.returnValue(noteId);
+ this.class.loadDiff('/foo/bar/merge_requests/1/diffs');
- expect(noteId.length).toBeGreaterThan(0);
- expect(window.notes.toggleDiffNote).toHaveBeenCalledWith({
- target: jasmine.any(Object),
- lineType: 'old',
- forceShow: true,
- });
+ expect(noteId.length).toBeGreaterThan(0);
+ expect(window.notes.toggleDiffNote).toHaveBeenCalledWith({
+ target: jasmine.any(Object),
+ lineType: 'old',
+ forceShow: true,
});
+ });
- it('should gracefully ignore non-existant fragment hash', function () {
- spyOn(window.gl.utils, 'getLocationHash').and.returnValue('note_something-that-does-not-exist');
- this.class.loadDiff('/foo/bar/merge_requests/1/diffs');
+ it('should gracefully ignore non-existant fragment hash', function () {
+ spyOn(window.gl.utils, 'getLocationHash').and.returnValue('note_something-that-does-not-exist');
+ this.class.loadDiff('/foo/bar/merge_requests/1/diffs');
- expect(window.notes.toggleDiffNote).not.toHaveBeenCalled();
- });
+ expect(window.notes.toggleDiffNote).not.toHaveBeenCalled();
});
+ });
- describe('with line number fragment hash', () => {
- it('should gracefully ignore line number fragment hash', function () {
- spyOn(window.gl.utils, 'getLocationHash').and.returnValue(noteLineNumId);
- this.class.loadDiff('/foo/bar/merge_requests/1/diffs');
+ describe('with line number fragment hash', () => {
+ it('should gracefully ignore line number fragment hash', function () {
+ spyOn(window.gl.utils, 'getLocationHash').and.returnValue(noteLineNumId);
+ this.class.loadDiff('/foo/bar/merge_requests/1/diffs');
- expect(noteLineNumId.length).toBeGreaterThan(0);
- expect(window.notes.toggleDiffNote).not.toHaveBeenCalled();
- });
+ expect(noteLineNumId.length).toBeGreaterThan(0);
+ expect(window.notes.toggleDiffNote).not.toHaveBeenCalled();
});
});
+ });
- describe('with parallel diff', () => {
- let noteId;
- let noteLineNumId;
-
- beforeEach(() => {
- const diffsResponse = getJSONFixture(parallelChangesTabJsonFixture);
-
- const $html = $(diffsResponse.html);
- noteId = $html.find('.note').attr('id');
- noteLineNumId = $html
- .find('.note')
- .closest('.notes_holder')
- .prev('.line_holder')
- .find('a[data-linenumber]')
- .attr('href')
- .replace('#', '');
-
- spyOn($, 'ajax').and.callFake(function (options) {
- options.success(diffsResponse);
- });
+ describe('with parallel diff', () => {
+ let noteId;
+ let noteLineNumId;
+
+ beforeEach(() => {
+ const diffsResponse = getJSONFixture(parallelChangesTabJsonFixture);
+
+ const $html = $(diffsResponse.html);
+ noteId = $html.find('.note').attr('id');
+ noteLineNumId = $html
+ .find('.note')
+ .closest('.notes_holder')
+ .prev('.line_holder')
+ .find('a[data-linenumber]')
+ .attr('href')
+ .replace('#', '');
+
+ spyOn($, 'ajax').and.callFake(function (options) {
+ options.success(diffsResponse);
});
+ });
- describe('with note fragment hash', () => {
- it('should expand and scroll to linked fragment hash #note_xxx', function () {
- spyOn(window.gl.utils, 'getLocationHash').and.returnValue(noteId);
+ describe('with note fragment hash', () => {
+ it('should expand and scroll to linked fragment hash #note_xxx', function () {
+ spyOn(window.gl.utils, 'getLocationHash').and.returnValue(noteId);
- this.class.loadDiff('/foo/bar/merge_requests/1/diffs');
+ this.class.loadDiff('/foo/bar/merge_requests/1/diffs');
- expect(noteId.length).toBeGreaterThan(0);
- expect(window.notes.toggleDiffNote).toHaveBeenCalledWith({
- target: jasmine.any(Object),
- lineType: 'new',
- forceShow: true,
- });
+ expect(noteId.length).toBeGreaterThan(0);
+ expect(window.notes.toggleDiffNote).toHaveBeenCalledWith({
+ target: jasmine.any(Object),
+ lineType: 'new',
+ forceShow: true,
});
+ });
- it('should gracefully ignore non-existant fragment hash', function () {
- spyOn(window.gl.utils, 'getLocationHash').and.returnValue('note_something-that-does-not-exist');
- this.class.loadDiff('/foo/bar/merge_requests/1/diffs');
+ it('should gracefully ignore non-existant fragment hash', function () {
+ spyOn(window.gl.utils, 'getLocationHash').and.returnValue('note_something-that-does-not-exist');
+ this.class.loadDiff('/foo/bar/merge_requests/1/diffs');
- expect(window.notes.toggleDiffNote).not.toHaveBeenCalled();
- });
+ expect(window.notes.toggleDiffNote).not.toHaveBeenCalled();
});
+ });
- describe('with line number fragment hash', () => {
- it('should gracefully ignore line number fragment hash', function () {
- spyOn(window.gl.utils, 'getLocationHash').and.returnValue(noteLineNumId);
- this.class.loadDiff('/foo/bar/merge_requests/1/diffs');
+ describe('with line number fragment hash', () => {
+ it('should gracefully ignore line number fragment hash', function () {
+ spyOn(window.gl.utils, 'getLocationHash').and.returnValue(noteLineNumId);
+ this.class.loadDiff('/foo/bar/merge_requests/1/diffs');
- expect(noteLineNumId.length).toBeGreaterThan(0);
- expect(window.notes.toggleDiffNote).not.toHaveBeenCalled();
- });
+ expect(noteLineNumId.length).toBeGreaterThan(0);
+ expect(window.notes.toggleDiffNote).not.toHaveBeenCalled();
});
});
});
});
-}).call(window);
+});
diff --git a/spec/javascripts/notes_spec.js b/spec/javascripts/notes_spec.js
index 2c096ed08a8..3394ea5f9d4 100644
--- a/spec/javascripts/notes_spec.js
+++ b/spec/javascripts/notes_spec.js
@@ -8,816 +8,814 @@ import '~/render_gfm';
import '~/render_math';
import '~/notes';
-(function() {
- window.gon || (window.gon = {});
- window.gl = window.gl || {};
- gl.utils = gl.utils || {};
-
- const htmlEscape = (comment) => {
- const escapedString = comment.replace(/["&'<>]/g, (a) => {
- const escapedToken = {
- '&': '&amp;',
- '<': '&lt;',
- '>': '&gt;',
- '"': '&quot;',
- "'": '&#x27;',
- '`': '&#x60;'
- }[a];
-
- return escapedToken;
- });
-
- return escapedString;
- };
-
- describe('Notes', function() {
- const FLASH_TYPE_ALERT = 'alert';
- var commentsTemplate = 'issues/issue_with_comment.html.raw';
- preloadFixtures(commentsTemplate);
-
- beforeEach(function () {
- loadFixtures(commentsTemplate);
- gl.utils.disableButtonIfEmptyField = _.noop;
- window.project_uploads_path = 'http://test.host/uploads';
- $('body').data('page', 'projects:issues:show');
- });
-
- describe('task lists', function() {
- beforeEach(function() {
- $('.js-comment-button').on('click', function(e) {
- e.preventDefault();
- });
- this.notes = new Notes('', []);
- });
+window.gon || (window.gon = {});
+window.gl = window.gl || {};
+gl.utils = gl.utils || {};
+
+const htmlEscape = (comment) => {
+ const escapedString = comment.replace(/["&'<>]/g, (a) => {
+ const escapedToken = {
+ '&': '&amp;',
+ '<': '&lt;',
+ '>': '&gt;',
+ '"': '&quot;',
+ "'": '&#x27;',
+ '`': '&#x60;'
+ }[a];
+
+ return escapedToken;
+ });
+
+ return escapedString;
+};
+
+describe('Notes', function() {
+ const FLASH_TYPE_ALERT = 'alert';
+ var commentsTemplate = 'issues/issue_with_comment.html.raw';
+ preloadFixtures(commentsTemplate);
+
+ beforeEach(function () {
+ loadFixtures(commentsTemplate);
+ gl.utils.disableButtonIfEmptyField = _.noop;
+ window.project_uploads_path = 'http://test.host/uploads';
+ $('body').data('page', 'projects:issues:show');
+ });
- it('modifies the Markdown field', function() {
- const changeEvent = document.createEvent('HTMLEvents');
- changeEvent.initEvent('change', true, true);
- $('input[type=checkbox]').attr('checked', true)[0].dispatchEvent(changeEvent);
- expect($('.js-task-list-field').val()).toBe('- [x] Task List Item');
+ describe('task lists', function() {
+ beforeEach(function() {
+ $('.js-comment-button').on('click', function(e) {
+ e.preventDefault();
});
+ this.notes = new Notes('', []);
+ });
- it('submits an ajax request on tasklist:changed', function() {
- spyOn(jQuery, 'ajax').and.callFake(function(req) {
- expect(req.type).toBe('PATCH');
- expect(req.url).toBe('http://test.host/frontend-fixtures/issues-project/notes/1');
- return expect(req.data.note).not.toBe(null);
- });
- $('.js-task-list-field').trigger('tasklist:changed');
+ it('modifies the Markdown field', function() {
+ const changeEvent = document.createEvent('HTMLEvents');
+ changeEvent.initEvent('change', true, true);
+ $('input[type=checkbox]').attr('checked', true)[0].dispatchEvent(changeEvent);
+ expect($('.js-task-list-field').val()).toBe('- [x] Task List Item');
+ });
+
+ it('submits an ajax request on tasklist:changed', function() {
+ spyOn(jQuery, 'ajax').and.callFake(function(req) {
+ expect(req.type).toBe('PATCH');
+ expect(req.url).toBe('http://test.host/frontend-fixtures/issues-project/notes/1');
+ return expect(req.data.note).not.toBe(null);
});
+ $('.js-task-list-field').trigger('tasklist:changed');
});
+ });
- describe('comments', function() {
- var textarea = '.js-note-text';
+ describe('comments', function() {
+ var textarea = '.js-note-text';
- beforeEach(function() {
- this.notes = new Notes('', []);
+ beforeEach(function() {
+ this.notes = new Notes('', []);
- this.autoSizeSpy = spyOnEvent($(textarea), 'autosize:update');
- spyOn(this.notes, 'renderNote').and.stub();
+ this.autoSizeSpy = spyOnEvent($(textarea), 'autosize:update');
+ spyOn(this.notes, 'renderNote').and.stub();
- $(textarea).data('autosave', {
- reset: function() {}
- });
+ $(textarea).data('autosave', {
+ reset: function() {}
+ });
- $('.js-comment-button').on('click', (e) => {
- const $form = $(this);
- e.preventDefault();
- this.notes.addNote($form);
- this.notes.reenableTargetFormSubmitButton(e);
- this.notes.resetMainTargetForm(e);
- });
+ $('.js-comment-button').on('click', (e) => {
+ const $form = $(this);
+ e.preventDefault();
+ this.notes.addNote($form);
+ this.notes.reenableTargetFormSubmitButton(e);
+ this.notes.resetMainTargetForm(e);
});
+ });
- it('autosizes after comment submission', function() {
- $(textarea).text('This is an example comment note');
- expect(this.autoSizeSpy).not.toHaveBeenTriggered();
+ it('autosizes after comment submission', function() {
+ $(textarea).text('This is an example comment note');
+ expect(this.autoSizeSpy).not.toHaveBeenTriggered();
- $('.js-comment-button').click();
- expect(this.autoSizeSpy).toHaveBeenTriggered();
- });
+ $('.js-comment-button').click();
+ expect(this.autoSizeSpy).toHaveBeenTriggered();
+ });
+ });
+
+ describe('updateNote', () => {
+ let sampleComment;
+ let noteEntity;
+ let $form;
+ let $notesContainer;
+
+ beforeEach(() => {
+ this.notes = new Notes('', []);
+ window.gon.current_username = 'root';
+ window.gon.current_user_fullname = 'Administrator';
+ sampleComment = 'foo';
+ noteEntity = {
+ id: 1234,
+ html: `<li class="note note-row-1234 timeline-entry" id="note_1234">
+ <div class="note-text">${sampleComment}</div>
+ </li>`,
+ note: sampleComment,
+ valid: true
+ };
+ $form = $('form.js-main-target-form');
+ $notesContainer = $('ul.main-notes-list');
+ $form.find('textarea.js-note-text').val(sampleComment);
});
- describe('updateNote', () => {
- let sampleComment;
- let noteEntity;
- let $form;
- let $notesContainer;
+ it('updates note and resets edit form', () => {
+ const deferred = $.Deferred();
+ spyOn($, 'ajax').and.returnValue(deferred.promise());
+ spyOn(this.notes, 'revertNoteEditForm');
+ spyOn(this.notes, 'setupNewNote');
- beforeEach(() => {
- this.notes = new Notes('', []);
- window.gon.current_username = 'root';
- window.gon.current_user_fullname = 'Administrator';
- sampleComment = 'foo';
- noteEntity = {
- id: 1234,
- html: `<li class="note note-row-1234 timeline-entry" id="note_1234">
- <div class="note-text">${sampleComment}</div>
- </li>`,
- note: sampleComment,
- valid: true
- };
- $form = $('form.js-main-target-form');
- $notesContainer = $('ul.main-notes-list');
- $form.find('textarea.js-note-text').val(sampleComment);
- });
+ $('.js-comment-button').click();
+ deferred.resolve(noteEntity);
- it('updates note and resets edit form', () => {
- const deferred = $.Deferred();
- spyOn($, 'ajax').and.returnValue(deferred.promise());
- spyOn(this.notes, 'revertNoteEditForm');
- spyOn(this.notes, 'setupNewNote');
+ const $targetNote = $notesContainer.find(`#note_${noteEntity.id}`);
+ const updatedNote = Object.assign({}, noteEntity);
+ updatedNote.note = 'bar';
+ this.notes.updateNote(updatedNote, $targetNote);
- $('.js-comment-button').click();
- deferred.resolve(noteEntity);
+ expect(this.notes.revertNoteEditForm).toHaveBeenCalledWith($targetNote);
+ expect(this.notes.setupNewNote).toHaveBeenCalled();
+ });
+ });
- const $targetNote = $notesContainer.find(`#note_${noteEntity.id}`);
- const updatedNote = Object.assign({}, noteEntity);
- updatedNote.note = 'bar';
- this.notes.updateNote(updatedNote, $targetNote);
+ describe('updateNoteTargetSelector', () => {
+ const hash = 'note_foo';
+ let $note;
- expect(this.notes.revertNoteEditForm).toHaveBeenCalledWith($targetNote);
- expect(this.notes.setupNewNote).toHaveBeenCalled();
- });
+ beforeEach(() => {
+ $note = $(`<div id="${hash}"></div>`);
+ spyOn($note, 'filter').and.callThrough();
+ spyOn($note, 'toggleClass').and.callThrough();
});
- describe('updateNoteTargetSelector', () => {
- const hash = 'note_foo';
- let $note;
+ it('sets target when hash matches', () => {
+ spyOn(gl.utils, 'getLocationHash');
+ gl.utils.getLocationHash.and.returnValue(hash);
- beforeEach(() => {
- $note = $(`<div id="${hash}"></div>`);
- spyOn($note, 'filter').and.callThrough();
- spyOn($note, 'toggleClass').and.callThrough();
- });
+ Notes.updateNoteTargetSelector($note);
- it('sets target when hash matches', () => {
- spyOn(gl.utils, 'getLocationHash');
- gl.utils.getLocationHash.and.returnValue(hash);
+ expect($note.filter).toHaveBeenCalledWith(`#${hash}`);
+ expect($note.toggleClass).toHaveBeenCalledWith('target', true);
+ });
- Notes.updateNoteTargetSelector($note);
+ it('unsets target when hash does not match', () => {
+ spyOn(gl.utils, 'getLocationHash');
+ gl.utils.getLocationHash.and.returnValue('note_doesnotexist');
- expect($note.filter).toHaveBeenCalledWith(`#${hash}`);
- expect($note.toggleClass).toHaveBeenCalledWith('target', true);
- });
+ Notes.updateNoteTargetSelector($note);
- it('unsets target when hash does not match', () => {
- spyOn(gl.utils, 'getLocationHash');
- gl.utils.getLocationHash.and.returnValue('note_doesnotexist');
+ expect($note.toggleClass).toHaveBeenCalledWith('target', false);
+ });
- Notes.updateNoteTargetSelector($note);
+ it('unsets target when there is not a hash fragment anymore', () => {
+ spyOn(gl.utils, 'getLocationHash');
+ gl.utils.getLocationHash.and.returnValue(null);
- expect($note.toggleClass).toHaveBeenCalledWith('target', false);
- });
+ Notes.updateNoteTargetSelector($note);
- it('unsets target when there is not a hash fragment anymore', () => {
- spyOn(gl.utils, 'getLocationHash');
- gl.utils.getLocationHash.and.returnValue(null);
+ expect($note.toggleClass).toHaveBeenCalledWith('target', false);
+ });
+ });
+
+ describe('renderNote', () => {
+ let notes;
+ let note;
+ let $notesList;
+
+ beforeEach(() => {
+ note = {
+ id: 1,
+ valid: true,
+ note: 'heya',
+ html: '<div>heya</div>',
+ };
+ $notesList = jasmine.createSpyObj('$notesList', [
+ 'find',
+ 'append',
+ ]);
+
+ notes = jasmine.createSpyObj('notes', [
+ 'setupNewNote',
+ 'refresh',
+ 'collapseLongCommitList',
+ 'updateNotesCount',
+ 'putConflictEditWarningInPlace'
+ ]);
+ notes.taskList = jasmine.createSpyObj('tasklist', ['init']);
+ notes.note_ids = [];
+ notes.updatedNotesTrackingMap = {};
+
+ spyOn(gl.utils, 'localTimeAgo');
+ spyOn(Notes, 'isNewNote').and.callThrough();
+ spyOn(Notes, 'isUpdatedNote').and.callThrough();
+ spyOn(Notes, 'animateAppendNote').and.callThrough();
+ spyOn(Notes, 'animateUpdateNote').and.callThrough();
+ });
- Notes.updateNoteTargetSelector($note);
+ describe('when adding note', () => {
+ it('should call .animateAppendNote', () => {
+ Notes.isNewNote.and.returnValue(true);
+ Notes.prototype.renderNote.call(notes, note, null, $notesList);
- expect($note.toggleClass).toHaveBeenCalledWith('target', false);
+ expect(Notes.animateAppendNote).toHaveBeenCalledWith(note.html, $notesList);
});
});
- describe('renderNote', () => {
- let notes;
- let note;
- let $notesList;
+ describe('when note was edited', () => {
+ it('should call .animateUpdateNote', () => {
+ Notes.isNewNote.and.returnValue(false);
+ Notes.isUpdatedNote.and.returnValue(true);
+ const $note = $('<div>');
+ $notesList.find.and.returnValue($note);
+ const $newNote = $(note.html);
+ Notes.animateUpdateNote.and.returnValue($newNote);
- beforeEach(() => {
- note = {
- id: 1,
- valid: true,
- note: 'heya',
- html: '<div>heya</div>',
- };
- $notesList = jasmine.createSpyObj('$notesList', [
- 'find',
- 'append',
- ]);
-
- notes = jasmine.createSpyObj('notes', [
- 'setupNewNote',
- 'refresh',
- 'collapseLongCommitList',
- 'updateNotesCount',
- 'putConflictEditWarningInPlace'
- ]);
- notes.taskList = jasmine.createSpyObj('tasklist', ['init']);
- notes.note_ids = [];
- notes.updatedNotesTrackingMap = {};
-
- spyOn(gl.utils, 'localTimeAgo');
- spyOn(Notes, 'isNewNote').and.callThrough();
- spyOn(Notes, 'isUpdatedNote').and.callThrough();
- spyOn(Notes, 'animateAppendNote').and.callThrough();
- spyOn(Notes, 'animateUpdateNote').and.callThrough();
+ Notes.prototype.renderNote.call(notes, note, null, $notesList);
+
+ expect(Notes.animateUpdateNote).toHaveBeenCalledWith(note.html, $note);
+ expect(notes.setupNewNote).toHaveBeenCalledWith($newNote);
});
- describe('when adding note', () => {
- it('should call .animateAppendNote', () => {
- Notes.isNewNote.and.returnValue(true);
+ describe('while editing', () => {
+ it('should update textarea if nothing has been touched', () => {
+ Notes.isNewNote.and.returnValue(false);
+ Notes.isUpdatedNote.and.returnValue(true);
+ const $note = $(`<div class="is-editing">
+ <div class="original-note-content">initial</div>
+ <textarea class="js-note-text">initial</textarea>
+ </div>`);
+ $notesList.find.and.returnValue($note);
Notes.prototype.renderNote.call(notes, note, null, $notesList);
- expect(Notes.animateAppendNote).toHaveBeenCalledWith(note.html, $notesList);
+ expect($note.find('.js-note-text').val()).toEqual(note.note);
});
- });
- describe('when note was edited', () => {
- it('should call .animateUpdateNote', () => {
+ it('should call .putConflictEditWarningInPlace', () => {
Notes.isNewNote.and.returnValue(false);
Notes.isUpdatedNote.and.returnValue(true);
- const $note = $('<div>');
+ const $note = $(`<div class="is-editing">
+ <div class="original-note-content">initial</div>
+ <textarea class="js-note-text">different</textarea>
+ </div>`);
$notesList.find.and.returnValue($note);
- const $newNote = $(note.html);
- Notes.animateUpdateNote.and.returnValue($newNote);
-
Notes.prototype.renderNote.call(notes, note, null, $notesList);
- expect(Notes.animateUpdateNote).toHaveBeenCalledWith(note.html, $note);
- expect(notes.setupNewNote).toHaveBeenCalledWith($newNote);
- });
-
- describe('while editing', () => {
- it('should update textarea if nothing has been touched', () => {
- Notes.isNewNote.and.returnValue(false);
- Notes.isUpdatedNote.and.returnValue(true);
- const $note = $(`<div class="is-editing">
- <div class="original-note-content">initial</div>
- <textarea class="js-note-text">initial</textarea>
- </div>`);
- $notesList.find.and.returnValue($note);
- Notes.prototype.renderNote.call(notes, note, null, $notesList);
-
- expect($note.find('.js-note-text').val()).toEqual(note.note);
- });
-
- it('should call .putConflictEditWarningInPlace', () => {
- Notes.isNewNote.and.returnValue(false);
- Notes.isUpdatedNote.and.returnValue(true);
- const $note = $(`<div class="is-editing">
- <div class="original-note-content">initial</div>
- <textarea class="js-note-text">different</textarea>
- </div>`);
- $notesList.find.and.returnValue($note);
- Notes.prototype.renderNote.call(notes, note, null, $notesList);
-
- expect(notes.putConflictEditWarningInPlace).toHaveBeenCalledWith(note, $note);
- });
+ expect(notes.putConflictEditWarningInPlace).toHaveBeenCalledWith(note, $note);
});
});
});
+ });
- describe('isUpdatedNote', () => {
- it('should consider same note text as the same', () => {
- const result = Notes.isUpdatedNote(
- {
- note: 'initial'
- },
- $(`<div>
- <div class="original-note-content">initial</div>
- </div>`)
- );
+ describe('isUpdatedNote', () => {
+ it('should consider same note text as the same', () => {
+ const result = Notes.isUpdatedNote(
+ {
+ note: 'initial'
+ },
+ $(`<div>
+ <div class="original-note-content">initial</div>
+ </div>`)
+ );
- expect(result).toEqual(false);
- });
+ expect(result).toEqual(false);
+ });
- it('should consider same note with trailing newline as the same', () => {
- const result = Notes.isUpdatedNote(
- {
- note: 'initial\n'
- },
- $(`<div>
- <div class="original-note-content">initial\n</div>
- </div>`)
- );
-
- expect(result).toEqual(false);
- });
+ it('should consider same note with trailing newline as the same', () => {
+ const result = Notes.isUpdatedNote(
+ {
+ note: 'initial\n'
+ },
+ $(`<div>
+ <div class="original-note-content">initial\n</div>
+ </div>`)
+ );
- it('should consider different notes as different', () => {
- const result = Notes.isUpdatedNote(
- {
- note: 'foo'
- },
- $(`<div>
- <div class="original-note-content">bar</div>
- </div>`)
- );
-
- expect(result).toEqual(true);
- });
+ expect(result).toEqual(false);
});
- describe('renderDiscussionNote', () => {
- let discussionContainer;
- let note;
- let notes;
- let $form;
- let row;
+ it('should consider different notes as different', () => {
+ const result = Notes.isUpdatedNote(
+ {
+ note: 'foo'
+ },
+ $(`<div>
+ <div class="original-note-content">bar</div>
+ </div>`)
+ );
- beforeEach(() => {
- note = {
- html: '<li></li>',
- discussion_html: '<div></div>',
- discussion_id: 1,
- discussion_resolvable: false,
- diff_discussion_html: false,
- };
- $form = jasmine.createSpyObj('$form', ['closest', 'find']);
- row = jasmine.createSpyObj('row', ['prevAll', 'first', 'find']);
-
- notes = jasmine.createSpyObj('notes', [
- 'isParallelView',
- 'updateNotesCount',
- ]);
- notes.note_ids = [];
-
- spyOn(gl.utils, 'localTimeAgo');
- spyOn(Notes, 'isNewNote');
- spyOn(Notes, 'animateAppendNote');
- Notes.isNewNote.and.returnValue(true);
- notes.isParallelView.and.returnValue(false);
- row.prevAll.and.returnValue(row);
- row.first.and.returnValue(row);
- row.find.and.returnValue(row);
- });
+ expect(result).toEqual(true);
+ });
+ });
- describe('Discussion root note', () => {
- let body;
+ describe('renderDiscussionNote', () => {
+ let discussionContainer;
+ let note;
+ let notes;
+ let $form;
+ let row;
+
+ beforeEach(() => {
+ note = {
+ html: '<li></li>',
+ discussion_html: '<div></div>',
+ discussion_id: 1,
+ discussion_resolvable: false,
+ diff_discussion_html: false,
+ };
+ $form = jasmine.createSpyObj('$form', ['closest', 'find']);
+ row = jasmine.createSpyObj('row', ['prevAll', 'first', 'find']);
+
+ notes = jasmine.createSpyObj('notes', [
+ 'isParallelView',
+ 'updateNotesCount',
+ ]);
+ notes.note_ids = [];
+
+ spyOn(gl.utils, 'localTimeAgo');
+ spyOn(Notes, 'isNewNote');
+ spyOn(Notes, 'animateAppendNote');
+ Notes.isNewNote.and.returnValue(true);
+ notes.isParallelView.and.returnValue(false);
+ row.prevAll.and.returnValue(row);
+ row.first.and.returnValue(row);
+ row.find.and.returnValue(row);
+ });
- beforeEach(() => {
- body = jasmine.createSpyObj('body', ['attr']);
- discussionContainer = { length: 0 };
+ describe('Discussion root note', () => {
+ let body;
- $form.closest.and.returnValues(row, $form);
- $form.find.and.returnValues(discussionContainer);
- body.attr.and.returnValue('');
+ beforeEach(() => {
+ body = jasmine.createSpyObj('body', ['attr']);
+ discussionContainer = { length: 0 };
- Notes.prototype.renderDiscussionNote.call(notes, note, $form);
- });
+ $form.closest.and.returnValues(row, $form);
+ $form.find.and.returnValues(discussionContainer);
+ body.attr.and.returnValue('');
- it('should call Notes.animateAppendNote', () => {
- expect(Notes.animateAppendNote).toHaveBeenCalledWith(note.discussion_html, $('.main-notes-list'));
- });
+ Notes.prototype.renderDiscussionNote.call(notes, note, $form);
});
- describe('Discussion sub note', () => {
- beforeEach(() => {
- discussionContainer = { length: 1 };
-
- $form.closest.and.returnValues(row, $form);
- $form.find.and.returnValues(discussionContainer);
-
- Notes.prototype.renderDiscussionNote.call(notes, note, $form);
- });
-
- it('should call Notes.animateAppendNote', () => {
- expect(Notes.animateAppendNote).toHaveBeenCalledWith(note.html, discussionContainer);
- });
+ it('should call Notes.animateAppendNote', () => {
+ expect(Notes.animateAppendNote).toHaveBeenCalledWith(note.discussion_html, $('.main-notes-list'));
});
});
- describe('animateAppendNote', () => {
- let noteHTML;
- let $notesList;
- let $resultantNote;
-
+ describe('Discussion sub note', () => {
beforeEach(() => {
- noteHTML = '<div></div>';
- $notesList = jasmine.createSpyObj('$notesList', ['append']);
+ discussionContainer = { length: 1 };
- $resultantNote = Notes.animateAppendNote(noteHTML, $notesList);
- });
+ $form.closest.and.returnValues(row, $form);
+ $form.find.and.returnValues(discussionContainer);
- it('should have `fade-in-full` class', () => {
- expect($resultantNote.hasClass('fade-in-full')).toEqual(true);
+ Notes.prototype.renderDiscussionNote.call(notes, note, $form);
});
- it('should append note to the notes list', () => {
- expect($notesList.append).toHaveBeenCalledWith($resultantNote);
+ it('should call Notes.animateAppendNote', () => {
+ expect(Notes.animateAppendNote).toHaveBeenCalledWith(note.html, discussionContainer);
});
});
+ });
- describe('animateUpdateNote', () => {
- let noteHTML;
- let $note;
- let $updatedNote;
-
- beforeEach(() => {
- noteHTML = '<div></div>';
- $note = jasmine.createSpyObj('$note', [
- 'replaceWith'
- ]);
+ describe('animateAppendNote', () => {
+ let noteHTML;
+ let $notesList;
+ let $resultantNote;
- $updatedNote = Notes.animateUpdateNote(noteHTML, $note);
- });
+ beforeEach(() => {
+ noteHTML = '<div></div>';
+ $notesList = jasmine.createSpyObj('$notesList', ['append']);
- it('should have `fade-in` class', () => {
- expect($updatedNote.hasClass('fade-in')).toEqual(true);
- });
+ $resultantNote = Notes.animateAppendNote(noteHTML, $notesList);
+ });
- it('should call replaceWith on $note', () => {
- expect($note.replaceWith).toHaveBeenCalledWith($updatedNote);
- });
+ it('should have `fade-in-full` class', () => {
+ expect($resultantNote.hasClass('fade-in-full')).toEqual(true);
});
- describe('putEditFormInPlace', () => {
- it('should call gl.GLForm with GFM parameter passed through', () => {
- spyOn(gl, 'GLForm');
+ it('should append note to the notes list', () => {
+ expect($notesList.append).toHaveBeenCalledWith($resultantNote);
+ });
+ });
- const $el = jasmine.createSpyObj('$form', ['find', 'closest']);
- $el.find.and.returnValue($('<div>'));
- $el.closest.and.returnValue($('<div>'));
+ describe('animateUpdateNote', () => {
+ let noteHTML;
+ let $note;
+ let $updatedNote;
- Notes.prototype.putEditFormInPlace.call({
- getEditFormSelector: () => '',
- enableGFM: true
- }, $el);
+ beforeEach(() => {
+ noteHTML = '<div></div>';
+ $note = jasmine.createSpyObj('$note', [
+ 'replaceWith'
+ ]);
- expect(gl.GLForm).toHaveBeenCalledWith(jasmine.any(Object), true);
- });
+ $updatedNote = Notes.animateUpdateNote(noteHTML, $note);
});
- describe('postComment & updateComment', () => {
- const sampleComment = 'foo';
- const updatedComment = 'bar';
- const note = {
- id: 1234,
- html: `<li class="note note-row-1234 timeline-entry" id="note_1234">
- <div class="note-text">${sampleComment}</div>
- </li>`,
- note: sampleComment,
- valid: true
- };
- let $form;
- let $notesContainer;
+ it('should have `fade-in` class', () => {
+ expect($updatedNote.hasClass('fade-in')).toEqual(true);
+ });
- beforeEach(() => {
- this.notes = new Notes('', []);
- window.gon.current_username = 'root';
- window.gon.current_user_fullname = 'Administrator';
- $form = $('form.js-main-target-form');
- $notesContainer = $('ul.main-notes-list');
- $form.find('textarea.js-note-text').val(sampleComment);
- });
+ it('should call replaceWith on $note', () => {
+ expect($note.replaceWith).toHaveBeenCalledWith($updatedNote);
+ });
+ });
- it('should show placeholder note while new comment is being posted', () => {
- $('.js-comment-button').click();
- expect($notesContainer.find('.note.being-posted').length > 0).toEqual(true);
- });
+ describe('putEditFormInPlace', () => {
+ it('should call gl.GLForm with GFM parameter passed through', () => {
+ spyOn(gl, 'GLForm');
- it('should remove placeholder note when new comment is done posting', () => {
- const deferred = $.Deferred();
- spyOn($, 'ajax').and.returnValue(deferred.promise());
- $('.js-comment-button').click();
+ const $el = jasmine.createSpyObj('$form', ['find', 'closest']);
+ $el.find.and.returnValue($('<div>'));
+ $el.closest.and.returnValue($('<div>'));
- deferred.resolve(note);
- expect($notesContainer.find('.note.being-posted').length).toEqual(0);
- });
+ Notes.prototype.putEditFormInPlace.call({
+ getEditFormSelector: () => '',
+ enableGFM: true
+ }, $el);
- it('should show actual note element when new comment is done posting', () => {
- const deferred = $.Deferred();
- spyOn($, 'ajax').and.returnValue(deferred.promise());
- $('.js-comment-button').click();
+ expect(gl.GLForm).toHaveBeenCalledWith(jasmine.any(Object), true);
+ });
+ });
- deferred.resolve(note);
- expect($notesContainer.find(`#note_${note.id}`).length > 0).toEqual(true);
- });
+ describe('postComment & updateComment', () => {
+ const sampleComment = 'foo';
+ const updatedComment = 'bar';
+ const note = {
+ id: 1234,
+ html: `<li class="note note-row-1234 timeline-entry" id="note_1234">
+ <div class="note-text">${sampleComment}</div>
+ </li>`,
+ note: sampleComment,
+ valid: true
+ };
+ let $form;
+ let $notesContainer;
+
+ beforeEach(() => {
+ this.notes = new Notes('', []);
+ window.gon.current_username = 'root';
+ window.gon.current_user_fullname = 'Administrator';
+ $form = $('form.js-main-target-form');
+ $notesContainer = $('ul.main-notes-list');
+ $form.find('textarea.js-note-text').val(sampleComment);
+ });
- it('should reset Form when new comment is done posting', () => {
- const deferred = $.Deferred();
- spyOn($, 'ajax').and.returnValue(deferred.promise());
- $('.js-comment-button').click();
+ it('should show placeholder note while new comment is being posted', () => {
+ $('.js-comment-button').click();
+ expect($notesContainer.find('.note.being-posted').length > 0).toEqual(true);
+ });
- deferred.resolve(note);
- expect($form.find('textarea.js-note-text').val()).toEqual('');
- });
+ it('should remove placeholder note when new comment is done posting', () => {
+ const deferred = $.Deferred();
+ spyOn($, 'ajax').and.returnValue(deferred.promise());
+ $('.js-comment-button').click();
- it('should show flash error message when new comment failed to be posted', () => {
- const deferred = $.Deferred();
- spyOn($, 'ajax').and.returnValue(deferred.promise());
- $('.js-comment-button').click();
+ deferred.resolve(note);
+ expect($notesContainer.find('.note.being-posted').length).toEqual(0);
+ });
- deferred.reject();
- expect($notesContainer.parent().find('.flash-container .flash-text').is(':visible')).toEqual(true);
- });
+ it('should show actual note element when new comment is done posting', () => {
+ const deferred = $.Deferred();
+ spyOn($, 'ajax').and.returnValue(deferred.promise());
+ $('.js-comment-button').click();
- it('should show flash error message when comment failed to be updated', () => {
- const deferred = $.Deferred();
- spyOn($, 'ajax').and.returnValue(deferred.promise());
- $('.js-comment-button').click();
-
- deferred.resolve(note);
- const $noteEl = $notesContainer.find(`#note_${note.id}`);
- $noteEl.find('.js-note-edit').click();
- $noteEl.find('textarea.js-note-text').val(updatedComment);
- $noteEl.find('.js-comment-save-button').click();
-
- deferred.reject();
- const $updatedNoteEl = $notesContainer.find(`#note_${note.id}`);
- expect($updatedNoteEl.hasClass('.being-posted')).toEqual(false); // Remove being-posted visuals
- expect($updatedNoteEl.find('.note-text').text().trim()).toEqual(sampleComment); // See if comment reverted back to original
- expect($('.flash-container').is(':visible')).toEqual(true); // Flash error message shown
- });
+ deferred.resolve(note);
+ expect($notesContainer.find(`#note_${note.id}`).length > 0).toEqual(true);
});
- describe('postComment with Slash commands', () => {
- const sampleComment = '/assign @root\n/award :100:';
- const note = {
- commands_changes: {
- assignee_id: 1,
- emoji_award: '100'
- },
- errors: {
- commands_only: ['Commands applied']
- },
- valid: false
- };
- let $form;
- let $notesContainer;
+ it('should reset Form when new comment is done posting', () => {
+ const deferred = $.Deferred();
+ spyOn($, 'ajax').and.returnValue(deferred.promise());
+ $('.js-comment-button').click();
- beforeEach(() => {
- this.notes = new Notes('', []);
- window.gon.current_username = 'root';
- window.gon.current_user_fullname = 'Administrator';
- gl.awardsHandler = {
- addAwardToEmojiBar: () => {},
- scrollToAwards: () => {}
- };
- gl.GfmAutoComplete = {
- dataSources: {
- commands: '/root/test-project/autocomplete_sources/commands'
- }
- };
- $form = $('form.js-main-target-form');
- $notesContainer = $('ul.main-notes-list');
- $form.find('textarea.js-note-text').val(sampleComment);
- });
+ deferred.resolve(note);
+ expect($form.find('textarea.js-note-text').val()).toEqual('');
+ });
- it('should remove slash command placeholder when comment with slash commands is done posting', () => {
- const deferred = $.Deferred();
- spyOn($, 'ajax').and.returnValue(deferred.promise());
- spyOn(gl.awardsHandler, 'addAwardToEmojiBar').and.callThrough();
- $('.js-comment-button').click();
+ it('should show flash error message when new comment failed to be posted', () => {
+ const deferred = $.Deferred();
+ spyOn($, 'ajax').and.returnValue(deferred.promise());
+ $('.js-comment-button').click();
- expect($notesContainer.find('.system-note.being-posted').length).toEqual(1); // Placeholder shown
- deferred.resolve(note);
- expect($notesContainer.find('.system-note.being-posted').length).toEqual(0); // Placeholder removed
- });
+ deferred.reject();
+ expect($notesContainer.parent().find('.flash-container .flash-text').is(':visible')).toEqual(true);
});
- describe('update comment with script tags', () => {
- const sampleComment = '<script></script>';
- const updatedComment = '<script></script>';
- const note = {
- id: 1234,
- html: `<li class="note note-row-1234 timeline-entry" id="note_1234">
- <div class="note-text">${sampleComment}</div>
- </li>`,
- note: sampleComment,
- valid: true
- };
- let $form;
- let $notesContainer;
-
- beforeEach(() => {
- this.notes = new Notes('', []);
- window.gon.current_username = 'root';
- window.gon.current_user_fullname = 'Administrator';
- $form = $('form.js-main-target-form');
- $notesContainer = $('ul.main-notes-list');
- $form.find('textarea.js-note-text').html(sampleComment);
- });
+ it('should show flash error message when comment failed to be updated', () => {
+ const deferred = $.Deferred();
+ spyOn($, 'ajax').and.returnValue(deferred.promise());
+ $('.js-comment-button').click();
+
+ deferred.resolve(note);
+ const $noteEl = $notesContainer.find(`#note_${note.id}`);
+ $noteEl.find('.js-note-edit').click();
+ $noteEl.find('textarea.js-note-text').val(updatedComment);
+ $noteEl.find('.js-comment-save-button').click();
+
+ deferred.reject();
+ const $updatedNoteEl = $notesContainer.find(`#note_${note.id}`);
+ expect($updatedNoteEl.hasClass('.being-posted')).toEqual(false); // Remove being-posted visuals
+ expect($updatedNoteEl.find('.note-text').text().trim()).toEqual(sampleComment); // See if comment reverted back to original
+ expect($('.flash-container').is(':visible')).toEqual(true); // Flash error message shown
+ });
+ });
- it('should not render a script tag', () => {
- const deferred = $.Deferred();
- spyOn($, 'ajax').and.returnValue(deferred.promise());
- $('.js-comment-button').click();
+ describe('postComment with Slash commands', () => {
+ const sampleComment = '/assign @root\n/award :100:';
+ const note = {
+ commands_changes: {
+ assignee_id: 1,
+ emoji_award: '100'
+ },
+ errors: {
+ commands_only: ['Commands applied']
+ },
+ valid: false
+ };
+ let $form;
+ let $notesContainer;
+
+ beforeEach(() => {
+ this.notes = new Notes('', []);
+ window.gon.current_username = 'root';
+ window.gon.current_user_fullname = 'Administrator';
+ gl.awardsHandler = {
+ addAwardToEmojiBar: () => {},
+ scrollToAwards: () => {}
+ };
+ gl.GfmAutoComplete = {
+ dataSources: {
+ commands: '/root/test-project/autocomplete_sources/commands'
+ }
+ };
+ $form = $('form.js-main-target-form');
+ $notesContainer = $('ul.main-notes-list');
+ $form.find('textarea.js-note-text').val(sampleComment);
+ });
- deferred.resolve(note);
- const $noteEl = $notesContainer.find(`#note_${note.id}`);
- $noteEl.find('.js-note-edit').click();
- $noteEl.find('textarea.js-note-text').html(updatedComment);
- $noteEl.find('.js-comment-save-button').click();
+ it('should remove slash command placeholder when comment with slash commands is done posting', () => {
+ const deferred = $.Deferred();
+ spyOn($, 'ajax').and.returnValue(deferred.promise());
+ spyOn(gl.awardsHandler, 'addAwardToEmojiBar').and.callThrough();
+ $('.js-comment-button').click();
- const $updatedNoteEl = $notesContainer.find(`#note_${note.id}`).find('.js-task-list-container');
- expect($updatedNoteEl.find('.note-text').text().trim()).toEqual('');
- });
+ expect($notesContainer.find('.system-note.being-posted').length).toEqual(1); // Placeholder shown
+ deferred.resolve(note);
+ expect($notesContainer.find('.system-note.being-posted').length).toEqual(0); // Placeholder removed
});
+ });
- describe('getFormData', () => {
- let $form;
- let sampleComment;
+ describe('update comment with script tags', () => {
+ const sampleComment = '<script></script>';
+ const updatedComment = '<script></script>';
+ const note = {
+ id: 1234,
+ html: `<li class="note note-row-1234 timeline-entry" id="note_1234">
+ <div class="note-text">${sampleComment}</div>
+ </li>`,
+ note: sampleComment,
+ valid: true
+ };
+ let $form;
+ let $notesContainer;
+
+ beforeEach(() => {
+ this.notes = new Notes('', []);
+ window.gon.current_username = 'root';
+ window.gon.current_user_fullname = 'Administrator';
+ $form = $('form.js-main-target-form');
+ $notesContainer = $('ul.main-notes-list');
+ $form.find('textarea.js-note-text').html(sampleComment);
+ });
- beforeEach(() => {
- this.notes = new Notes('', []);
+ it('should not render a script tag', () => {
+ const deferred = $.Deferred();
+ spyOn($, 'ajax').and.returnValue(deferred.promise());
+ $('.js-comment-button').click();
- $form = $('form');
- sampleComment = 'foobar';
- });
+ deferred.resolve(note);
+ const $noteEl = $notesContainer.find(`#note_${note.id}`);
+ $noteEl.find('.js-note-edit').click();
+ $noteEl.find('textarea.js-note-text').html(updatedComment);
+ $noteEl.find('.js-comment-save-button').click();
- it('should return form metadata object from form reference', () => {
- $form.find('textarea.js-note-text').val(sampleComment);
- const { formData, formContent, formAction } = this.notes.getFormData($form);
+ const $updatedNoteEl = $notesContainer.find(`#note_${note.id}`).find('.js-task-list-container');
+ expect($updatedNoteEl.find('.note-text').text().trim()).toEqual('');
+ });
+ });
- expect(formData.indexOf(sampleComment) > -1).toBe(true);
- expect(formContent).toEqual(sampleComment);
- expect(formAction).toEqual($form.attr('action'));
- });
+ describe('getFormData', () => {
+ let $form;
+ let sampleComment;
- it('should return form metadata with sanitized formContent from form reference', () => {
- spyOn(_, 'escape').and.callFake(htmlEscape);
+ beforeEach(() => {
+ this.notes = new Notes('', []);
- sampleComment = '<script>alert("Boom!");</script>';
- $form.find('textarea.js-note-text').val(sampleComment);
+ $form = $('form');
+ sampleComment = 'foobar';
+ });
- const { formContent } = this.notes.getFormData($form);
+ it('should return form metadata object from form reference', () => {
+ $form.find('textarea.js-note-text').val(sampleComment);
+ const { formData, formContent, formAction } = this.notes.getFormData($form);
- expect(_.escape).toHaveBeenCalledWith(sampleComment);
- expect(formContent).toEqual('&lt;script&gt;alert(&quot;Boom!&quot;);&lt;/script&gt;');
- });
+ expect(formData.indexOf(sampleComment) > -1).toBe(true);
+ expect(formContent).toEqual(sampleComment);
+ expect(formAction).toEqual($form.attr('action'));
});
- describe('hasQuickActions', () => {
- beforeEach(() => {
- this.notes = new Notes('', []);
- });
+ it('should return form metadata with sanitized formContent from form reference', () => {
+ spyOn(_, 'escape').and.callFake(htmlEscape);
- it('should return true when comment begins with a quick action', () => {
- const sampleComment = '/wip\n/milestone %1.0\n/merge\n/unassign Merging this';
- const hasQuickActions = this.notes.hasQuickActions(sampleComment);
+ sampleComment = '<script>alert("Boom!");</script>';
+ $form.find('textarea.js-note-text').val(sampleComment);
- expect(hasQuickActions).toBeTruthy();
- });
+ const { formContent } = this.notes.getFormData($form);
- it('should return false when comment does NOT begin with a quick action', () => {
- const sampleComment = 'Hey, /unassign Merging this';
- const hasQuickActions = this.notes.hasQuickActions(sampleComment);
+ expect(_.escape).toHaveBeenCalledWith(sampleComment);
+ expect(formContent).toEqual('&lt;script&gt;alert(&quot;Boom!&quot;);&lt;/script&gt;');
+ });
+ });
- expect(hasQuickActions).toBeFalsy();
- });
+ describe('hasQuickActions', () => {
+ beforeEach(() => {
+ this.notes = new Notes('', []);
+ });
- it('should return false when comment does NOT have any quick actions', () => {
- const sampleComment = 'Looking good, Awesome!';
- const hasQuickActions = this.notes.hasQuickActions(sampleComment);
+ it('should return true when comment begins with a quick action', () => {
+ const sampleComment = '/wip\n/milestone %1.0\n/merge\n/unassign Merging this';
+ const hasQuickActions = this.notes.hasQuickActions(sampleComment);
- expect(hasQuickActions).toBeFalsy();
- });
+ expect(hasQuickActions).toBeTruthy();
});
- describe('stripQuickActions', () => {
- it('should strip quick actions from the comment which begins with a quick action', () => {
- this.notes = new Notes();
- const sampleComment = '/wip\n/milestone %1.0\n/merge\n/unassign Merging this';
- const stripedComment = this.notes.stripQuickActions(sampleComment);
+ it('should return false when comment does NOT begin with a quick action', () => {
+ const sampleComment = 'Hey, /unassign Merging this';
+ const hasQuickActions = this.notes.hasQuickActions(sampleComment);
- expect(stripedComment).toBe('');
- });
+ expect(hasQuickActions).toBeFalsy();
+ });
- it('should strip quick actions from the comment but leaves plain comment if it is present', () => {
- this.notes = new Notes();
- const sampleComment = '/wip\n/milestone %1.0\n/merge\n/unassign\nMerging this';
- const stripedComment = this.notes.stripQuickActions(sampleComment);
+ it('should return false when comment does NOT have any quick actions', () => {
+ const sampleComment = 'Looking good, Awesome!';
+ const hasQuickActions = this.notes.hasQuickActions(sampleComment);
- expect(stripedComment).toBe('Merging this');
- });
+ expect(hasQuickActions).toBeFalsy();
+ });
+ });
- it('should NOT strip string that has slashes within', () => {
- this.notes = new Notes();
- const sampleComment = 'http://127.0.0.1:3000/root/gitlab-shell/issues/1';
- const stripedComment = this.notes.stripQuickActions(sampleComment);
+ describe('stripQuickActions', () => {
+ it('should strip quick actions from the comment which begins with a quick action', () => {
+ this.notes = new Notes();
+ const sampleComment = '/wip\n/milestone %1.0\n/merge\n/unassign Merging this';
+ const stripedComment = this.notes.stripQuickActions(sampleComment);
- expect(stripedComment).toBe(sampleComment);
- });
+ expect(stripedComment).toBe('');
});
- describe('getQuickActionDescription', () => {
- const availableQuickActions = [
- { name: 'close', description: 'Close this issue', params: [] },
- { name: 'title', description: 'Change title', params: [{}] },
- { name: 'estimate', description: 'Set time estimate', params: [{}] }
- ];
+ it('should strip quick actions from the comment but leaves plain comment if it is present', () => {
+ this.notes = new Notes();
+ const sampleComment = '/wip\n/milestone %1.0\n/merge\n/unassign\nMerging this';
+ const stripedComment = this.notes.stripQuickActions(sampleComment);
- beforeEach(() => {
- this.notes = new Notes();
- });
+ expect(stripedComment).toBe('Merging this');
+ });
- it('should return executing quick action description when note has single quick action', () => {
- const sampleComment = '/close';
- expect(this.notes.getQuickActionDescription(sampleComment, availableQuickActions)).toBe('Applying command to close this issue');
- });
+ it('should NOT strip string that has slashes within', () => {
+ this.notes = new Notes();
+ const sampleComment = 'http://127.0.0.1:3000/root/gitlab-shell/issues/1';
+ const stripedComment = this.notes.stripQuickActions(sampleComment);
- it('should return generic multiple quick action description when note has multiple quick actions', () => {
- const sampleComment = '/close\n/title [Duplicate] Issue foobar';
- expect(this.notes.getQuickActionDescription(sampleComment, availableQuickActions)).toBe('Applying multiple commands');
- });
+ expect(stripedComment).toBe(sampleComment);
+ });
+ });
- it('should return generic quick action description when available quick actions list is not populated', () => {
- const sampleComment = '/close\n/title [Duplicate] Issue foobar';
- expect(this.notes.getQuickActionDescription(sampleComment)).toBe('Applying command');
- });
+ describe('getQuickActionDescription', () => {
+ const availableQuickActions = [
+ { name: 'close', description: 'Close this issue', params: [] },
+ { name: 'title', description: 'Change title', params: [{}] },
+ { name: 'estimate', description: 'Set time estimate', params: [{}] }
+ ];
+
+ beforeEach(() => {
+ this.notes = new Notes();
});
- describe('createPlaceholderNote', () => {
- const sampleComment = 'foobar';
- const uniqueId = 'b1234-a4567';
- const currentUsername = 'root';
- const currentUserFullname = 'Administrator';
- const currentUserAvatar = 'avatar_url';
+ it('should return executing quick action description when note has single quick action', () => {
+ const sampleComment = '/close';
+ expect(this.notes.getQuickActionDescription(sampleComment, availableQuickActions)).toBe('Applying command to close this issue');
+ });
- beforeEach(() => {
- this.notes = new Notes('', []);
- });
+ it('should return generic multiple quick action description when note has multiple quick actions', () => {
+ const sampleComment = '/close\n/title [Duplicate] Issue foobar';
+ expect(this.notes.getQuickActionDescription(sampleComment, availableQuickActions)).toBe('Applying multiple commands');
+ });
- it('should return constructed placeholder element for regular note based on form contents', () => {
- const $tempNote = this.notes.createPlaceholderNote({
- formContent: sampleComment,
- uniqueId,
- isDiscussionNote: false,
- currentUsername,
- currentUserFullname,
- currentUserAvatar,
- });
- const $tempNoteHeader = $tempNote.find('.note-header');
-
- expect($tempNote.prop('nodeName')).toEqual('LI');
- expect($tempNote.attr('id')).toEqual(uniqueId);
- expect($tempNote.hasClass('being-posted')).toBeTruthy();
- expect($tempNote.hasClass('fade-in-half')).toBeTruthy();
- $tempNote.find('.timeline-icon > a, .note-header-info > a').each(function() {
- expect($(this).attr('href')).toEqual(`/${currentUsername}`);
- });
- expect($tempNote.find('.timeline-icon .avatar').attr('src')).toEqual(currentUserAvatar);
- expect($tempNote.find('.timeline-content').hasClass('discussion')).toBeFalsy();
- expect($tempNoteHeader.find('.hidden-xs').text().trim()).toEqual(currentUserFullname);
- expect($tempNoteHeader.find('.note-headline-light').text().trim()).toEqual(`@${currentUsername}`);
- expect($tempNote.find('.note-body .note-text p').text().trim()).toEqual(sampleComment);
- });
+ it('should return generic quick action description when available quick actions list is not populated', () => {
+ const sampleComment = '/close\n/title [Duplicate] Issue foobar';
+ expect(this.notes.getQuickActionDescription(sampleComment)).toBe('Applying command');
+ });
+ });
- it('should return constructed placeholder element for discussion note based on form contents', () => {
- const $tempNote = this.notes.createPlaceholderNote({
- formContent: sampleComment,
- uniqueId,
- isDiscussionNote: true,
- currentUsername,
- currentUserFullname
- });
+ describe('createPlaceholderNote', () => {
+ const sampleComment = 'foobar';
+ const uniqueId = 'b1234-a4567';
+ const currentUsername = 'root';
+ const currentUserFullname = 'Administrator';
+ const currentUserAvatar = 'avatar_url';
- expect($tempNote.prop('nodeName')).toEqual('LI');
- expect($tempNote.find('.timeline-content').hasClass('discussion')).toBeTruthy();
- });
+ beforeEach(() => {
+ this.notes = new Notes('', []);
});
- describe('createPlaceholderSystemNote', () => {
- const sampleCommandDescription = 'Applying command to close this issue';
- const uniqueId = 'b1234-a4567';
+ it('should return constructed placeholder element for regular note based on form contents', () => {
+ const $tempNote = this.notes.createPlaceholderNote({
+ formContent: sampleComment,
+ uniqueId,
+ isDiscussionNote: false,
+ currentUsername,
+ currentUserFullname,
+ currentUserAvatar,
+ });
+ const $tempNoteHeader = $tempNote.find('.note-header');
+
+ expect($tempNote.prop('nodeName')).toEqual('LI');
+ expect($tempNote.attr('id')).toEqual(uniqueId);
+ expect($tempNote.hasClass('being-posted')).toBeTruthy();
+ expect($tempNote.hasClass('fade-in-half')).toBeTruthy();
+ $tempNote.find('.timeline-icon > a, .note-header-info > a').each(function() {
+ expect($(this).attr('href')).toEqual(`/${currentUsername}`);
+ });
+ expect($tempNote.find('.timeline-icon .avatar').attr('src')).toEqual(currentUserAvatar);
+ expect($tempNote.find('.timeline-content').hasClass('discussion')).toBeFalsy();
+ expect($tempNoteHeader.find('.hidden-xs').text().trim()).toEqual(currentUserFullname);
+ expect($tempNoteHeader.find('.note-headline-light').text().trim()).toEqual(`@${currentUsername}`);
+ expect($tempNote.find('.note-body .note-text p').text().trim()).toEqual(sampleComment);
+ });
- beforeEach(() => {
- this.notes = new Notes('', []);
- spyOn(_, 'escape').and.callFake(htmlEscape);
+ it('should return constructed placeholder element for discussion note based on form contents', () => {
+ const $tempNote = this.notes.createPlaceholderNote({
+ formContent: sampleComment,
+ uniqueId,
+ isDiscussionNote: true,
+ currentUsername,
+ currentUserFullname
});
- it('should return constructed placeholder element for system note based on form contents', () => {
- const $tempNote = this.notes.createPlaceholderSystemNote({
- formContent: sampleCommandDescription,
- uniqueId,
- });
+ expect($tempNote.prop('nodeName')).toEqual('LI');
+ expect($tempNote.find('.timeline-content').hasClass('discussion')).toBeTruthy();
+ });
+ });
- expect($tempNote.prop('nodeName')).toEqual('LI');
- expect($tempNote.attr('id')).toEqual(uniqueId);
- expect($tempNote.hasClass('being-posted')).toBeTruthy();
- expect($tempNote.hasClass('fade-in-half')).toBeTruthy();
- expect($tempNote.find('.timeline-content i').text().trim()).toEqual(sampleCommandDescription);
- });
+ describe('createPlaceholderSystemNote', () => {
+ const sampleCommandDescription = 'Applying command to close this issue';
+ const uniqueId = 'b1234-a4567';
+
+ beforeEach(() => {
+ this.notes = new Notes('', []);
+ spyOn(_, 'escape').and.callFake(htmlEscape);
});
- describe('appendFlash', () => {
- beforeEach(() => {
- this.notes = new Notes();
+ it('should return constructed placeholder element for system note based on form contents', () => {
+ const $tempNote = this.notes.createPlaceholderSystemNote({
+ formContent: sampleCommandDescription,
+ uniqueId,
});
- it('shows a flash message', () => {
- this.notes.addFlash('Error message', FLASH_TYPE_ALERT, this.notes.parentTimeline);
+ expect($tempNote.prop('nodeName')).toEqual('LI');
+ expect($tempNote.attr('id')).toEqual(uniqueId);
+ expect($tempNote.hasClass('being-posted')).toBeTruthy();
+ expect($tempNote.hasClass('fade-in-half')).toBeTruthy();
+ expect($tempNote.find('.timeline-content i').text().trim()).toEqual(sampleCommandDescription);
+ });
+ });
- expect($('.flash-alert').is(':visible')).toBeTruthy();
- });
+ describe('appendFlash', () => {
+ beforeEach(() => {
+ this.notes = new Notes();
});
- describe('clearFlash', () => {
- beforeEach(() => {
- $(document).off('ajax:success');
- this.notes = new Notes();
- });
+ it('shows a flash message', () => {
+ this.notes.addFlash('Error message', FLASH_TYPE_ALERT, this.notes.parentTimeline);
- it('hides visible flash message', () => {
- this.notes.addFlash('Error message 1', FLASH_TYPE_ALERT, this.notes.parentTimeline);
+ expect($('.flash-alert').is(':visible')).toBeTruthy();
+ });
+ });
+
+ describe('clearFlash', () => {
+ beforeEach(() => {
+ $(document).off('ajax:success');
+ this.notes = new Notes();
+ });
- this.notes.clearFlash();
+ it('hides visible flash message', () => {
+ this.notes.addFlash('Error message 1', FLASH_TYPE_ALERT, this.notes.parentTimeline);
- expect($('.flash-alert').is(':visible')).toBeFalsy();
- });
+ this.notes.clearFlash();
+
+ expect($('.flash-alert').is(':visible')).toBeFalsy();
});
});
-}).call(window);
+});
diff --git a/spec/javascripts/pretty_time_spec.js b/spec/javascripts/pretty_time_spec.js
index de99e7e3894..eebab0ba166 100644
--- a/spec/javascripts/pretty_time_spec.js
+++ b/spec/javascripts/pretty_time_spec.js
@@ -1,134 +1,133 @@
import '~/lib/utils/pretty_time';
-(() => {
- const prettyTime = gl.utils.prettyTime;
+const gl = window.gl || (window.gl = {});
+const prettyTime = gl.utils.prettyTime;
- describe('prettyTime methods', function () {
- describe('parseSeconds', function () {
- it('should correctly parse a negative value', function () {
- const parser = prettyTime.parseSeconds;
+describe('prettyTime methods', function () {
+ describe('parseSeconds', function () {
+ it('should correctly parse a negative value', function () {
+ const parser = prettyTime.parseSeconds;
- const zeroSeconds = parser(-1000);
+ const zeroSeconds = parser(-1000);
- expect(zeroSeconds.minutes).toBe(16);
- expect(zeroSeconds.hours).toBe(0);
- expect(zeroSeconds.days).toBe(0);
- expect(zeroSeconds.weeks).toBe(0);
- });
+ expect(zeroSeconds.minutes).toBe(16);
+ expect(zeroSeconds.hours).toBe(0);
+ expect(zeroSeconds.days).toBe(0);
+ expect(zeroSeconds.weeks).toBe(0);
+ });
+
+ it('should correctly parse a zero value', function () {
+ const parser = prettyTime.parseSeconds;
+
+ const zeroSeconds = parser(0);
+
+ expect(zeroSeconds.minutes).toBe(0);
+ expect(zeroSeconds.hours).toBe(0);
+ expect(zeroSeconds.days).toBe(0);
+ expect(zeroSeconds.weeks).toBe(0);
+ });
+
+ it('should correctly parse a small non-zero second values', function () {
+ const parser = prettyTime.parseSeconds;
+
+ const subOneMinute = parser(10);
+
+ expect(subOneMinute.minutes).toBe(0);
+ expect(subOneMinute.hours).toBe(0);
+ expect(subOneMinute.days).toBe(0);
+ expect(subOneMinute.weeks).toBe(0);
- it('should correctly parse a zero value', function () {
- const parser = prettyTime.parseSeconds;
+ const aboveOneMinute = parser(100);
- const zeroSeconds = parser(0);
+ expect(aboveOneMinute.minutes).toBe(1);
+ expect(aboveOneMinute.hours).toBe(0);
+ expect(aboveOneMinute.days).toBe(0);
+ expect(aboveOneMinute.weeks).toBe(0);
- expect(zeroSeconds.minutes).toBe(0);
- expect(zeroSeconds.hours).toBe(0);
- expect(zeroSeconds.days).toBe(0);
- expect(zeroSeconds.weeks).toBe(0);
- });
+ const manyMinutes = parser(1000);
- it('should correctly parse a small non-zero second values', function () {
- const parser = prettyTime.parseSeconds;
+ expect(manyMinutes.minutes).toBe(16);
+ expect(manyMinutes.hours).toBe(0);
+ expect(manyMinutes.days).toBe(0);
+ expect(manyMinutes.weeks).toBe(0);
+ });
- const subOneMinute = parser(10);
+ it('should correctly parse large second values', function () {
+ const parser = prettyTime.parseSeconds;
- expect(subOneMinute.minutes).toBe(0);
- expect(subOneMinute.hours).toBe(0);
- expect(subOneMinute.days).toBe(0);
- expect(subOneMinute.weeks).toBe(0);
+ const aboveOneHour = parser(4800);
- const aboveOneMinute = parser(100);
+ expect(aboveOneHour.minutes).toBe(20);
+ expect(aboveOneHour.hours).toBe(1);
+ expect(aboveOneHour.days).toBe(0);
+ expect(aboveOneHour.weeks).toBe(0);
- expect(aboveOneMinute.minutes).toBe(1);
- expect(aboveOneMinute.hours).toBe(0);
- expect(aboveOneMinute.days).toBe(0);
- expect(aboveOneMinute.weeks).toBe(0);
+ const aboveOneDay = parser(110000);
- const manyMinutes = parser(1000);
+ expect(aboveOneDay.minutes).toBe(33);
+ expect(aboveOneDay.hours).toBe(6);
+ expect(aboveOneDay.days).toBe(3);
+ expect(aboveOneDay.weeks).toBe(0);
- expect(manyMinutes.minutes).toBe(16);
- expect(manyMinutes.hours).toBe(0);
- expect(manyMinutes.days).toBe(0);
- expect(manyMinutes.weeks).toBe(0);
- });
+ const aboveOneWeek = parser(25000000);
- it('should correctly parse large second values', function () {
- const parser = prettyTime.parseSeconds;
+ expect(aboveOneWeek.minutes).toBe(26);
+ expect(aboveOneWeek.hours).toBe(0);
+ expect(aboveOneWeek.days).toBe(3);
+ expect(aboveOneWeek.weeks).toBe(173);
+ });
+ });
- const aboveOneHour = parser(4800);
+ describe('stringifyTime', function () {
+ it('should stringify values with all non-zero units', function () {
+ const timeObject = {
+ weeks: 1,
+ days: 4,
+ hours: 7,
+ minutes: 20,
+ };
- expect(aboveOneHour.minutes).toBe(20);
- expect(aboveOneHour.hours).toBe(1);
- expect(aboveOneHour.days).toBe(0);
- expect(aboveOneHour.weeks).toBe(0);
+ const timeString = prettyTime.stringifyTime(timeObject);
- const aboveOneDay = parser(110000);
+ expect(timeString).toBe('1w 4d 7h 20m');
+ });
- expect(aboveOneDay.minutes).toBe(33);
- expect(aboveOneDay.hours).toBe(6);
- expect(aboveOneDay.days).toBe(3);
- expect(aboveOneDay.weeks).toBe(0);
+ it('should stringify values with some non-zero units', function () {
+ const timeObject = {
+ weeks: 0,
+ days: 4,
+ hours: 0,
+ minutes: 20,
+ };
- const aboveOneWeek = parser(25000000);
+ const timeString = prettyTime.stringifyTime(timeObject);
- expect(aboveOneWeek.minutes).toBe(26);
- expect(aboveOneWeek.hours).toBe(0);
- expect(aboveOneWeek.days).toBe(3);
- expect(aboveOneWeek.weeks).toBe(173);
- });
+ expect(timeString).toBe('4d 20m');
});
- describe('stringifyTime', function () {
- it('should stringify values with all non-zero units', function () {
- const timeObject = {
- weeks: 1,
- days: 4,
- hours: 7,
- minutes: 20,
- };
-
- const timeString = prettyTime.stringifyTime(timeObject);
-
- expect(timeString).toBe('1w 4d 7h 20m');
- });
-
- it('should stringify values with some non-zero units', function () {
- const timeObject = {
- weeks: 0,
- days: 4,
- hours: 0,
- minutes: 20,
- };
-
- const timeString = prettyTime.stringifyTime(timeObject);
-
- expect(timeString).toBe('4d 20m');
- });
-
- it('should stringify values with no non-zero units', function () {
- const timeObject = {
- weeks: 0,
- days: 0,
- hours: 0,
- minutes: 0,
- };
-
- const timeString = prettyTime.stringifyTime(timeObject);
-
- expect(timeString).toBe('0m');
- });
+ it('should stringify values with no non-zero units', function () {
+ const timeObject = {
+ weeks: 0,
+ days: 0,
+ hours: 0,
+ minutes: 0,
+ };
+
+ const timeString = prettyTime.stringifyTime(timeObject);
+
+ expect(timeString).toBe('0m');
});
+ });
- describe('abbreviateTime', function () {
- it('should abbreviate stringified times for weeks', function () {
- const fullTimeString = '1w 3d 4h 5m';
- expect(prettyTime.abbreviateTime(fullTimeString)).toBe('1w');
- });
+ describe('abbreviateTime', function () {
+ it('should abbreviate stringified times for weeks', function () {
+ const fullTimeString = '1w 3d 4h 5m';
+ expect(prettyTime.abbreviateTime(fullTimeString)).toBe('1w');
+ });
- it('should abbreviate stringified times for non-weeks', function () {
- const fullTimeString = '0w 3d 4h 5m';
- expect(prettyTime.abbreviateTime(fullTimeString)).toBe('3d');
- });
+ it('should abbreviate stringified times for non-weeks', function () {
+ const fullTimeString = '0w 3d 4h 5m';
+ expect(prettyTime.abbreviateTime(fullTimeString)).toBe('3d');
});
});
-})(window.gl || (window.gl = {}));
+});
diff --git a/spec/javascripts/right_sidebar_spec.js b/spec/javascripts/right_sidebar_spec.js
index f2072a6f350..711b19bbf9a 100644
--- a/spec/javascripts/right_sidebar_spec.js
+++ b/spec/javascripts/right_sidebar_spec.js
@@ -4,85 +4,83 @@
import '~/commons/bootstrap';
import '~/right_sidebar';
-(function() {
- var $aside, $icon, $labelsIcon, $page, $toggle, assertSidebarState;
-
- this.sidebar = null;
-
- $aside = null;
-
- $toggle = null;
-
- $icon = null;
-
- $page = null;
-
- $labelsIcon = null;
-
- assertSidebarState = function(state) {
- var shouldBeCollapsed, shouldBeExpanded;
- shouldBeExpanded = state === 'expanded';
- shouldBeCollapsed = state === 'collapsed';
- expect($aside.hasClass('right-sidebar-expanded')).toBe(shouldBeExpanded);
- expect($page.hasClass('right-sidebar-expanded')).toBe(shouldBeExpanded);
- expect($icon.hasClass('fa-angle-double-right')).toBe(shouldBeExpanded);
- expect($aside.hasClass('right-sidebar-collapsed')).toBe(shouldBeCollapsed);
- expect($page.hasClass('right-sidebar-collapsed')).toBe(shouldBeCollapsed);
- return expect($icon.hasClass('fa-angle-double-left')).toBe(shouldBeCollapsed);
- };
-
- describe('RightSidebar', function() {
- var fixtureName = 'issues/open-issue.html.raw';
- preloadFixtures(fixtureName);
- loadJSONFixtures('todos/todos.json');
-
- beforeEach(function() {
- loadFixtures(fixtureName);
- this.sidebar = new Sidebar;
- $aside = $('.right-sidebar');
- $page = $('.page-with-sidebar');
- $icon = $aside.find('i');
- $toggle = $aside.find('.js-sidebar-toggle');
- return $labelsIcon = $aside.find('.sidebar-collapsed-icon');
- });
- it('should expand/collapse the sidebar when arrow is clicked', function() {
- assertSidebarState('expanded');
- $toggle.click();
- assertSidebarState('collapsed');
- $toggle.click();
- assertSidebarState('expanded');
- });
- it('should float over the page and when sidebar icons clicked', function() {
- $labelsIcon.click();
- return assertSidebarState('expanded');
- });
- it('should collapse when the icon arrow clicked while it is floating on page', function() {
- $labelsIcon.click();
- assertSidebarState('expanded');
- $toggle.click();
- return assertSidebarState('collapsed');
- });
+var $aside, $icon, $labelsIcon, $page, $toggle, assertSidebarState;
+
+this.sidebar = null;
+
+$aside = null;
+
+$toggle = null;
+
+$icon = null;
+
+$page = null;
- it('should broadcast todo:toggle event when add todo clicked', function() {
- var todos = getJSONFixture('todos/todos.json');
- spyOn(jQuery, 'ajax').and.callFake(function() {
- var d = $.Deferred();
- var response = todos;
- d.resolve(response);
- return d.promise();
- });
+$labelsIcon = null;
- var todoToggleSpy = spyOnEvent(document, 'todo:toggle');
+assertSidebarState = function(state) {
+ var shouldBeCollapsed, shouldBeExpanded;
+ shouldBeExpanded = state === 'expanded';
+ shouldBeCollapsed = state === 'collapsed';
+ expect($aside.hasClass('right-sidebar-expanded')).toBe(shouldBeExpanded);
+ expect($page.hasClass('right-sidebar-expanded')).toBe(shouldBeExpanded);
+ expect($icon.hasClass('fa-angle-double-right')).toBe(shouldBeExpanded);
+ expect($aside.hasClass('right-sidebar-collapsed')).toBe(shouldBeCollapsed);
+ expect($page.hasClass('right-sidebar-collapsed')).toBe(shouldBeCollapsed);
+ return expect($icon.hasClass('fa-angle-double-left')).toBe(shouldBeCollapsed);
+};
- $('.issuable-sidebar-header .js-issuable-todo').click();
+describe('RightSidebar', function() {
+ var fixtureName = 'issues/open-issue.html.raw';
+ preloadFixtures(fixtureName);
+ loadJSONFixtures('todos/todos.json');
- expect(todoToggleSpy.calls.count()).toEqual(1);
+ beforeEach(function() {
+ loadFixtures(fixtureName);
+ this.sidebar = new Sidebar;
+ $aside = $('.right-sidebar');
+ $page = $('.page-with-sidebar');
+ $icon = $aside.find('i');
+ $toggle = $aside.find('.js-sidebar-toggle');
+ return $labelsIcon = $aside.find('.sidebar-collapsed-icon');
+ });
+ it('should expand/collapse the sidebar when arrow is clicked', function() {
+ assertSidebarState('expanded');
+ $toggle.click();
+ assertSidebarState('collapsed');
+ $toggle.click();
+ assertSidebarState('expanded');
+ });
+ it('should float over the page and when sidebar icons clicked', function() {
+ $labelsIcon.click();
+ return assertSidebarState('expanded');
+ });
+ it('should collapse when the icon arrow clicked while it is floating on page', function() {
+ $labelsIcon.click();
+ assertSidebarState('expanded');
+ $toggle.click();
+ return assertSidebarState('collapsed');
+ });
+
+ it('should broadcast todo:toggle event when add todo clicked', function() {
+ var todos = getJSONFixture('todos/todos.json');
+ spyOn(jQuery, 'ajax').and.callFake(function() {
+ var d = $.Deferred();
+ var response = todos;
+ d.resolve(response);
+ return d.promise();
});
- it('should not hide collapsed icons', () => {
- [].forEach.call(document.querySelectorAll('.sidebar-collapsed-icon'), (el) => {
- expect(el.querySelector('.fa, svg').classList.contains('hidden')).toBeFalsy();
- });
+ var todoToggleSpy = spyOnEvent(document, 'todo:toggle');
+
+ $('.issuable-sidebar-header .js-issuable-todo').click();
+
+ expect(todoToggleSpy.calls.count()).toEqual(1);
+ });
+
+ it('should not hide collapsed icons', () => {
+ [].forEach.call(document.querySelectorAll('.sidebar-collapsed-icon'), (el) => {
+ expect(el.querySelector('.fa, svg').classList.contains('hidden')).toBeFalsy();
});
});
-}).call(window);
+});
diff --git a/spec/javascripts/search_autocomplete_spec.js b/spec/javascripts/search_autocomplete_spec.js
index a53f58b5d0d..9594ffcdf39 100644
--- a/spec/javascripts/search_autocomplete_spec.js
+++ b/spec/javascripts/search_autocomplete_spec.js
@@ -5,173 +5,171 @@ import '~/search_autocomplete';
import '~/lib/utils/common_utils';
import 'vendor/fuzzaldrin-plus';
-(function() {
- var addBodyAttributes, assertLinks, dashboardIssuesPath, dashboardMRsPath, groupIssuesPath, groupMRsPath, groupName, mockDashboardOptions, mockGroupOptions, mockProjectOptions, projectIssuesPath, projectMRsPath, projectName, userId, widget;
- var userName = 'root';
-
- widget = null;
-
- userId = 1;
-
- dashboardIssuesPath = '/dashboard/issues';
-
- dashboardMRsPath = '/dashboard/merge_requests';
-
- projectIssuesPath = '/gitlab-org/gitlab-ce/issues';
-
- projectMRsPath = '/gitlab-org/gitlab-ce/merge_requests';
-
- groupIssuesPath = '/groups/gitlab-org/issues';
-
- groupMRsPath = '/groups/gitlab-org/merge_requests';
-
- projectName = 'GitLab Community Edition';
-
- 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) {
- section = 'dashboard';
- }
- $body = $('body');
- $body.removeAttr('data-page');
- $body.removeAttr('data-project');
- $body.removeAttr('data-group');
- switch (section) {
- case 'dashboard':
- return $body.data('page', 'root:index');
- case 'group':
- $body.data('page', 'groups:show');
- return $body.data('group', 'gitlab-org');
- case 'project':
- $body.data('page', 'projects:show');
- return $body.data('project', 'gitlab-ce');
- }
+var addBodyAttributes, assertLinks, dashboardIssuesPath, dashboardMRsPath, groupIssuesPath, groupMRsPath, groupName, mockDashboardOptions, mockGroupOptions, mockProjectOptions, projectIssuesPath, projectMRsPath, projectName, userId, widget;
+var userName = 'root';
+
+widget = null;
+
+userId = 1;
+
+dashboardIssuesPath = '/dashboard/issues';
+
+dashboardMRsPath = '/dashboard/merge_requests';
+
+projectIssuesPath = '/gitlab-org/gitlab-ce/issues';
+
+projectMRsPath = '/gitlab-org/gitlab-ce/merge_requests';
+
+groupIssuesPath = '/groups/gitlab-org/issues';
+
+groupMRsPath = '/groups/gitlab-org/merge_requests';
+
+projectName = 'GitLab Community Edition';
+
+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) {
+ section = 'dashboard';
+ }
+ $body = $('body');
+ $body.removeAttr('data-page');
+ $body.removeAttr('data-project');
+ $body.removeAttr('data-group');
+ switch (section) {
+ case 'dashboard':
+ return $body.data('page', 'root:index');
+ case 'group':
+ $body.data('page', 'groups:show');
+ return $body.data('group', 'gitlab-org');
+ case 'project':
+ $body.data('page', 'projects:show');
+ return $body.data('project', 'gitlab-ce');
+ }
+};
+
+// Mock `gl` object in window for dashboard specific page. App code will need it.
+mockDashboardOptions = function() {
+ window.gl || (window.gl = {});
+ return window.gl.dashboardOptions = {
+ issuesPath: dashboardIssuesPath,
+ mrPath: dashboardMRsPath
};
-
- // Mock `gl` object in window for dashboard specific page. App code will need it.
- mockDashboardOptions = function() {
- window.gl || (window.gl = {});
- return window.gl.dashboardOptions = {
- issuesPath: dashboardIssuesPath,
- mrPath: dashboardMRsPath
- };
- };
-
- // Mock `gl` object in window for project specific page. App code will need it.
- mockProjectOptions = function() {
- window.gl || (window.gl = {});
- return window.gl.projectOptions = {
- 'gitlab-ce': {
- issuesPath: projectIssuesPath,
- mrPath: projectMRsPath,
- projectName: projectName
- }
- };
- };
-
- mockGroupOptions = function() {
- window.gl || (window.gl = {});
- return window.gl.groupOptions = {
- 'gitlab-org': {
- issuesPath: groupIssuesPath,
- mrPath: groupMRsPath,
- projectName: groupName
- }
- };
+};
+
+// Mock `gl` object in window for project specific page. App code will need it.
+mockProjectOptions = function() {
+ window.gl || (window.gl = {});
+ return window.gl.projectOptions = {
+ 'gitlab-ce': {
+ issuesPath: projectIssuesPath,
+ mrPath: projectMRsPath,
+ projectName: projectName
+ }
};
-
- assertLinks = function(list, issuesPath, mrsPath) {
- var a1, a2, a3, a4, issuesAssignedToMeLink, issuesIHaveCreatedLink, mrsAssignedToMeLink, mrsIHaveCreatedLink;
- issuesAssignedToMeLink = issuesPath + "/?assignee_username=" + userName;
- issuesIHaveCreatedLink = issuesPath + "/?author_username=" + userName;
- mrsAssignedToMeLink = mrsPath + "/?assignee_username=" + userName;
- mrsIHaveCreatedLink = mrsPath + "/?author_username=" + userName;
- a1 = "a[href='" + issuesAssignedToMeLink + "']";
- a2 = "a[href='" + issuesIHaveCreatedLink + "']";
- a3 = "a[href='" + mrsAssignedToMeLink + "']";
- a4 = "a[href='" + mrsIHaveCreatedLink + "']";
- expect(list.find(a1).length).toBe(1);
- expect(list.find(a1).text()).toBe('Issues assigned to me');
- expect(list.find(a2).length).toBe(1);
- expect(list.find(a2).text()).toBe("Issues I've created");
- expect(list.find(a3).length).toBe(1);
- expect(list.find(a3).text()).toBe('Merge requests assigned to me');
- expect(list.find(a4).length).toBe(1);
- return expect(list.find(a4).text()).toBe("Merge requests I've created");
+};
+
+mockGroupOptions = function() {
+ window.gl || (window.gl = {});
+ return window.gl.groupOptions = {
+ 'gitlab-org': {
+ issuesPath: groupIssuesPath,
+ mrPath: groupMRsPath,
+ projectName: groupName
+ }
};
+};
+
+assertLinks = function(list, issuesPath, mrsPath) {
+ var a1, a2, a3, a4, issuesAssignedToMeLink, issuesIHaveCreatedLink, mrsAssignedToMeLink, mrsIHaveCreatedLink;
+ issuesAssignedToMeLink = issuesPath + "/?assignee_username=" + userName;
+ issuesIHaveCreatedLink = issuesPath + "/?author_username=" + userName;
+ mrsAssignedToMeLink = mrsPath + "/?assignee_username=" + userName;
+ mrsIHaveCreatedLink = mrsPath + "/?author_username=" + userName;
+ a1 = "a[href='" + issuesAssignedToMeLink + "']";
+ a2 = "a[href='" + issuesIHaveCreatedLink + "']";
+ a3 = "a[href='" + mrsAssignedToMeLink + "']";
+ a4 = "a[href='" + mrsIHaveCreatedLink + "']";
+ expect(list.find(a1).length).toBe(1);
+ expect(list.find(a1).text()).toBe('Issues assigned to me');
+ expect(list.find(a2).length).toBe(1);
+ expect(list.find(a2).text()).toBe("Issues I've created");
+ expect(list.find(a3).length).toBe(1);
+ expect(list.find(a3).text()).toBe('Merge requests assigned to me');
+ expect(list.find(a4).length).toBe(1);
+ return expect(list.find(a4).text()).toBe("Merge requests I've created");
+};
+
+describe('Search autocomplete dropdown', function() {
+ preloadFixtures('static/search_autocomplete.html.raw');
+ beforeEach(function() {
+ loadFixtures('static/search_autocomplete.html.raw');
+ widget = new gl.SearchAutocomplete;
+ // Prevent turbolinks from triggering within gl_dropdown
+ spyOn(window.gl.utils, 'visitUrl').and.returnValue(true);
+
+ window.gon = {};
+ window.gon.current_user_id = userId;
+ window.gon.current_username = userName;
+
+ return widget = new gl.SearchAutocomplete;
+ });
- describe('Search autocomplete dropdown', function() {
- preloadFixtures('static/search_autocomplete.html.raw');
- beforeEach(function() {
- loadFixtures('static/search_autocomplete.html.raw');
- widget = new gl.SearchAutocomplete;
- // Prevent turbolinks from triggering within gl_dropdown
- spyOn(window.gl.utils, 'visitUrl').and.returnValue(true);
-
- window.gon = {};
- window.gon.current_user_id = userId;
- window.gon.current_username = userName;
-
- return widget = new gl.SearchAutocomplete;
- });
-
- afterEach(function() {
- window.gon = {};
- });
- it('should show Dashboard specific dropdown menu', function() {
- var list;
- addBodyAttributes();
- mockDashboardOptions();
- widget.searchInput.triggerHandler('focus');
- list = widget.wrap.find('.dropdown-menu').find('ul');
- return assertLinks(list, dashboardIssuesPath, dashboardMRsPath);
- });
- it('should show Group specific dropdown menu', function() {
- var list;
- addBodyAttributes('group');
- mockGroupOptions();
- widget.searchInput.triggerHandler('focus');
- list = widget.wrap.find('.dropdown-menu').find('ul');
- return assertLinks(list, groupIssuesPath, groupMRsPath);
- });
- it('should show Project specific dropdown menu', function() {
- var list;
- addBodyAttributes('project');
- mockProjectOptions();
- widget.searchInput.triggerHandler('focus');
- list = widget.wrap.find('.dropdown-menu').find('ul');
- return assertLinks(list, projectIssuesPath, projectMRsPath);
- });
- it('should not show category related menu if there is text in the input', function() {
- var link, list;
- addBodyAttributes('project');
- mockProjectOptions();
- widget.searchInput.val('help');
- widget.searchInput.triggerHandler('focus');
- list = widget.wrap.find('.dropdown-menu').find('ul');
- link = "a[href='" + projectIssuesPath + "/?assignee_id=" + userId + "']";
- return expect(list.find(link).length).toBe(0);
- });
- return it('should not submit the search form when selecting an autocomplete row with the keyboard', function() {
- var ENTER = 13;
- var DOWN = 40;
- addBodyAttributes();
- mockDashboardOptions(true);
- var submitSpy = spyOnEvent('form', 'submit');
- widget.searchInput.triggerHandler('focus');
- widget.wrap.trigger($.Event('keydown', { which: DOWN }));
- var enterKeyEvent = $.Event('keydown', { which: ENTER });
- widget.searchInput.trigger(enterKeyEvent);
- // This does not currently catch failing behavior. For security reasons,
- // browsers will not trigger default behavior (form submit, in this
- // example) on JavaScript-created keypresses.
- expect(submitSpy).not.toHaveBeenTriggered();
- // Does a worse job at capturing the intent of the test, but works.
- expect(enterKeyEvent.isDefaultPrevented()).toBe(true);
- });
+ afterEach(function() {
+ window.gon = {};
+ });
+ it('should show Dashboard specific dropdown menu', function() {
+ var list;
+ addBodyAttributes();
+ mockDashboardOptions();
+ widget.searchInput.triggerHandler('focus');
+ list = widget.wrap.find('.dropdown-menu').find('ul');
+ return assertLinks(list, dashboardIssuesPath, dashboardMRsPath);
+ });
+ it('should show Group specific dropdown menu', function() {
+ var list;
+ addBodyAttributes('group');
+ mockGroupOptions();
+ widget.searchInput.triggerHandler('focus');
+ list = widget.wrap.find('.dropdown-menu').find('ul');
+ return assertLinks(list, groupIssuesPath, groupMRsPath);
+ });
+ it('should show Project specific dropdown menu', function() {
+ var list;
+ addBodyAttributes('project');
+ mockProjectOptions();
+ widget.searchInput.triggerHandler('focus');
+ list = widget.wrap.find('.dropdown-menu').find('ul');
+ return assertLinks(list, projectIssuesPath, projectMRsPath);
+ });
+ it('should not show category related menu if there is text in the input', function() {
+ var link, list;
+ addBodyAttributes('project');
+ mockProjectOptions();
+ widget.searchInput.val('help');
+ widget.searchInput.triggerHandler('focus');
+ list = widget.wrap.find('.dropdown-menu').find('ul');
+ link = "a[href='" + projectIssuesPath + "/?assignee_id=" + userId + "']";
+ return expect(list.find(link).length).toBe(0);
+ });
+ return it('should not submit the search form when selecting an autocomplete row with the keyboard', function() {
+ var ENTER = 13;
+ var DOWN = 40;
+ addBodyAttributes();
+ mockDashboardOptions(true);
+ var submitSpy = spyOnEvent('form', 'submit');
+ widget.searchInput.triggerHandler('focus');
+ widget.wrap.trigger($.Event('keydown', { which: DOWN }));
+ var enterKeyEvent = $.Event('keydown', { which: ENTER });
+ widget.searchInput.trigger(enterKeyEvent);
+ // This does not currently catch failing behavior. For security reasons,
+ // browsers will not trigger default behavior (form submit, in this
+ // example) on JavaScript-created keypresses.
+ expect(submitSpy).not.toHaveBeenTriggered();
+ // Does a worse job at capturing the intent of the test, but works.
+ expect(enterKeyEvent.isDefaultPrevented()).toBe(true);
});
-}).call(window);
+});
diff --git a/spec/javascripts/shortcuts_issuable_spec.js b/spec/javascripts/shortcuts_issuable_spec.js
index 3515dfbc60b..e621a13fe39 100644
--- a/spec/javascripts/shortcuts_issuable_spec.js
+++ b/spec/javascripts/shortcuts_issuable_spec.js
@@ -4,75 +4,73 @@
import '~/copy_as_gfm';
import '~/shortcuts_issuable';
-(function() {
- describe('ShortcutsIssuable', function() {
- var fixtureName = 'issues/open-issue.html.raw';
- preloadFixtures(fixtureName);
+describe('ShortcutsIssuable', function() {
+ var fixtureName = 'issues/open-issue.html.raw';
+ preloadFixtures(fixtureName);
+ beforeEach(function() {
+ loadFixtures(fixtureName);
+ document.querySelector('.js-new-note-form').classList.add('js-main-target-form');
+ this.shortcut = new ShortcutsIssuable();
+ });
+ describe('replyWithSelectedText', function() {
+ var stubSelection;
+ // Stub window.gl.utils.getSelectedFragment to return a node with the provided HTML.
+ stubSelection = function(html) {
+ window.gl.utils.getSelectedFragment = function() {
+ var node = document.createElement('div');
+ node.innerHTML = html;
+ return node;
+ };
+ };
beforeEach(function() {
- loadFixtures(fixtureName);
- document.querySelector('.js-new-note-form').classList.add('js-main-target-form');
- this.shortcut = new ShortcutsIssuable();
+ this.selector = 'form.js-main-target-form textarea#note_note';
});
- describe('replyWithSelectedText', function() {
- var stubSelection;
- // Stub window.gl.utils.getSelectedFragment to return a node with the provided HTML.
- stubSelection = function(html) {
- window.gl.utils.getSelectedFragment = function() {
- var node = document.createElement('div');
- node.innerHTML = html;
- return node;
- };
- };
+ describe('with empty selection', function() {
+ it('does not return an error', function() {
+ this.shortcut.replyWithSelectedText();
+ expect($(this.selector).val()).toBe('');
+ });
+ it('triggers `focus`', function() {
+ this.shortcut.replyWithSelectedText();
+ expect(document.activeElement).toBe(document.querySelector(this.selector));
+ });
+ });
+ describe('with any selection', function() {
beforeEach(function() {
- this.selector = 'form.js-main-target-form textarea#note_note';
+ stubSelection('<p>Selected text.</p>');
});
- describe('with empty selection', function() {
- it('does not return an error', function() {
- this.shortcut.replyWithSelectedText();
- expect($(this.selector).val()).toBe('');
- });
- it('triggers `focus`', function() {
- this.shortcut.replyWithSelectedText();
- expect(document.activeElement).toBe(document.querySelector(this.selector));
- });
+ it('leaves existing input intact', function() {
+ $(this.selector).val('This text was already here.');
+ expect($(this.selector).val()).toBe('This text was already here.');
+ this.shortcut.replyWithSelectedText();
+ expect($(this.selector).val()).toBe("This text was already here.\n\n> Selected text.\n\n");
});
- describe('with any selection', function() {
- beforeEach(function() {
- stubSelection('<p>Selected text.</p>');
- });
- it('leaves existing input intact', function() {
- $(this.selector).val('This text was already here.');
- expect($(this.selector).val()).toBe('This text was already here.');
- this.shortcut.replyWithSelectedText();
- expect($(this.selector).val()).toBe("This text was already here.\n\n> Selected text.\n\n");
- });
- it('triggers `input`', function() {
- var triggered = false;
- $(this.selector).on('input', function() {
- triggered = true;
- });
- this.shortcut.replyWithSelectedText();
- expect(triggered).toBe(true);
- });
- it('triggers `focus`', function() {
- this.shortcut.replyWithSelectedText();
- expect(document.activeElement).toBe(document.querySelector(this.selector));
+ it('triggers `input`', function() {
+ var triggered = false;
+ $(this.selector).on('input', function() {
+ triggered = true;
});
+ this.shortcut.replyWithSelectedText();
+ expect(triggered).toBe(true);
});
- describe('with a one-line selection', function() {
- it('quotes the selection', function() {
- stubSelection('<p>This text has been selected.</p>');
- this.shortcut.replyWithSelectedText();
- expect($(this.selector).val()).toBe("> This text has been selected.\n\n");
- });
+ it('triggers `focus`', function() {
+ this.shortcut.replyWithSelectedText();
+ expect(document.activeElement).toBe(document.querySelector(this.selector));
});
- describe('with a multi-line selection', function() {
- it('quotes the selected lines as a group', function() {
- stubSelection("<p>Selected line one.</p>\n\n<p>Selected line two.</p>\n\n<p>Selected line three.</p>");
- this.shortcut.replyWithSelectedText();
- expect($(this.selector).val()).toBe("> Selected line one.\n>\n> Selected line two.\n>\n> Selected line three.\n\n");
- });
+ });
+ describe('with a one-line selection', function() {
+ it('quotes the selection', function() {
+ stubSelection('<p>This text has been selected.</p>');
+ this.shortcut.replyWithSelectedText();
+ expect($(this.selector).val()).toBe("> This text has been selected.\n\n");
+ });
+ });
+ describe('with a multi-line selection', function() {
+ it('quotes the selected lines as a group', function() {
+ stubSelection("<p>Selected line one.</p>\n\n<p>Selected line two.</p>\n\n<p>Selected line three.</p>");
+ this.shortcut.replyWithSelectedText();
+ expect($(this.selector).val()).toBe("> Selected line one.\n>\n> Selected line two.\n>\n> Selected line three.\n\n");
});
});
});
-}).call(window);
+});
diff --git a/spec/javascripts/smart_interval_spec.js b/spec/javascripts/smart_interval_spec.js
index 7833bf3fb04..71147eaea32 100644
--- a/spec/javascripts/smart_interval_spec.js
+++ b/spec/javascripts/smart_interval_spec.js
@@ -1,179 +1,178 @@
import '~/smart_interval';
-(() => {
- const DEFAULT_MAX_INTERVAL = 100;
- const DEFAULT_STARTING_INTERVAL = 5;
- const DEFAULT_SHORT_TIMEOUT = 75;
- const DEFAULT_LONG_TIMEOUT = 1000;
- const DEFAULT_INCREMENT_FACTOR = 2;
-
- function createDefaultSmartInterval(config) {
- const defaultParams = {
- callback: () => {},
- startingInterval: DEFAULT_STARTING_INTERVAL,
- maxInterval: DEFAULT_MAX_INTERVAL,
- incrementByFactorOf: DEFAULT_INCREMENT_FACTOR,
- lazyStart: false,
- immediateExecution: false,
- hiddenInterval: null,
- };
-
- if (config) {
- _.extend(defaultParams, config);
- }
-
- return new gl.SmartInterval(defaultParams);
+const gl = window.gl || (window.gl = {});
+const DEFAULT_MAX_INTERVAL = 100;
+const DEFAULT_STARTING_INTERVAL = 5;
+const DEFAULT_SHORT_TIMEOUT = 75;
+const DEFAULT_LONG_TIMEOUT = 1000;
+const DEFAULT_INCREMENT_FACTOR = 2;
+
+function createDefaultSmartInterval(config) {
+ const defaultParams = {
+ callback: () => {},
+ startingInterval: DEFAULT_STARTING_INTERVAL,
+ maxInterval: DEFAULT_MAX_INTERVAL,
+ incrementByFactorOf: DEFAULT_INCREMENT_FACTOR,
+ lazyStart: false,
+ immediateExecution: false,
+ hiddenInterval: null,
+ };
+
+ if (config) {
+ _.extend(defaultParams, config);
}
- describe('SmartInterval', function () {
- describe('Increment Interval', function () {
- beforeEach(function () {
- this.smartInterval = createDefaultSmartInterval();
- });
-
- it('should increment the interval delay', function (done) {
- const interval = this.smartInterval;
- setTimeout(() => {
- const intervalConfig = this.smartInterval.cfg;
- const iterationCount = 4;
- const maxIntervalAfterIterations = intervalConfig.startingInterval *
- (intervalConfig.incrementByFactorOf ** (iterationCount - 1)); // 40
- const currentInterval = interval.getCurrentInterval();
-
- // Provide some flexibility for performance of testing environment
- expect(currentInterval).toBeGreaterThan(intervalConfig.startingInterval);
- expect(currentInterval <= maxIntervalAfterIterations).toBeTruthy();
-
- done();
- }, DEFAULT_SHORT_TIMEOUT); // 4 iterations, increment by 2x = (5 + 10 + 20 + 40)
- });
-
- it('should not increment past maxInterval', function (done) {
- const interval = this.smartInterval;
-
- setTimeout(() => {
- const currentInterval = interval.getCurrentInterval();
- expect(currentInterval).toBe(interval.cfg.maxInterval);
-
- done();
- }, DEFAULT_LONG_TIMEOUT);
- });
+ return new gl.SmartInterval(defaultParams);
+}
+
+describe('SmartInterval', function () {
+ describe('Increment Interval', function () {
+ beforeEach(function () {
+ this.smartInterval = createDefaultSmartInterval();
+ });
+
+ it('should increment the interval delay', function (done) {
+ const interval = this.smartInterval;
+ setTimeout(() => {
+ const intervalConfig = this.smartInterval.cfg;
+ const iterationCount = 4;
+ const maxIntervalAfterIterations = intervalConfig.startingInterval *
+ (intervalConfig.incrementByFactorOf ** (iterationCount - 1)); // 40
+ const currentInterval = interval.getCurrentInterval();
+
+ // Provide some flexibility for performance of testing environment
+ expect(currentInterval).toBeGreaterThan(intervalConfig.startingInterval);
+ expect(currentInterval <= maxIntervalAfterIterations).toBeTruthy();
+
+ done();
+ }, DEFAULT_SHORT_TIMEOUT); // 4 iterations, increment by 2x = (5 + 10 + 20 + 40)
+ });
+
+ it('should not increment past maxInterval', function (done) {
+ const interval = this.smartInterval;
+
+ setTimeout(() => {
+ const currentInterval = interval.getCurrentInterval();
+ expect(currentInterval).toBe(interval.cfg.maxInterval);
+
+ done();
+ }, DEFAULT_LONG_TIMEOUT);
});
+ });
- describe('Public methods', function () {
- beforeEach(function () {
- this.smartInterval = createDefaultSmartInterval();
- });
+ describe('Public methods', function () {
+ beforeEach(function () {
+ this.smartInterval = createDefaultSmartInterval();
+ });
- it('should cancel an interval', function (done) {
- const interval = this.smartInterval;
+ it('should cancel an interval', function (done) {
+ const interval = this.smartInterval;
- setTimeout(() => {
- interval.cancel();
+ setTimeout(() => {
+ interval.cancel();
- const intervalId = interval.state.intervalId;
- const currentInterval = interval.getCurrentInterval();
- const intervalLowerLimit = interval.cfg.startingInterval;
+ const intervalId = interval.state.intervalId;
+ const currentInterval = interval.getCurrentInterval();
+ const intervalLowerLimit = interval.cfg.startingInterval;
- expect(intervalId).toBeUndefined();
- expect(currentInterval).toBe(intervalLowerLimit);
+ expect(intervalId).toBeUndefined();
+ expect(currentInterval).toBe(intervalLowerLimit);
- done();
- }, DEFAULT_SHORT_TIMEOUT);
- });
+ done();
+ }, DEFAULT_SHORT_TIMEOUT);
+ });
- it('should resume an interval', function (done) {
- const interval = this.smartInterval;
+ it('should resume an interval', function (done) {
+ const interval = this.smartInterval;
- setTimeout(() => {
- interval.cancel();
+ setTimeout(() => {
+ interval.cancel();
- interval.resume();
+ interval.resume();
- const intervalId = interval.state.intervalId;
+ const intervalId = interval.state.intervalId;
- expect(intervalId).toBeTruthy();
+ expect(intervalId).toBeTruthy();
- done();
- }, DEFAULT_SHORT_TIMEOUT);
- });
+ done();
+ }, DEFAULT_SHORT_TIMEOUT);
});
+ });
- describe('DOM Events', function () {
- beforeEach(function () {
- // This ensures DOM and DOM events are initialized for these specs.
- setFixtures('<div></div>');
+ describe('DOM Events', function () {
+ beforeEach(function () {
+ // This ensures DOM and DOM events are initialized for these specs.
+ setFixtures('<div></div>');
- this.smartInterval = createDefaultSmartInterval();
- });
+ this.smartInterval = createDefaultSmartInterval();
+ });
- it('should pause when page is not visible', function (done) {
- const interval = this.smartInterval;
+ it('should pause when page is not visible', function (done) {
+ const interval = this.smartInterval;
- setTimeout(() => {
- expect(interval.state.intervalId).toBeTruthy();
+ setTimeout(() => {
+ expect(interval.state.intervalId).toBeTruthy();
- // simulates triggering of visibilitychange event
- interval.handleVisibilityChange({ target: { visibilityState: 'hidden' } });
+ // simulates triggering of visibilitychange event
+ interval.handleVisibilityChange({ target: { visibilityState: 'hidden' } });
- expect(interval.state.intervalId).toBeUndefined();
- done();
- }, DEFAULT_SHORT_TIMEOUT);
- });
+ expect(interval.state.intervalId).toBeUndefined();
+ done();
+ }, DEFAULT_SHORT_TIMEOUT);
+ });
- it('should change to the hidden interval when page is not visible', function (done) {
- const HIDDEN_INTERVAL = 1500;
- const interval = createDefaultSmartInterval({ hiddenInterval: HIDDEN_INTERVAL });
+ it('should change to the hidden interval when page is not visible', function (done) {
+ const HIDDEN_INTERVAL = 1500;
+ const interval = createDefaultSmartInterval({ hiddenInterval: HIDDEN_INTERVAL });
- setTimeout(() => {
- expect(interval.state.intervalId).toBeTruthy();
- expect(interval.getCurrentInterval() >= DEFAULT_STARTING_INTERVAL &&
- interval.getCurrentInterval() <= DEFAULT_MAX_INTERVAL).toBeTruthy();
+ setTimeout(() => {
+ expect(interval.state.intervalId).toBeTruthy();
+ expect(interval.getCurrentInterval() >= DEFAULT_STARTING_INTERVAL &&
+ interval.getCurrentInterval() <= DEFAULT_MAX_INTERVAL).toBeTruthy();
- // simulates triggering of visibilitychange event
- interval.handleVisibilityChange({ target: { visibilityState: 'hidden' } });
+ // simulates triggering of visibilitychange event
+ interval.handleVisibilityChange({ target: { visibilityState: 'hidden' } });
- expect(interval.state.intervalId).toBeTruthy();
- expect(interval.getCurrentInterval()).toBe(HIDDEN_INTERVAL);
- done();
- }, DEFAULT_SHORT_TIMEOUT);
- });
+ expect(interval.state.intervalId).toBeTruthy();
+ expect(interval.getCurrentInterval()).toBe(HIDDEN_INTERVAL);
+ done();
+ }, DEFAULT_SHORT_TIMEOUT);
+ });
- it('should resume when page is becomes visible at the previous interval', function (done) {
- const interval = this.smartInterval;
+ it('should resume when page is becomes visible at the previous interval', function (done) {
+ const interval = this.smartInterval;
- setTimeout(() => {
- expect(interval.state.intervalId).toBeTruthy();
+ setTimeout(() => {
+ expect(interval.state.intervalId).toBeTruthy();
- // simulates triggering of visibilitychange event
- interval.handleVisibilityChange({ target: { visibilityState: 'hidden' } });
+ // simulates triggering of visibilitychange event
+ interval.handleVisibilityChange({ target: { visibilityState: 'hidden' } });
- expect(interval.state.intervalId).toBeUndefined();
+ expect(interval.state.intervalId).toBeUndefined();
- // simulates triggering of visibilitychange event
- interval.handleVisibilityChange({ target: { visibilityState: 'visible' } });
+ // simulates triggering of visibilitychange event
+ interval.handleVisibilityChange({ target: { visibilityState: 'visible' } });
- expect(interval.state.intervalId).toBeTruthy();
+ expect(interval.state.intervalId).toBeTruthy();
- done();
- }, DEFAULT_SHORT_TIMEOUT);
- });
+ done();
+ }, DEFAULT_SHORT_TIMEOUT);
+ });
- it('should cancel on page unload', function (done) {
- const interval = this.smartInterval;
+ it('should cancel on page unload', function (done) {
+ const interval = this.smartInterval;
- setTimeout(() => {
- $(document).triggerHandler('beforeunload');
- expect(interval.state.intervalId).toBeUndefined();
- expect(interval.getCurrentInterval()).toBe(interval.cfg.startingInterval);
- done();
- }, DEFAULT_SHORT_TIMEOUT);
- });
+ setTimeout(() => {
+ $(document).triggerHandler('beforeunload');
+ expect(interval.state.intervalId).toBeUndefined();
+ expect(interval.getCurrentInterval()).toBe(interval.cfg.startingInterval);
+ done();
+ }, DEFAULT_SHORT_TIMEOUT);
+ });
- it('should execute callback before first interval', function () {
- const interval = createDefaultSmartInterval({ immediateExecution: true });
- expect(interval.cfg.immediateExecution).toBeFalsy();
- });
+ it('should execute callback before first interval', function () {
+ const interval = createDefaultSmartInterval({ immediateExecution: true });
+ expect(interval.cfg.immediateExecution).toBeFalsy();
});
});
-})(window.gl || (window.gl = {}));
+});
diff --git a/spec/javascripts/syntax_highlight_spec.js b/spec/javascripts/syntax_highlight_spec.js
index 946f98379ce..4a7d623fb1c 100644
--- a/spec/javascripts/syntax_highlight_spec.js
+++ b/spec/javascripts/syntax_highlight_spec.js
@@ -2,43 +2,41 @@
import '~/syntax_highlight';
-(function() {
- describe('Syntax Highlighter', function() {
- var stubUserColorScheme;
- stubUserColorScheme = function(value) {
- if (window.gon == null) {
- window.gon = {};
- }
- return window.gon.user_color_scheme = value;
- };
- describe('on a js-syntax-highlight element', function() {
- beforeEach(function() {
- return setFixtures('<div class="js-syntax-highlight"></div>');
- });
- return it('applies syntax highlighting', function() {
- stubUserColorScheme('monokai');
- $('.js-syntax-highlight').syntaxHighlight();
- return expect($('.js-syntax-highlight')).toHaveClass('monokai');
- });
+describe('Syntax Highlighter', function() {
+ var stubUserColorScheme;
+ stubUserColorScheme = function(value) {
+ if (window.gon == null) {
+ window.gon = {};
+ }
+ return window.gon.user_color_scheme = value;
+ };
+ describe('on a js-syntax-highlight element', function() {
+ beforeEach(function() {
+ return setFixtures('<div class="js-syntax-highlight"></div>');
});
- return describe('on a parent element', function() {
- beforeEach(function() {
- return setFixtures("<div class=\"parent\">\n <div class=\"js-syntax-highlight\"></div>\n <div class=\"foo\"></div>\n <div class=\"js-syntax-highlight\"></div>\n</div>");
- });
- it('applies highlighting to all applicable children', function() {
- stubUserColorScheme('monokai');
- $('.parent').syntaxHighlight();
- expect($('.parent, .foo')).not.toHaveClass('monokai');
- return expect($('.monokai').length).toBe(2);
- });
- return it('prevents an infinite loop when no matches exist', function() {
- var highlight;
- setFixtures('<div></div>');
- highlight = function() {
- return $('div').syntaxHighlight();
- };
- return expect(highlight).not.toThrow();
- });
+ return it('applies syntax highlighting', function() {
+ stubUserColorScheme('monokai');
+ $('.js-syntax-highlight').syntaxHighlight();
+ return expect($('.js-syntax-highlight')).toHaveClass('monokai');
});
});
-}).call(window);
+ return describe('on a parent element', function() {
+ beforeEach(function() {
+ return setFixtures("<div class=\"parent\">\n <div class=\"js-syntax-highlight\"></div>\n <div class=\"foo\"></div>\n <div class=\"js-syntax-highlight\"></div>\n</div>");
+ });
+ it('applies highlighting to all applicable children', function() {
+ stubUserColorScheme('monokai');
+ $('.parent').syntaxHighlight();
+ expect($('.parent, .foo')).not.toHaveClass('monokai');
+ return expect($('.monokai').length).toBe(2);
+ });
+ return it('prevents an infinite loop when no matches exist', function() {
+ var highlight;
+ setFixtures('<div></div>');
+ highlight = function() {
+ return $('div').syntaxHighlight();
+ };
+ return expect(highlight).not.toThrow();
+ });
+ });
+});
diff --git a/spec/javascripts/u2f/authenticate_spec.js b/spec/javascripts/u2f/authenticate_spec.js
index a160c86308d..c9a10f607e3 100644
--- a/spec/javascripts/u2f/authenticate_spec.js
+++ b/spec/javascripts/u2f/authenticate_spec.js
@@ -8,65 +8,63 @@ import '~/u2f/error';
import 'vendor/u2f';
import './mock_u2f_device';
-(function() {
- describe('U2FAuthenticate', function() {
- preloadFixtures('u2f/authenticate.html.raw');
+describe('U2FAuthenticate', function() {
+ preloadFixtures('u2f/authenticate.html.raw');
- beforeEach(function() {
- loadFixtures('u2f/authenticate.html.raw');
- this.u2fDevice = new MockU2FDevice;
- this.container = $("#js-authenticate-u2f");
- this.component = new window.gl.U2FAuthenticate(
- this.container,
- '#js-login-u2f-form',
- {
- sign_requests: []
- },
- document.querySelector('#js-login-2fa-device'),
- document.querySelector('.js-2fa-form')
- );
+ beforeEach(function() {
+ loadFixtures('u2f/authenticate.html.raw');
+ this.u2fDevice = new MockU2FDevice;
+ this.container = $("#js-authenticate-u2f");
+ this.component = new window.gl.U2FAuthenticate(
+ this.container,
+ '#js-login-u2f-form',
+ {
+ sign_requests: []
+ },
+ document.querySelector('#js-login-2fa-device'),
+ document.querySelector('.js-2fa-form')
+ );
- // bypass automatic form submission within renderAuthenticated
- spyOn(this.component, 'renderAuthenticated').and.returnValue(true);
+ // bypass automatic form submission within renderAuthenticated
+ spyOn(this.component, 'renderAuthenticated').and.returnValue(true);
- return this.component.start();
+ return this.component.start();
+ });
+ it('allows authenticating via a U2F device', function() {
+ var inProgressMessage;
+ inProgressMessage = this.container.find("p");
+ expect(inProgressMessage.text()).toContain("Trying to communicate with your device");
+ this.u2fDevice.respondToAuthenticateRequest({
+ deviceData: "this is data from the device"
});
- it('allows authenticating via a U2F device', function() {
- var inProgressMessage;
- inProgressMessage = this.container.find("p");
- expect(inProgressMessage.text()).toContain("Trying to communicate with your device");
+ expect(this.component.renderAuthenticated).toHaveBeenCalledWith('{"deviceData":"this is data from the device"}');
+ });
+ return describe("errors", function() {
+ it("displays an error message", function() {
+ var errorMessage, setupButton;
+ setupButton = this.container.find("#js-login-u2f-device");
+ setupButton.trigger('click');
this.u2fDevice.respondToAuthenticateRequest({
- deviceData: "this is data from the device"
+ errorCode: "error!"
});
- expect(this.component.renderAuthenticated).toHaveBeenCalledWith('{"deviceData":"this is data from the device"}');
+ errorMessage = this.container.find("p");
+ return expect(errorMessage.text()).toContain("There was a problem communicating with your device");
});
- return describe("errors", function() {
- it("displays an error message", function() {
- var errorMessage, setupButton;
- setupButton = this.container.find("#js-login-u2f-device");
- setupButton.trigger('click');
- this.u2fDevice.respondToAuthenticateRequest({
- errorCode: "error!"
- });
- errorMessage = this.container.find("p");
- return expect(errorMessage.text()).toContain("There was a problem communicating with your device");
+ return it("allows retrying authentication after an error", function() {
+ var retryButton, setupButton;
+ setupButton = this.container.find("#js-login-u2f-device");
+ setupButton.trigger('click');
+ this.u2fDevice.respondToAuthenticateRequest({
+ errorCode: "error!"
});
- return it("allows retrying authentication after an error", function() {
- var retryButton, setupButton;
- setupButton = this.container.find("#js-login-u2f-device");
- setupButton.trigger('click');
- this.u2fDevice.respondToAuthenticateRequest({
- errorCode: "error!"
- });
- retryButton = this.container.find("#js-u2f-try-again");
- retryButton.trigger('click');
- setupButton = this.container.find("#js-login-u2f-device");
- setupButton.trigger('click');
- this.u2fDevice.respondToAuthenticateRequest({
- deviceData: "this is data from the device"
- });
- expect(this.component.renderAuthenticated).toHaveBeenCalledWith('{"deviceData":"this is data from the device"}');
+ retryButton = this.container.find("#js-u2f-try-again");
+ retryButton.trigger('click');
+ setupButton = this.container.find("#js-login-u2f-device");
+ setupButton.trigger('click');
+ this.u2fDevice.respondToAuthenticateRequest({
+ deviceData: "this is data from the device"
});
+ expect(this.component.renderAuthenticated).toHaveBeenCalledWith('{"deviceData":"this is data from the device"}');
});
});
-}).call(window);
+});
diff --git a/spec/javascripts/u2f/register_spec.js b/spec/javascripts/u2f/register_spec.js
index a445c80f2af..ac20e7e49af 100644
--- a/spec/javascripts/u2f/register_spec.js
+++ b/spec/javascripts/u2f/register_spec.js
@@ -8,70 +8,68 @@ import '~/u2f/error';
import 'vendor/u2f';
import './mock_u2f_device';
-(function() {
- describe('U2FRegister', function() {
- preloadFixtures('u2f/register.html.raw');
+describe('U2FRegister', function() {
+ preloadFixtures('u2f/register.html.raw');
- beforeEach(function() {
- loadFixtures('u2f/register.html.raw');
- this.u2fDevice = new MockU2FDevice;
- this.container = $("#js-register-u2f");
- this.component = new U2FRegister(this.container, $("#js-register-u2f-templates"), {}, "token");
- return this.component.start();
+ beforeEach(function() {
+ loadFixtures('u2f/register.html.raw');
+ this.u2fDevice = new MockU2FDevice;
+ this.container = $("#js-register-u2f");
+ this.component = new U2FRegister(this.container, $("#js-register-u2f-templates"), {}, "token");
+ return this.component.start();
+ });
+ it('allows registering a U2F device', function() {
+ var deviceResponse, inProgressMessage, registeredMessage, setupButton;
+ setupButton = this.container.find("#js-setup-u2f-device");
+ expect(setupButton.text()).toBe('Setup new U2F device');
+ setupButton.trigger('click');
+ inProgressMessage = this.container.children("p");
+ expect(inProgressMessage.text()).toContain("Trying to communicate with your device");
+ this.u2fDevice.respondToRegisterRequest({
+ deviceData: "this is data from the device"
});
- it('allows registering a U2F device', function() {
- var deviceResponse, inProgressMessage, registeredMessage, setupButton;
+ registeredMessage = this.container.find('p');
+ deviceResponse = this.container.find('#js-device-response');
+ expect(registeredMessage.text()).toContain("Your device was successfully set up!");
+ return expect(deviceResponse.val()).toBe('{"deviceData":"this is data from the device"}');
+ });
+ return describe("errors", function() {
+ it("doesn't allow the same device to be registered twice (for the same user", function() {
+ var errorMessage, setupButton;
setupButton = this.container.find("#js-setup-u2f-device");
- expect(setupButton.text()).toBe('Setup new U2F device');
setupButton.trigger('click');
- inProgressMessage = this.container.children("p");
- expect(inProgressMessage.text()).toContain("Trying to communicate with your device");
this.u2fDevice.respondToRegisterRequest({
- deviceData: "this is data from the device"
+ errorCode: 4
});
- registeredMessage = this.container.find('p');
- deviceResponse = this.container.find('#js-device-response');
- expect(registeredMessage.text()).toContain("Your device was successfully set up!");
- return expect(deviceResponse.val()).toBe('{"deviceData":"this is data from the device"}');
+ errorMessage = this.container.find("p");
+ return expect(errorMessage.text()).toContain("already been registered with us");
});
- return describe("errors", function() {
- it("doesn't allow the same device to be registered twice (for the same user", function() {
- var errorMessage, setupButton;
- setupButton = this.container.find("#js-setup-u2f-device");
- setupButton.trigger('click');
- this.u2fDevice.respondToRegisterRequest({
- errorCode: 4
- });
- errorMessage = this.container.find("p");
- return expect(errorMessage.text()).toContain("already been registered with us");
+ it("displays an error message for other errors", function() {
+ var errorMessage, setupButton;
+ setupButton = this.container.find("#js-setup-u2f-device");
+ setupButton.trigger('click');
+ this.u2fDevice.respondToRegisterRequest({
+ errorCode: "error!"
});
- it("displays an error message for other errors", function() {
- var errorMessage, setupButton;
- setupButton = this.container.find("#js-setup-u2f-device");
- setupButton.trigger('click');
- this.u2fDevice.respondToRegisterRequest({
- errorCode: "error!"
- });
- errorMessage = this.container.find("p");
- return expect(errorMessage.text()).toContain("There was a problem communicating with your device");
+ errorMessage = this.container.find("p");
+ return expect(errorMessage.text()).toContain("There was a problem communicating with your device");
+ });
+ return it("allows retrying registration after an error", function() {
+ var registeredMessage, retryButton, setupButton;
+ setupButton = this.container.find("#js-setup-u2f-device");
+ setupButton.trigger('click');
+ this.u2fDevice.respondToRegisterRequest({
+ errorCode: "error!"
});
- return it("allows retrying registration after an error", function() {
- var registeredMessage, retryButton, setupButton;
- setupButton = this.container.find("#js-setup-u2f-device");
- setupButton.trigger('click');
- this.u2fDevice.respondToRegisterRequest({
- errorCode: "error!"
- });
- retryButton = this.container.find("#U2FTryAgain");
- retryButton.trigger('click');
- setupButton = this.container.find("#js-setup-u2f-device");
- setupButton.trigger('click');
- this.u2fDevice.respondToRegisterRequest({
- deviceData: "this is data from the device"
- });
- registeredMessage = this.container.find("p");
- return expect(registeredMessage.text()).toContain("Your device was successfully set up!");
+ retryButton = this.container.find("#U2FTryAgain");
+ retryButton.trigger('click');
+ setupButton = this.container.find("#js-setup-u2f-device");
+ setupButton.trigger('click');
+ this.u2fDevice.respondToRegisterRequest({
+ deviceData: "this is data from the device"
});
+ registeredMessage = this.container.find("p");
+ return expect(registeredMessage.text()).toContain("Your device was successfully set up!");
});
});
-}).call(window);
+});
diff --git a/spec/javascripts/zen_mode_spec.js b/spec/javascripts/zen_mode_spec.js
index a225b04c47e..55beb6cc590 100644
--- a/spec/javascripts/zen_mode_spec.js
+++ b/spec/javascripts/zen_mode_spec.js
@@ -4,75 +4,73 @@
import ZenMode from '~/zen_mode';
-(function() {
- var enterZen, escapeKeydown, exitZen;
+var enterZen, escapeKeydown, exitZen;
- describe('ZenMode', function() {
- var fixtureName = 'issues/open-issue.html.raw';
- preloadFixtures(fixtureName);
+describe('ZenMode', function() {
+ var fixtureName = 'issues/open-issue.html.raw';
+ preloadFixtures(fixtureName);
+ beforeEach(function() {
+ loadFixtures(fixtureName);
+ spyOn(Dropzone, 'forElement').and.callFake(function() {
+ return {
+ enable: function() {
+ 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() {
+ it('pauses Mousetrap', function() {
+ spyOn(Mousetrap, 'pause');
+ enterZen();
+ return expect(Mousetrap.pause).toHaveBeenCalled();
+ });
+ return it('removes textarea styling', function() {
+ $('.notes-form textarea').attr('style', 'height: 400px');
+ enterZen();
+ return expect($('.notes-form textarea')).not.toHaveAttr('style');
+ });
+ });
+ describe('in use', function() {
beforeEach(function() {
- loadFixtures(fixtureName);
- spyOn(Dropzone, 'forElement').and.callFake(function() {
- return {
- enable: function() {
- 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;
+ return enterZen();
+ });
+ return it('exits on Escape', function() {
+ escapeKeydown();
+ return expect($('.notes-form .zen-backdrop')).not.toHaveClass('fullscreen');
});
- describe('on enter', function() {
- it('pauses Mousetrap', function() {
- spyOn(Mousetrap, 'pause');
- enterZen();
- return expect(Mousetrap.pause).toHaveBeenCalled();
- });
- return it('removes textarea styling', function() {
- $('.notes-form textarea').attr('style', 'height: 400px');
- enterZen();
- return expect($('.notes-form textarea')).not.toHaveAttr('style');
- });
+ });
+ return describe('on exit', function() {
+ beforeEach(function() {
+ return enterZen();
});
- describe('in use', function() {
- beforeEach(function() {
- return enterZen();
- });
- return it('exits on Escape', function() {
- escapeKeydown();
- return expect($('.notes-form .zen-backdrop')).not.toHaveClass('fullscreen');
- });
+ it('unpauses Mousetrap', function() {
+ spyOn(Mousetrap, 'unpause');
+ exitZen();
+ return expect(Mousetrap.unpause).toHaveBeenCalled();
});
- return describe('on exit', function() {
- beforeEach(function() {
- return enterZen();
- });
- it('unpauses Mousetrap', function() {
- spyOn(Mousetrap, 'unpause');
- exitZen();
- return expect(Mousetrap.unpause).toHaveBeenCalled();
- });
- return it('restores the scroll position', function() {
- spyOn(this.zen, 'scrollTo');
- exitZen();
- return expect(this.zen.scrollTo).toHaveBeenCalled();
- });
+ return it('restores the scroll position', function() {
+ spyOn(this.zen, 'scrollTo');
+ exitZen();
+ return expect(this.zen.scrollTo).toHaveBeenCalled();
});
});
+});
- enterZen = function() {
- return $('.notes-form .js-zen-enter').click();
- };
+enterZen = function() {
+ return $('.notes-form .js-zen-enter').click();
+};
- exitZen = function() {
- return $('.notes-form .js-zen-leave').click();
- };
+exitZen = function() {
+ return $('.notes-form .js-zen-leave').click();
+};
- escapeKeydown = function() {
- return $('.notes-form textarea').trigger($.Event('keydown', {
- keyCode: 27
- }));
- };
-}).call(window);
+escapeKeydown = function() {
+ return $('.notes-form textarea').trigger($.Event('keydown', {
+ keyCode: 27
+ }));
+};