Commit 6e12c008 authored by Marvin Karegyeya's avatar Marvin Karegyeya Committed by Kushal Pandya

Remove-IIFEs-from-gl_dropdown.js

parent 7de8ee9f
/* eslint-disable func-names, no-underscore-dangle, no-var, one-var, vars-on-top, no-shadow, no-cond-assign, no-return-assign, no-else-return, camelcase, no-lonely-if, guard-for-in, no-restricted-syntax, consistent-return, no-param-reassign, no-loop-func */ /* eslint-disable func-names, no-underscore-dangle, no-var, one-var, vars-on-top, no-cond-assign, no-return-assign, no-else-return, camelcase, no-lonely-if, guard-for-in, no-restricted-syntax, consistent-return, no-param-reassign, no-loop-func */
import $ from 'jquery'; import $ from 'jquery';
import _ from 'underscore'; import _ from 'underscore';
...@@ -8,984 +8,905 @@ import { visitUrl } from './lib/utils/url_utility'; ...@@ -8,984 +8,905 @@ import { visitUrl } from './lib/utils/url_utility';
import { isObject } from './lib/utils/type_utility'; import { isObject } from './lib/utils/type_utility';
import renderItem from './gl_dropdown/render'; import renderItem from './gl_dropdown/render';
var GitLabDropdown, GitLabDropdownFilter, GitLabDropdownRemote, GitLabDropdownInput; const BLUR_KEYCODES = [27, 40];
GitLabDropdownInput = (function() {
function GitLabDropdownInput(input, options) {
var $inputContainer, $clearButton;
var _this = this;
this.input = input;
this.options = options;
this.fieldName = this.options.fieldName || 'field-name';
$inputContainer = this.input.parent();
$clearButton = $inputContainer.find('.js-dropdown-input-clear');
$clearButton.on(
'click',
(function(_this) {
// Clear click
return function(e) {
e.preventDefault();
e.stopPropagation();
return _this.input
.val('')
.trigger('input')
.focus();
};
})(this),
);
this.input const HAS_VALUE_CLASS = 'has-value';
.on('keydown', e => {
var keyCode = e.which;
if (keyCode === 13 && !options.elIsInput) {
e.preventDefault();
}
})
.on('input', e => {
var val = e.currentTarget.value || _this.options.inputFieldName;
val = val
.split(' ')
.join('-') // replaces space with dash
.replace(/[^a-zA-Z0-9 -]/g, '')
.toLowerCase() // replace non alphanumeric
.replace(/(-)\1+/g, '-'); // replace repeated dashes
_this.cb(_this.options.fieldName, val, {}, true);
_this.input
.closest('.dropdown')
.find('.dropdown-toggle-text')
.text(val);
});
}
GitLabDropdownInput.prototype.onInput = function(cb) { const LOADING_CLASS = 'is-loading';
this.cb = cb;
};
return GitLabDropdownInput;
})();
GitLabDropdownFilter = (function() {
var BLUR_KEYCODES, HAS_VALUE_CLASS;
BLUR_KEYCODES = [27, 40];
HAS_VALUE_CLASS = 'has-value';
function GitLabDropdownFilter(input, options) {
var $clearButton, $inputContainer, ref, timeout;
this.input = input;
this.options = options;
this.filterInputBlur = (ref = this.options.filterInputBlur) != null ? ref : true;
$inputContainer = this.input.parent();
$clearButton = $inputContainer.find('.js-dropdown-input-clear');
$clearButton.on(
'click',
(function(_this) {
// Clear click
return function(e) {
e.preventDefault();
e.stopPropagation();
return _this.input
.val('')
.trigger('input')
.focus();
};
})(this),
);
// Key events
timeout = '';
this.input
.on('keydown', e => {
var keyCode = e.which;
if (keyCode === 13 && !options.elIsInput) {
e.preventDefault();
}
})
.on('input', () => {
if (this.input.val() !== '' && !$inputContainer.hasClass(HAS_VALUE_CLASS)) {
$inputContainer.addClass(HAS_VALUE_CLASS);
} else if (this.input.val() === '' && $inputContainer.hasClass(HAS_VALUE_CLASS)) {
$inputContainer.removeClass(HAS_VALUE_CLASS);
}
// Only filter asynchronously only if option remote is set
if (this.options.remote) {
clearTimeout(timeout);
return (timeout = setTimeout(() => {
$inputContainer.parent().addClass('is-loading');
return this.options.query(this.input.val(), data => {
$inputContainer.parent().removeClass('is-loading');
return this.options.callback(data);
});
}, 250));
} else {
return this.filter(this.input.val());
}
});
}
GitLabDropdownFilter.prototype.shouldBlur = function(keyCode) { const PAGE_TWO_CLASS = 'is-page-two';
return BLUR_KEYCODES.indexOf(keyCode) !== -1;
};
GitLabDropdownFilter.prototype.filter = function(search_text) { const ACTIVE_CLASS = 'is-active';
var data, elements, group, key, results, tmp;
if (this.options.onFilter) { const INDETERMINATE_CLASS = 'is-indeterminate';
this.options.onFilter(search_text);
} let currentIndex = -1;
data = this.options.data();
if (data != null && !this.options.filterByText) { const NON_SELECTABLE_CLASSES = '.divider, .separator, .dropdown-header, .dropdown-menu-empty-item';
results = data;
if (search_text !== '') { const SELECTABLE_CLASSES = `.dropdown-content li:not(${NON_SELECTABLE_CLASSES}, .option-hidden)`;
// When data is an array of objects therefore [object Array] e.g.
// [ const CURSOR_SELECT_SCROLL_PADDING = 5;
// { prop: 'foo' },
// { prop: 'baz' } const FILTER_INPUT = '.dropdown-input .dropdown-input-field:not(.dropdown-no-filter)';
// ]
if (_.isArray(data)) { const NO_FILTER_INPUT = '.dropdown-input .dropdown-input-field.dropdown-no-filter';
results = fuzzaldrinPlus.filter(data, search_text, {
key: this.options.keys, function GitLabDropdownInput(input, options) {
var $inputContainer, $clearButton;
var _this = this;
this.input = input;
this.options = options;
this.fieldName = this.options.fieldName || 'field-name';
$inputContainer = this.input.parent();
$clearButton = $inputContainer.find('.js-dropdown-input-clear');
$clearButton.on('click', e => {
// Clear click
e.preventDefault();
e.stopPropagation();
return this.input
.val('')
.trigger('input')
.focus();
});
this.input
.on('keydown', e => {
var keyCode = e.which;
if (keyCode === 13 && !options.elIsInput) {
e.preventDefault();
}
})
.on('input', e => {
var val = e.currentTarget.value || _this.options.inputFieldName;
val = val
.split(' ')
.join('-') // replaces space with dash
.replace(/[^a-zA-Z0-9 -]/g, '')
.toLowerCase() // replace non alphanumeric
.replace(/(-)\1+/g, '-'); // replace repeated dashes
_this.cb(_this.options.fieldName, val, {}, true);
_this.input
.closest('.dropdown')
.find('.dropdown-toggle-text')
.text(val);
});
}
GitLabDropdownInput.prototype.onInput = function(cb) {
this.cb = cb;
};
function GitLabDropdownFilter(input, options) {
var $clearButton, $inputContainer, ref, timeout;
this.input = input;
this.options = options;
this.filterInputBlur = (ref = this.options.filterInputBlur) != null ? ref : true;
$inputContainer = this.input.parent();
$clearButton = $inputContainer.find('.js-dropdown-input-clear');
$clearButton.on('click', e => {
// Clear click
e.preventDefault();
e.stopPropagation();
return this.input
.val('')
.trigger('input')
.focus();
});
// Key events
timeout = '';
this.input
.on('keydown', e => {
var keyCode = e.which;
if (keyCode === 13 && !options.elIsInput) {
e.preventDefault();
}
})
.on('input', () => {
if (this.input.val() !== '' && !$inputContainer.hasClass(HAS_VALUE_CLASS)) {
$inputContainer.addClass(HAS_VALUE_CLASS);
} else if (this.input.val() === '' && $inputContainer.hasClass(HAS_VALUE_CLASS)) {
$inputContainer.removeClass(HAS_VALUE_CLASS);
}
// Only filter asynchronously only if option remote is set
if (this.options.remote) {
clearTimeout(timeout);
return (timeout = setTimeout(() => {
$inputContainer.parent().addClass('is-loading');
return this.options.query(this.input.val(), data => {
$inputContainer.parent().removeClass('is-loading');
return this.options.callback(data);
}); });
} else { }, 250));
// If data is grouped therefore an [object Object]. e.g. } else {
// { return this.filter(this.input.val());
// groupName1: [ }
// { prop: 'foo' }, });
// { prop: 'baz' } }
// ],
// groupName2: [ GitLabDropdownFilter.prototype.shouldBlur = function(keyCode) {
// { prop: 'abc' }, return BLUR_KEYCODES.indexOf(keyCode) !== -1;
// { prop: 'def' } };
// ]
// } GitLabDropdownFilter.prototype.filter = function(search_text) {
if (isObject(data)) { var data, elements, group, key, results, tmp;
results = {}; if (this.options.onFilter) {
for (key in data) { this.options.onFilter(search_text);
group = data[key]; }
tmp = fuzzaldrinPlus.filter(group, search_text, { data = this.options.data();
key: this.options.keys, if (data != null && !this.options.filterByText) {
}); results = data;
if (tmp.length) { if (search_text !== '') {
results[key] = tmp.map(item => item); // When data is an array of objects therefore [object Array] e.g.
} // [
// { prop: 'foo' },
// { prop: 'baz' }
// ]
if (_.isArray(data)) {
results = fuzzaldrinPlus.filter(data, search_text, {
key: this.options.keys,
});
} else {
// If data is grouped therefore an [object Object]. e.g.
// {
// groupName1: [
// { prop: 'foo' },
// { prop: 'baz' }
// ],
// groupName2: [
// { prop: 'abc' },
// { prop: 'def' }
// ]
// }
if (isObject(data)) {
results = {};
for (key in data) {
group = data[key];
tmp = fuzzaldrinPlus.filter(group, search_text, {
key: this.options.keys,
});
if (tmp.length) {
results[key] = tmp.map(item => item);
} }
} }
} }
} }
return this.options.callback(results); }
} else { return this.options.callback(results);
elements = this.options.elements(); } else {
if (search_text) { elements = this.options.elements();
elements.each(function() { if (search_text) {
var $el, matches; elements.each(function() {
$el = $(this); var $el, matches;
matches = fuzzaldrinPlus.match($el.text().trim(), search_text); $el = $(this);
if (!$el.is('.dropdown-header')) { matches = fuzzaldrinPlus.match($el.text().trim(), search_text);
if (matches.length) { if (!$el.is('.dropdown-header')) {
return $el.show().removeClass('option-hidden'); if (matches.length) {
} else { return $el.show().removeClass('option-hidden');
return $el.hide().addClass('option-hidden'); } else {
} return $el.hide().addClass('option-hidden');
} }
}); }
} else { });
elements.show().removeClass('option-hidden'); } else {
} elements.show().removeClass('option-hidden');
elements
.parent()
.find('.dropdown-menu-empty-item')
.toggleClass('hidden', elements.is(':visible'));
} }
};
return GitLabDropdownFilter;
})();
GitLabDropdownRemote = (function() { elements
function GitLabDropdownRemote(dataEndpoint, options) { .parent()
this.dataEndpoint = dataEndpoint; .find('.dropdown-menu-empty-item')
this.options = options; .toggleClass('hidden', elements.is(':visible'));
} }
};
GitLabDropdownRemote.prototype.execute = function() { function GitLabDropdownRemote(dataEndpoint, options) {
if (typeof this.dataEndpoint === 'string') { this.dataEndpoint = dataEndpoint;
return this.fetchData(); this.options = options;
} else if (typeof this.dataEndpoint === 'function') { }
if (this.options.beforeSend) {
this.options.beforeSend();
}
return this.dataEndpoint(
'',
(function(_this) {
// Fetch the data by calling the data funcfion
return function(data) {
if (_this.options.success) {
_this.options.success(data);
}
if (_this.options.beforeSend) {
return _this.options.beforeSend();
}
};
})(this),
);
}
};
GitLabDropdownRemote.prototype.fetchData = function() { GitLabDropdownRemote.prototype.execute = function() {
if (typeof this.dataEndpoint === 'string') {
return this.fetchData();
} else if (typeof this.dataEndpoint === 'function') {
if (this.options.beforeSend) { if (this.options.beforeSend) {
this.options.beforeSend(); this.options.beforeSend();
} }
return this.dataEndpoint('', data => {
// Fetch the data through ajax if the data is a string // Fetch the data by calling the data function
return axios.get(this.dataEndpoint).then(({ data }) => {
if (this.options.success) { if (this.options.success) {
return this.options.success(data); this.options.success(data);
}
if (this.options.beforeSend) {
return this.options.beforeSend();
} }
}); });
}; }
};
return GitLabDropdownRemote;
})();
GitLabDropdown = (function() {
var ACTIVE_CLASS,
FILTER_INPUT,
NO_FILTER_INPUT,
INDETERMINATE_CLASS,
LOADING_CLASS,
PAGE_TWO_CLASS,
NON_SELECTABLE_CLASSES,
SELECTABLE_CLASSES,
CURSOR_SELECT_SCROLL_PADDING,
currentIndex;
LOADING_CLASS = 'is-loading';
PAGE_TWO_CLASS = 'is-page-two';
ACTIVE_CLASS = 'is-active';
INDETERMINATE_CLASS = 'is-indeterminate';
currentIndex = -1; GitLabDropdownRemote.prototype.fetchData = function() {
if (this.options.beforeSend) {
this.options.beforeSend();
}
NON_SELECTABLE_CLASSES = '.divider, .separator, .dropdown-header, .dropdown-menu-empty-item'; // Fetch the data through ajax if the data is a string
return axios.get(this.dataEndpoint).then(({ data }) => {
SELECTABLE_CLASSES = `.dropdown-content li:not(${NON_SELECTABLE_CLASSES}, .option-hidden)`; if (this.options.success) {
return this.options.success(data);
CURSOR_SELECT_SCROLL_PADDING = 5;
FILTER_INPUT = '.dropdown-input .dropdown-input-field:not(.dropdown-no-filter)';
NO_FILTER_INPUT = '.dropdown-input .dropdown-input-field.dropdown-no-filter';
function GitLabDropdown(el1, options) {
var searchFields, selector, self;
this.el = el1;
this.options = options;
this.updateLabel = this.updateLabel.bind(this);
this.hidden = this.hidden.bind(this);
this.opened = this.opened.bind(this);
this.shouldPropagate = this.shouldPropagate.bind(this);
self = this;
selector = $(this.el).data('target');
this.dropdown = selector != null ? $(selector) : $(this.el).parent();
// Set Defaults
this.filterInput = this.options.filterInput || this.getElement(FILTER_INPUT);
this.noFilterInput = this.options.noFilterInput || this.getElement(NO_FILTER_INPUT);
this.highlight = Boolean(this.options.highlight);
this.icon = Boolean(this.options.icon);
this.filterInputBlur =
this.options.filterInputBlur != null ? this.options.filterInputBlur : true;
// If no input is passed create a default one
self = this;
// If selector was passed
if (_.isString(this.filterInput)) {
this.filterInput = this.getElement(this.filterInput);
} }
searchFields = this.options.search ? this.options.search.fields : []; });
if (this.options.data) { };
// If we provided data
// data could be an array of objects or a group of arrays function GitLabDropdown(el1, options) {
if (_.isObject(this.options.data) && !_.isFunction(this.options.data)) { var searchFields, selector, self;
this.fullData = this.options.data; this.el = el1;
currentIndex = -1; this.options = options;
this.parseData(this.options.data); this.updateLabel = this.updateLabel.bind(this);
this.focusTextInput(); this.hidden = this.hidden.bind(this);
} else { this.opened = this.opened.bind(this);
this.remote = new GitLabDropdownRemote(this.options.data, { this.shouldPropagate = this.shouldPropagate.bind(this);
dataType: this.options.dataType, self = this;
beforeSend: this.toggleLoading.bind(this), selector = $(this.el).data('target');
success: (function(_this) { this.dropdown = selector != null ? $(selector) : $(this.el).parent();
return function(data) { // Set Defaults
_this.fullData = data; this.filterInput = this.options.filterInput || this.getElement(FILTER_INPUT);
_this.parseData(_this.fullData); this.noFilterInput = this.options.noFilterInput || this.getElement(NO_FILTER_INPUT);
_this.focusTextInput(); this.highlight = Boolean(this.options.highlight);
this.icon = Boolean(this.options.icon);
// Update dropdown position since remote data may have changed dropdown size this.filterInputBlur = this.options.filterInputBlur != null ? this.options.filterInputBlur : true;
_this.dropdown.find('.dropdown-menu-toggle').dropdown('update'); // If no input is passed create a default one
self = this;
if ( // If selector was passed
_this.options.filterable && if (_.isString(this.filterInput)) {
_this.filter && this.filterInput = this.getElement(this.filterInput);
_this.filter.input && }
_this.filter.input.val() && searchFields = this.options.search ? this.options.search.fields : [];
_this.filter.input.val().trim() !== '' if (this.options.data) {
) { // If we provided data
return _this.filter.input.trigger('input'); // data could be an array of objects or a group of arrays
} if (_.isObject(this.options.data) && !_.isFunction(this.options.data)) {
}; this.fullData = this.options.data;
// Remote data currentIndex = -1;
})(this), this.parseData(this.options.data);
instance: this, this.focusTextInput();
}); } else {
} this.remote = new GitLabDropdownRemote(this.options.data, {
} dataType: this.options.dataType,
if (this.noFilterInput.length) { beforeSend: this.toggleLoading.bind(this),
this.plainInput = new GitLabDropdownInput(this.noFilterInput, this.options); success: data => {
this.plainInput.onInput(this.addInput.bind(this)); this.fullData = data;
} this.parseData(this.fullData);
// Init filterable this.focusTextInput();
if (this.options.filterable) {
this.filter = new GitLabDropdownFilter(this.filterInput, { // Update dropdown position since remote data may have changed dropdown size
elIsInput: $(this.el).is('input'), this.dropdown.find('.dropdown-menu-toggle').dropdown('update');
filterInputBlur: this.filterInputBlur,
filterByText: this.options.filterByText, if (
onFilter: this.options.onFilter, this.options.filterable &&
remote: this.options.filterRemote, this.filter &&
query: this.options.data, this.filter.input &&
keys: searchFields, this.filter.input.val() &&
this.filter.input.val().trim() !== ''
) {
return this.filter.input.trigger('input');
}
},
instance: this, instance: this,
elements: (function(_this) {
return function() {
selector = `.dropdown-content li:not(${NON_SELECTABLE_CLASSES})`;
if (_this.dropdown.find('.dropdown-toggle-page').length) {
selector = `.dropdown-page-one ${selector}`;
}
return $(selector, this.instance.dropdown);
};
})(this),
data: (function(_this) {
return function() {
return _this.fullData;
};
})(this),
callback: (function(_this) {
return function(data) {
_this.parseData(data);
if (_this.filterInput.val() !== '') {
selector = SELECTABLE_CLASSES;
if (_this.dropdown.find('.dropdown-toggle-page').length) {
selector = `.dropdown-page-one ${selector}`;
}
if ($(_this.el).is('input')) {
currentIndex = -1;
} else {
$(selector, _this.dropdown)
.first()
.find('a')
.addClass('is-focused');
currentIndex = 0;
}
}
};
})(this),
}); });
} }
// Event listeners }
this.dropdown.on('shown.bs.dropdown', this.opened); if (this.noFilterInput.length) {
this.dropdown.on('hidden.bs.dropdown', this.hidden); this.plainInput = new GitLabDropdownInput(this.noFilterInput, this.options);
$(this.el).on('update.label', this.updateLabel); this.plainInput.onInput(this.addInput.bind(this));
this.dropdown.on('click', '.dropdown-menu, .dropdown-menu-close', this.shouldPropagate); }
this.dropdown.on( // Init filterable
'keyup', if (this.options.filterable) {
(function(_this) { this.filter = new GitLabDropdownFilter(this.filterInput, {
return function(e) { elIsInput: $(this.el).is('input'),
// Escape key filterInputBlur: this.filterInputBlur,
if (e.which === 27) { filterByText: this.options.filterByText,
return $('.dropdown-menu-close', _this.dropdown).trigger('click'); onFilter: this.options.onFilter,
remote: this.options.filterRemote,
query: this.options.data,
keys: searchFields,
instance: this,
elements: () => {
selector = `.dropdown-content li:not(${NON_SELECTABLE_CLASSES})`;
if (this.dropdown.find('.dropdown-toggle-page').length) {
selector = `.dropdown-page-one ${selector}`;
}
return $(selector, this.dropdown);
},
data: () => this.fullData,
callback: data => {
this.parseData(data);
if (this.filterInput.val() !== '') {
selector = SELECTABLE_CLASSES;
if (this.dropdown.find('.dropdown-toggle-page').length) {
selector = `.dropdown-page-one ${selector}`;
} }
}; if ($(this.el).is('input')) {
})(this), currentIndex = -1;
); } else {
this.dropdown.on( $(selector, this.dropdown)
'blur', .first()
'a', .find('a')
(function(_this) { .addClass('is-focused');
return function(e) { currentIndex = 0;
var $dropdownMenu, $relatedTarget;
if (e.relatedTarget != null) {
$relatedTarget = $(e.relatedTarget);
$dropdownMenu = $relatedTarget.closest('.dropdown-menu');
if ($dropdownMenu.length === 0) {
return _this.dropdown.removeClass('show');
}
} }
}; }
})(this), },
); });
if (this.dropdown.find('.dropdown-toggle-page').length) { }
this.dropdown.find('.dropdown-toggle-page, .dropdown-menu-back').on( // Event listeners
'click', this.dropdown.on('shown.bs.dropdown', this.opened);
(function(_this) { this.dropdown.on('hidden.bs.dropdown', this.hidden);
return function(e) { $(this.el).on('update.label', this.updateLabel);
e.preventDefault(); this.dropdown.on('click', '.dropdown-menu, .dropdown-menu-close', this.shouldPropagate);
e.stopPropagation(); this.dropdown.on('keyup', e => {
return _this.togglePage(); // Escape key
}; if (e.which === 27) {
})(this), return $('.dropdown-menu-close', this.dropdown).trigger('click');
);
} }
if (this.options.selectable) { });
selector = '.dropdown-content a'; this.dropdown.on('blur', 'a', e => {
if (this.dropdown.find('.dropdown-toggle-page').length) { var $dropdownMenu, $relatedTarget;
selector = '.dropdown-page-one .dropdown-content a'; if (e.relatedTarget != null) {
$relatedTarget = $(e.relatedTarget);
$dropdownMenu = $relatedTarget.closest('.dropdown-menu');
if ($dropdownMenu.length === 0) {
return this.dropdown.removeClass('show');
}
}
});
if (this.dropdown.find('.dropdown-toggle-page').length) {
this.dropdown.find('.dropdown-toggle-page, .dropdown-menu-back').on('click', e => {
e.preventDefault();
e.stopPropagation();
return this.togglePage();
});
}
if (this.options.selectable) {
selector = '.dropdown-content a';
if (this.dropdown.find('.dropdown-toggle-page').length) {
selector = '.dropdown-page-one .dropdown-content a';
}
this.dropdown.on('click', selector, e => {
var $el, selected, selectedObj, isMarking;
$el = $(e.currentTarget);
selected = self.rowClicked($el);
selectedObj = selected ? selected[0] : null;
isMarking = selected ? selected[1] : null;
if (this.options.clicked) {
this.options.clicked.call(this, {
selectedObj,
$el,
e,
isMarking,
});
} }
this.dropdown.on('click', selector, e => {
var $el, selected, selectedObj, isMarking;
$el = $(e.currentTarget);
selected = self.rowClicked($el);
selectedObj = selected ? selected[0] : null;
isMarking = selected ? selected[1] : null;
if (this.options.clicked) {
this.options.clicked.call(this, {
selectedObj,
$el,
e,
isMarking,
});
}
// Update label right after all modifications in dropdown has been done // Update label right after all modifications in dropdown has been done
if (this.options.toggleLabel) { if (this.options.toggleLabel) {
this.updateLabel(selectedObj, $el, this); this.updateLabel(selectedObj, $el, this);
} }
$el.trigger('blur'); $el.trigger('blur');
}); });
}
} }
}
// Finds an element inside wrapper element // Finds an element inside wrapper element
GitLabDropdown.prototype.getElement = function(selector) { GitLabDropdown.prototype.getElement = function(selector) {
return this.dropdown.find(selector); return this.dropdown.find(selector);
}; };
GitLabDropdown.prototype.toggleLoading = function() { GitLabDropdown.prototype.toggleLoading = function() {
return $('.dropdown-menu', this.dropdown).toggleClass(LOADING_CLASS); return $('.dropdown-menu', this.dropdown).toggleClass(LOADING_CLASS);
}; };
GitLabDropdown.prototype.togglePage = function() { GitLabDropdown.prototype.togglePage = function() {
var menu; var menu;
menu = $('.dropdown-menu', this.dropdown); menu = $('.dropdown-menu', this.dropdown);
if (menu.hasClass(PAGE_TWO_CLASS)) { if (menu.hasClass(PAGE_TWO_CLASS)) {
if (this.remote) { if (this.remote) {
this.remote.execute(); this.remote.execute();
}
} }
menu.toggleClass(PAGE_TWO_CLASS); }
// Focus first visible input on active page menu.toggleClass(PAGE_TWO_CLASS);
return this.dropdown.find('[class^="dropdown-page-"]:visible :text:visible:first').focus(); // Focus first visible input on active page
}; return this.dropdown.find('[class^="dropdown-page-"]:visible :text:visible:first').focus();
};
GitLabDropdown.prototype.parseData = function(data) {
var full_html, groupData, html, name; GitLabDropdown.prototype.parseData = function(data) {
this.renderedData = data; var full_html, groupData, html, name;
if (this.options.filterable && data.length === 0) { this.renderedData = data;
// render no matching results if (this.options.filterable && data.length === 0) {
html = [this.noResults()]; // render no matching results
} else { html = [this.noResults()];
// Handle array groups } else {
if (isObject(data)) { // Handle array groups
html = []; if (isObject(data)) {
for (name in data) { html = [];
groupData = data[name]; for (name in data) {
html.push( groupData = data[name];
this.renderItem( html.push(
{ this.renderItem(
content: name, {
type: 'header', content: name,
}, type: 'header',
name, },
), name,
); ),
this.renderData(groupData, name).map(item => html.push(item)); );
} this.renderData(groupData, name).map(item => html.push(item));
} else {
// Render each row
html = this.renderData(data);
} }
} else {
// Render each row
html = this.renderData(data);
} }
// Render the full menu }
full_html = this.renderMenu(html); // Render the full menu
return this.appendMenu(full_html); full_html = this.renderMenu(html);
}; return this.appendMenu(full_html);
};
GitLabDropdown.prototype.renderData = function(data, group) {
return data.map((obj, index) => this.renderItem(obj, group || false, index));
};
GitLabDropdown.prototype.shouldPropagate = function(e) {
var $target;
if (this.options.multiSelect || this.options.shouldPropagate === false) {
$target = $(e.target);
if (
$target &&
!$target.hasClass('dropdown-menu-close') &&
!$target.hasClass('dropdown-menu-close-icon') &&
!$target.data('isLink')
) {
e.stopPropagation();
// This prevents automatic scrolling to the top
if ($target.closest('a').length) {
return false;
}
}
return true; GitLabDropdown.prototype.renderData = function(data, group) {
return data.map((obj, index) => this.renderItem(obj, group || false, index));
};
GitLabDropdown.prototype.shouldPropagate = function(e) {
var $target;
if (this.options.multiSelect || this.options.shouldPropagate === false) {
$target = $(e.target);
if (
$target &&
!$target.hasClass('dropdown-menu-close') &&
!$target.hasClass('dropdown-menu-close-icon') &&
!$target.data('isLink')
) {
e.stopPropagation();
// This prevents automatic scrolling to the top
if ($target.closest('a').length) {
return false;
}
} }
};
GitLabDropdown.prototype.filteredFullData = function() {
return this.fullData.filter(
r =>
typeof r === 'object' &&
!Object.prototype.hasOwnProperty.call(r, 'beforeDivider') &&
!Object.prototype.hasOwnProperty.call(r, 'header'),
);
};
GitLabDropdown.prototype.opened = function(e) { return true;
var contentHtml; }
this.resetRows(); };
this.addArrowKeyEvent();
const dropdownToggle = this.dropdown.find('.dropdown-menu-toggle'); GitLabDropdown.prototype.filteredFullData = function() {
const hasFilterBulkUpdate = dropdownToggle.hasClass('js-filter-bulk-update'); return this.fullData.filter(
const shouldRefreshOnOpen = dropdownToggle.hasClass('js-gl-dropdown-refresh-on-open'); r =>
const hasMultiSelect = dropdownToggle.hasClass('js-multiselect'); typeof r === 'object' &&
!Object.prototype.hasOwnProperty.call(r, 'beforeDivider') &&
!Object.prototype.hasOwnProperty.call(r, 'header'),
);
};
// Makes indeterminate items effective GitLabDropdown.prototype.opened = function(e) {
if (this.fullData && (shouldRefreshOnOpen || hasFilterBulkUpdate)) { var contentHtml;
this.parseData(this.fullData); this.resetRows();
} this.addArrowKeyEvent();
// Process the data to make sure rendered data const dropdownToggle = this.dropdown.find('.dropdown-menu-toggle');
// matches the correct layout const hasFilterBulkUpdate = dropdownToggle.hasClass('js-filter-bulk-update');
const inputValue = this.filterInput.val(); const shouldRefreshOnOpen = dropdownToggle.hasClass('js-gl-dropdown-refresh-on-open');
if (this.fullData && hasMultiSelect && this.options.processData && inputValue.length === 0) { const hasMultiSelect = dropdownToggle.hasClass('js-multiselect');
this.options.processData.call(
this.options,
inputValue,
this.filteredFullData(),
this.parseData.bind(this),
);
}
contentHtml = $('.dropdown-content', this.dropdown).html(); // Makes indeterminate items effective
if (this.remote && contentHtml === '') { if (this.fullData && (shouldRefreshOnOpen || hasFilterBulkUpdate)) {
this.remote.execute(); this.parseData(this.fullData);
}
// Process the data to make sure rendered data
// matches the correct layout
const inputValue = this.filterInput.val();
if (this.fullData && hasMultiSelect && this.options.processData && inputValue.length === 0) {
this.options.processData.call(
this.options,
inputValue,
this.filteredFullData(),
this.parseData.bind(this),
);
}
contentHtml = $('.dropdown-content', this.dropdown).html();
if (this.remote && contentHtml === '') {
this.remote.execute();
} else {
this.focusTextInput();
}
if (this.options.showMenuAbove) {
this.positionMenuAbove();
}
if (this.options.opened) {
if (this.options.preserveContext) {
this.options.opened(e);
} else { } else {
this.focusTextInput(); this.options.opened.call(this, e);
} }
}
if (this.options.showMenuAbove) { return this.dropdown.trigger('shown.gl.dropdown');
this.positionMenuAbove(); };
}
if (this.options.opened) { GitLabDropdown.prototype.positionMenuAbove = function() {
if (this.options.preserveContext) { var $menu = this.dropdown.find('.dropdown-menu');
this.options.opened(e);
} else {
this.options.opened.call(this, e);
}
}
return this.dropdown.trigger('shown.gl.dropdown'); $menu.addClass('dropdown-open-top');
}; $menu.css('top', 'initial');
$menu.css('bottom', '100%');
};
GitLabDropdown.prototype.positionMenuAbove = function() { GitLabDropdown.prototype.hidden = function(e) {
var $menu = this.dropdown.find('.dropdown-menu'); var $input;
this.resetRows();
this.removeArrowKeyEvent();
$input = this.dropdown.find('.dropdown-input-field');
if (this.options.filterable) {
$input.blur();
}
if (this.dropdown.find('.dropdown-toggle-page').length) {
$('.dropdown-menu', this.dropdown).removeClass(PAGE_TWO_CLASS);
}
if (this.options.hidden) {
this.options.hidden.call(this, e);
}
return this.dropdown.trigger('hidden.gl.dropdown');
};
$menu.addClass('dropdown-open-top'); // Render the full menu
$menu.css('top', 'initial'); GitLabDropdown.prototype.renderMenu = function(html) {
$menu.css('bottom', '100%'); if (this.options.renderMenu) {
}; return this.options.renderMenu(html);
} else {
return $('<ul>').append(html);
}
};
GitLabDropdown.prototype.hidden = function(e) { // Append the menu into the dropdown
var $input; GitLabDropdown.prototype.appendMenu = function(html) {
this.resetRows(); return this.clearMenu().append(html);
this.removeArrowKeyEvent(); };
$input = this.dropdown.find('.dropdown-input-field');
if (this.options.filterable) {
$input.blur();
}
if (this.dropdown.find('.dropdown-toggle-page').length) {
$('.dropdown-menu', this.dropdown).removeClass(PAGE_TWO_CLASS);
}
if (this.options.hidden) {
this.options.hidden.call(this, e);
}
return this.dropdown.trigger('hidden.gl.dropdown');
};
// Render the full menu GitLabDropdown.prototype.clearMenu = function() {
GitLabDropdown.prototype.renderMenu = function(html) { var selector;
if (this.options.renderMenu) { selector = '.dropdown-content';
return this.options.renderMenu(html); if (this.dropdown.find('.dropdown-toggle-page').length) {
if (this.options.containerSelector) {
selector = this.options.containerSelector;
} else { } else {
return $('<ul>').append(html); selector = '.dropdown-page-one .dropdown-content';
} }
}; }
// Append the menu into the dropdown return $(selector, this.dropdown).empty();
GitLabDropdown.prototype.appendMenu = function(html) { };
return this.clearMenu().append(html);
};
GitLabDropdown.prototype.clearMenu = function() { GitLabDropdown.prototype.renderItem = function(data, group, index) {
var selector; let parent;
selector = '.dropdown-content';
if (this.dropdown.find('.dropdown-toggle-page').length) {
if (this.options.containerSelector) {
selector = this.options.containerSelector;
} else {
selector = '.dropdown-page-one .dropdown-content';
}
}
return $(selector, this.dropdown).empty(); if (this.dropdown && this.dropdown[0]) {
}; parent = this.dropdown[0].parentNode;
}
GitLabDropdown.prototype.renderItem = function(data, group, index) { return renderItem({
let parent; instance: this,
options: Object.assign({}, this.options, {
icon: this.icon,
highlight: this.highlight,
highlightText: text => this.highlightTextMatches(text, this.filterInput.val()),
highlightTemplate: this.highlightTemplate.bind(this),
parent,
}),
data,
group,
index,
});
};
if (this.dropdown && this.dropdown[0]) { GitLabDropdown.prototype.highlightTemplate = function(text, template) {
parent = this.dropdown[0].parentNode; return `"<b>${_.escape(text)}</b>" ${template}`;
} };
return renderItem({ GitLabDropdown.prototype.highlightTextMatches = function(text, term) {
instance: this, const occurrences = fuzzaldrinPlus.match(text, term);
options: Object.assign({}, this.options, { const { indexOf } = [];
icon: this.icon,
highlight: this.highlight,
highlightText: text => this.highlightTextMatches(text, this.filterInput.val()),
highlightTemplate: this.highlightTemplate.bind(this),
parent,
}),
data,
group,
index,
});
};
GitLabDropdown.prototype.highlightTemplate = function(text, template) {
return `"<b>${_.escape(text)}</b>" ${template}`;
};
GitLabDropdown.prototype.highlightTextMatches = function(text, term) {
const occurrences = fuzzaldrinPlus.match(text, term);
const { indexOf } = [];
return text
.split('')
.map((character, i) => {
if (indexOf.call(occurrences, i) !== -1) {
return `<b>${character}</b>`;
} else {
return character;
}
})
.join('');
};
GitLabDropdown.prototype.noResults = function() {
return '<li class="dropdown-menu-empty-item"><a>No matching results</a></li>';
};
GitLabDropdown.prototype.rowClicked = function(el) {
var field, groupName, isInput, selectedIndex, selectedObject, value, isMarking;
const { fieldName } = this.options;
isInput = $(this.el).is('input');
if (this.renderedData) {
groupName = el.data('group');
if (groupName) {
selectedIndex = el.data('index');
selectedObject = this.renderedData[groupName][selectedIndex];
} else {
selectedIndex = el.closest('li').index();
this.selectedIndex = selectedIndex;
selectedObject = this.renderedData[selectedIndex];
}
}
if (this.options.vue) { return text
if (el.hasClass(ACTIVE_CLASS)) { .split('')
el.removeClass(ACTIVE_CLASS); .map((character, i) => {
if (indexOf.call(occurrences, i) !== -1) {
return `<b>${character}</b>`;
} else { } else {
el.addClass(ACTIVE_CLASS); return character;
} }
})
.join('');
};
return [selectedObject]; GitLabDropdown.prototype.noResults = function() {
} return '<li class="dropdown-menu-empty-item"><a>No matching results</a></li>';
};
field = []; GitLabDropdown.prototype.rowClicked = function(el) {
value = this.options.id ? this.options.id(selectedObject, el) : selectedObject.id; var field, groupName, isInput, selectedIndex, selectedObject, value, isMarking;
if (isInput) {
field = $(this.el);
} else if (value != null) {
field = this.dropdown
.parent()
.find(`input[name='${fieldName}'][value='${value.toString().replace(/'/g, "\\'")}']`);
}
if (this.options.isSelectable && !this.options.isSelectable(selectedObject, el)) { const { fieldName } = this.options;
return [selectedObject]; isInput = $(this.el).is('input');
if (this.renderedData) {
groupName = el.data('group');
if (groupName) {
selectedIndex = el.data('index');
selectedObject = this.renderedData[groupName][selectedIndex];
} else {
selectedIndex = el.closest('li').index();
this.selectedIndex = selectedIndex;
selectedObject = this.renderedData[selectedIndex];
} }
}
if (el.hasClass(ACTIVE_CLASS) && value !== 0) { if (this.options.vue) {
isMarking = false; if (el.hasClass(ACTIVE_CLASS)) {
el.removeClass(ACTIVE_CLASS); el.removeClass(ACTIVE_CLASS);
if (field && field.length) {
this.clearField(field, isInput);
}
} else if (el.hasClass(INDETERMINATE_CLASS)) {
isMarking = true;
el.addClass(ACTIVE_CLASS);
el.removeClass(INDETERMINATE_CLASS);
if (field && field.length && value == null) {
this.clearField(field, isInput);
}
if ((!field || !field.length) && fieldName) {
this.addInput(fieldName, value, selectedObject);
}
} else { } else {
isMarking = true;
if (!this.options.multiSelect || el.hasClass('dropdown-clear-active')) {
this.dropdown.find(`.${ACTIVE_CLASS}`).removeClass(ACTIVE_CLASS);
if (!isInput) {
this.dropdown
.parent()
.find(`input[name='${fieldName}']`)
.remove();
}
}
if (field && field.length && value == null) {
this.clearField(field, isInput);
}
// Toggle active class for the tick mark
el.addClass(ACTIVE_CLASS); el.addClass(ACTIVE_CLASS);
if (value != null) {
if ((!field || !field.length) && fieldName) {
this.addInput(fieldName, value, selectedObject);
} else if (field && field.length) {
field.val(value).trigger('change');
}
}
} }
return [selectedObject, isMarking]; return [selectedObject];
}; }
field = [];
value = this.options.id ? this.options.id(selectedObject, el) : selectedObject.id;
if (isInput) {
field = $(this.el);
} else if (value != null) {
field = this.dropdown
.parent()
.find(`input[name='${fieldName}'][value='${value.toString().replace(/'/g, "\\'")}']`);
}
GitLabDropdown.prototype.focusTextInput = function() { if (this.options.isSelectable && !this.options.isSelectable(selectedObject, el)) {
if (this.options.filterable) { return [selectedObject];
const initialScrollTop = $(window).scrollTop(); }
if (this.dropdown.is('.show') && !this.filterInput.is(':focus')) { if (el.hasClass(ACTIVE_CLASS) && value !== 0) {
this.filterInput.focus(); isMarking = false;
el.removeClass(ACTIVE_CLASS);
if (field && field.length) {
this.clearField(field, isInput);
}
} else if (el.hasClass(INDETERMINATE_CLASS)) {
isMarking = true;
el.addClass(ACTIVE_CLASS);
el.removeClass(INDETERMINATE_CLASS);
if (field && field.length && value == null) {
this.clearField(field, isInput);
}
if ((!field || !field.length) && fieldName) {
this.addInput(fieldName, value, selectedObject);
}
} else {
isMarking = true;
if (!this.options.multiSelect || el.hasClass('dropdown-clear-active')) {
this.dropdown.find(`.${ACTIVE_CLASS}`).removeClass(ACTIVE_CLASS);
if (!isInput) {
this.dropdown
.parent()
.find(`input[name='${fieldName}']`)
.remove();
} }
}
if ($(window).scrollTop() < initialScrollTop) { if (field && field.length && value == null) {
$(window).scrollTop(initialScrollTop); this.clearField(field, isInput);
}
// Toggle active class for the tick mark
el.addClass(ACTIVE_CLASS);
if (value != null) {
if ((!field || !field.length) && fieldName) {
this.addInput(fieldName, value, selectedObject);
} else if (field && field.length) {
field.val(value).trigger('change');
} }
} }
}; }
GitLabDropdown.prototype.addInput = function(fieldName, value, selectedObject, single) { return [selectedObject, isMarking];
var $input; };
// Create hidden input for form
if (single) {
$(`input[name="${fieldName}"]`).remove();
}
$input = $('<input>') GitLabDropdown.prototype.focusTextInput = function() {
.attr('type', 'hidden') if (this.options.filterable) {
.attr('name', fieldName) const initialScrollTop = $(window).scrollTop();
.val(value);
if (this.options.inputId != null) {
$input.attr('id', this.options.inputId);
}
if (this.options.multiSelect) { if (this.dropdown.is('.show') && !this.filterInput.is(':focus')) {
Object.keys(selectedObject).forEach(attribute => { this.filterInput.focus();
$input.attr(`data-${attribute}`, selectedObject[attribute]);
});
} }
if (this.options.inputMeta) { if ($(window).scrollTop() < initialScrollTop) {
$input.attr('data-meta', selectedObject[this.options.inputMeta]); $(window).scrollTop(initialScrollTop);
} }
}
};
GitLabDropdown.prototype.addInput = function(fieldName, value, selectedObject, single) {
var $input;
// Create hidden input for form
if (single) {
$(`input[name="${fieldName}"]`).remove();
}
$input = $('<input>')
.attr('type', 'hidden')
.attr('name', fieldName)
.val(value);
if (this.options.inputId != null) {
$input.attr('id', this.options.inputId);
}
this.dropdown.before($input).trigger('change'); if (this.options.multiSelect) {
}; Object.keys(selectedObject).forEach(attribute => {
$input.attr(`data-${attribute}`, selectedObject[attribute]);
});
}
if (this.options.inputMeta) {
$input.attr('data-meta', selectedObject[this.options.inputMeta]);
}
GitLabDropdown.prototype.selectRowAtIndex = function(index) { this.dropdown.before($input).trigger('change');
var $el, selector; };
// If we pass an option index
if (typeof index !== 'undefined') { GitLabDropdown.prototype.selectRowAtIndex = function(index) {
selector = `${SELECTABLE_CLASSES}:eq(${index}) a`; var $el, selector;
// If we pass an option index
if (typeof index !== 'undefined') {
selector = `${SELECTABLE_CLASSES}:eq(${index}) a`;
} else {
selector = '.dropdown-content .is-focused';
}
if (this.dropdown.find('.dropdown-toggle-page').length) {
selector = `.dropdown-page-one ${selector}`;
}
// simulate a click on the first link
$el = $(selector, this.dropdown);
if ($el.length) {
var href = $el.attr('href');
if (href && href !== '#') {
visitUrl(href);
} else { } else {
selector = '.dropdown-content .is-focused'; $el.trigger('click');
} }
if (this.dropdown.find('.dropdown-toggle-page').length) { }
selector = `.dropdown-page-one ${selector}`; };
}
// simulate a click on the first link
$el = $(selector, this.dropdown);
if ($el.length) {
var href = $el.attr('href');
if (href && href !== '#') {
visitUrl(href);
} else {
$el.trigger('click');
}
}
};
GitLabDropdown.prototype.addArrowKeyEvent = function() { GitLabDropdown.prototype.addArrowKeyEvent = function() {
var ARROW_KEY_CODES, selector; var ARROW_KEY_CODES, selector;
ARROW_KEY_CODES = [38, 40]; ARROW_KEY_CODES = [38, 40];
selector = SELECTABLE_CLASSES; selector = SELECTABLE_CLASSES;
if (this.dropdown.find('.dropdown-toggle-page').length) { if (this.dropdown.find('.dropdown-toggle-page').length) {
selector = `.dropdown-page-one ${selector}`; selector = `.dropdown-page-one ${selector}`;
}
return $('body').on('keydown', e => {
var $listItems, PREV_INDEX, currentKeyCode;
currentKeyCode = e.which;
if (ARROW_KEY_CODES.indexOf(currentKeyCode) !== -1) {
e.preventDefault();
e.stopImmediatePropagation();
PREV_INDEX = currentIndex;
$listItems = $(selector, this.dropdown);
// if @options.filterable
// $input.blur()
if (currentKeyCode === 40) {
// Move down
if (currentIndex < $listItems.length - 1) {
currentIndex += 1;
}
} else if (currentKeyCode === 38) {
// Move up
if (currentIndex > 0) {
currentIndex -= 1;
}
}
if (currentIndex !== PREV_INDEX) {
this.highlightRowAtIndex($listItems, currentIndex);
}
return false;
} }
return $('body').on( if (currentKeyCode === 13 && currentIndex !== -1) {
'keydown', e.preventDefault();
(function(_this) { this.selectRowAtIndex();
return function(e) {
var $listItems, PREV_INDEX, currentKeyCode;
currentKeyCode = e.which;
if (ARROW_KEY_CODES.indexOf(currentKeyCode) !== -1) {
e.preventDefault();
e.stopImmediatePropagation();
PREV_INDEX = currentIndex;
$listItems = $(selector, _this.dropdown);
// if @options.filterable
// $input.blur()
if (currentKeyCode === 40) {
// Move down
if (currentIndex < $listItems.length - 1) {
currentIndex += 1;
}
} else if (currentKeyCode === 38) {
// Move up
if (currentIndex > 0) {
currentIndex -= 1;
}
}
if (currentIndex !== PREV_INDEX) {
_this.highlightRowAtIndex($listItems, currentIndex);
}
return false;
}
if (currentKeyCode === 13 && currentIndex !== -1) {
e.preventDefault();
_this.selectRowAtIndex();
}
};
})(this),
);
};
GitLabDropdown.prototype.removeArrowKeyEvent = function() {
return $('body').off('keydown');
};
GitLabDropdown.prototype.resetRows = function resetRows() {
currentIndex = -1;
$('.is-focused', this.dropdown).removeClass('is-focused');
};
GitLabDropdown.prototype.highlightRowAtIndex = function($listItems, index) {
var $dropdownContent,
$listItem,
dropdownContentBottom,
dropdownContentHeight,
dropdownContentTop,
dropdownScrollTop,
listItemBottom,
listItemHeight,
listItemTop;
if (!$listItems) {
$listItems = $(SELECTABLE_CLASSES, this.dropdown);
} }
});
};
// Remove the class for the previously focused row GitLabDropdown.prototype.removeArrowKeyEvent = function() {
$('.is-focused', this.dropdown).removeClass('is-focused'); return $('body').off('keydown');
// Update the class for the row at the specific index };
$listItem = $listItems.eq(index);
$listItem.find('a:first-child').addClass('is-focused');
// Dropdown content scroll area
$dropdownContent = $listItem.closest('.dropdown-content');
dropdownScrollTop = $dropdownContent.scrollTop();
dropdownContentHeight = $dropdownContent.outerHeight();
dropdownContentTop = $dropdownContent.prop('offsetTop');
dropdownContentBottom = dropdownContentTop + dropdownContentHeight;
// Get the offset bottom of the list item
listItemHeight = $listItem.outerHeight();
listItemTop = $listItem.prop('offsetTop');
listItemBottom = listItemTop + listItemHeight;
if (!index) {
// Scroll the dropdown content to the top
$dropdownContent.scrollTop(0);
} else if (index === $listItems.length - 1) {
// Scroll the dropdown content to the bottom
$dropdownContent.scrollTop($dropdownContent.prop('scrollHeight'));
} else if (listItemBottom > dropdownContentBottom + dropdownScrollTop) {
// Scroll the dropdown content down
$dropdownContent.scrollTop(
listItemBottom - dropdownContentBottom + CURSOR_SELECT_SCROLL_PADDING,
);
} else if (listItemTop < dropdownContentTop + dropdownScrollTop) {
// Scroll the dropdown content up
return $dropdownContent.scrollTop(
listItemTop - dropdownContentTop - CURSOR_SELECT_SCROLL_PADDING,
);
}
};
GitLabDropdown.prototype.updateLabel = function(selected, el, instance) { GitLabDropdown.prototype.resetRows = function resetRows() {
if (selected == null) { currentIndex = -1;
selected = null; $('.is-focused', this.dropdown).removeClass('is-focused');
} };
if (el == null) {
el = null;
}
if (instance == null) {
instance = null;
}
let toggleText = this.options.toggleLabel(selected, el, instance); GitLabDropdown.prototype.highlightRowAtIndex = function($listItems, index) {
if (this.options.updateLabel) { var $dropdownContent,
// Option to override the dropdown label text $listItem,
toggleText = this.options.updateLabel; dropdownContentBottom,
} dropdownContentHeight,
dropdownContentTop,
dropdownScrollTop,
listItemBottom,
listItemHeight,
listItemTop;
if (!$listItems) {
$listItems = $(SELECTABLE_CLASSES, this.dropdown);
}
// Remove the class for the previously focused row
$('.is-focused', this.dropdown).removeClass('is-focused');
// Update the class for the row at the specific index
$listItem = $listItems.eq(index);
$listItem.find('a:first-child').addClass('is-focused');
// Dropdown content scroll area
$dropdownContent = $listItem.closest('.dropdown-content');
dropdownScrollTop = $dropdownContent.scrollTop();
dropdownContentHeight = $dropdownContent.outerHeight();
dropdownContentTop = $dropdownContent.prop('offsetTop');
dropdownContentBottom = dropdownContentTop + dropdownContentHeight;
// Get the offset bottom of the list item
listItemHeight = $listItem.outerHeight();
listItemTop = $listItem.prop('offsetTop');
listItemBottom = listItemTop + listItemHeight;
if (!index) {
// Scroll the dropdown content to the top
$dropdownContent.scrollTop(0);
} else if (index === $listItems.length - 1) {
// Scroll the dropdown content to the bottom
$dropdownContent.scrollTop($dropdownContent.prop('scrollHeight'));
} else if (listItemBottom > dropdownContentBottom + dropdownScrollTop) {
// Scroll the dropdown content down
$dropdownContent.scrollTop(
listItemBottom - dropdownContentBottom + CURSOR_SELECT_SCROLL_PADDING,
);
} else if (listItemTop < dropdownContentTop + dropdownScrollTop) {
// Scroll the dropdown content up
return $dropdownContent.scrollTop(
listItemTop - dropdownContentTop - CURSOR_SELECT_SCROLL_PADDING,
);
}
};
GitLabDropdown.prototype.updateLabel = function(selected, el, instance) {
if (selected == null) {
selected = null;
}
if (el == null) {
el = null;
}
if (instance == null) {
instance = null;
}
return $(this.el) let toggleText = this.options.toggleLabel(selected, el, instance);
.find('.dropdown-toggle-text') if (this.options.updateLabel) {
.text(toggleText); // Option to override the dropdown label text
}; toggleText = this.options.updateLabel;
}
GitLabDropdown.prototype.clearField = function(field, isInput) { return $(this.el)
return isInput ? field.val('') : field.remove(); .find('.dropdown-toggle-text')
}; .text(toggleText);
};
return GitLabDropdown; GitLabDropdown.prototype.clearField = function(field, isInput) {
})(); return isInput ? field.val('') : field.remove();
};
$.fn.glDropdown = function(opts) { $.fn.glDropdown = function(opts) {
return this.each(function() { return this.each(function() {
......
---
title: Remove IIFEs from gl_dropdown.js
merge_request: 19983
author: nuwe1
type: other
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment