diff options
author | Jacob Schatz <jschatz@gitlab.com> | 2016-10-14 19:45:29 +0300 |
---|---|---|
committer | Jacob Schatz <jschatz@gitlab.com> | 2016-10-14 19:45:29 +0300 |
commit | 9e199fe057a41cc1316cc96b4472c340895e98a9 (patch) | |
tree | 553c4bd8f4374df3b86b0357cc6f1ef5ca6919f2 /app/assets/javascripts | |
parent | c2ca8a75064587ae17600fecb53e8c572505f1c4 (diff) | |
parent | ebddb5f329778ebf96d78c31e2ac93707a455864 (diff) |
Merge branch 'gl-dropdown-render-perf' into 'master'
Increased performance of GL dropdown renderItem
## What does this MR do?
- Fixes an issue where `renderItem` is called several times even when not required
- Increased performance when rendering dropdown items
- When using the `gl_dropdown.renderItem` it cuts the render time in approx. half. The main part holding it back now is finding the input to work out if it selected or not.
## What are the relevant issue numbers?
Closes #21110
See merge request !6222
Diffstat (limited to 'app/assets/javascripts')
-rw-r--r-- | app/assets/javascripts/gl_dropdown.js | 88 |
1 files changed, 44 insertions, 44 deletions
diff --git a/app/assets/javascripts/gl_dropdown.js b/app/assets/javascripts/gl_dropdown.js index e034ca68645..53762f2965c 100644 --- a/app/assets/javascripts/gl_dropdown.js +++ b/app/assets/javascripts/gl_dropdown.js @@ -25,7 +25,7 @@ return function(e) { e.preventDefault(); e.stopPropagation(); - return _this.input.val('').trigger('keyup').focus(); + return _this.input.val('').trigger('input').focus(); }; })(this)); // Key events @@ -37,28 +37,16 @@ e.preventDefault() } }) - .on('keyup', function(e) { - var keyCode; - keyCode = e.which; - if (ARROW_KEY_CODES.indexOf(keyCode) >= 0) { - return; - } + .on('input', function() { 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); } - if (keyCode === 13 && !options.elIsInput) { - return false; - } // Only filter asynchronously only if option remote is set if (this.options.remote) { clearTimeout(timeout); return timeout = setTimeout(function() { - var blurField = this.shouldBlur(keyCode); - if (blurField && this.filterInputBlur) { - this.input.blur(); - } return this.options.query(this.input.val(), function(data) { return this.options.callback(data); }.bind(this)); @@ -255,7 +243,7 @@ _this.fullData = data; _this.parseData(_this.fullData); if (_this.options.filterable && _this.filter && _this.filter.input) { - return _this.filter.input.trigger('keyup'); + return _this.filter.input.trigger('input'); } }; // Remote data @@ -487,7 +475,7 @@ // Triggering 'keyup' will re-render the dropdown which is not always required // specially if we want to keep the state of the dropdown needed for bulk-assignment if (!this.options.persistWhenHide) { - $input.trigger("keyup"); + $input.trigger("input"); } if (this.dropdown.find(".dropdown-toggle-page").length) { $('.dropdown-menu', this.dropdown).removeClass(PAGE_TWO_CLASS); @@ -500,14 +488,27 @@ // Render the full menu GitLabDropdown.prototype.renderMenu = function(html) { - var menu_html; - menu_html = ""; if (this.options.renderMenu) { - menu_html = this.options.renderMenu(html); + return this.options.renderMenu(html); } else { - menu_html = $('<ul />').append(html); + var ul = document.createElement('ul'); + + for (var i = 0; i < html.length; i++) { + var el = html[i]; + + if (el instanceof jQuery) { + el = el.get(0); + } + + if (typeof el === 'string') { + ul.innerHTML += el; + } else { + ul.appendChild(el); + } + } + + return ul; } - return menu_html; }; // Append the menu into the dropdown @@ -521,7 +522,7 @@ }; GitLabDropdown.prototype.renderItem = function(data, group, index) { - var cssClass, field, fieldName, groupAttrs, html, selected, text, url, value; + var field, fieldName, html, selected, text, url, value; if (group == null) { group = false; } @@ -529,18 +530,16 @@ // Render the row index = false; } - html = ""; - // Divider - if (data === "divider") { - return "<li class='divider'></li>"; - } - // Separator is a full-width divider - if (data === "separator") { - return "<li class='separator'></li>"; + html = document.createElement('li'); + if (data === 'divider' || data === 'separator') { + html.className = data; + return html; } // Header if (data.header != null) { - return _.template('<li class="dropdown-header"><%- header %></li>')({ header: data.header }); + html.className = 'dropdown-header'; + html.innerHTML = data.header; + return html; } if (this.options.renderRow) { // Call the render function @@ -567,24 +566,25 @@ } else { text = data.text != null ? data.text : ''; } - cssClass = ""; - if (selected) { - cssClass = "is-active"; - } if (this.highlight) { text = this.highlightTextMatches(text, this.filterInput.val()); } + // Create the list item & the link + var link = document.createElement('a'); + + link.href = url; + link.innerHTML = text; + + if (selected) { + link.className = 'is-active'; + } + if (group) { - groupAttrs = 'data-group=' + group + ' data-index=' + index; - } else { - groupAttrs = ''; + link.dataset.group = group; + link.dataset.index = index; } - html = _.template('<li><a href="<%- url %>" <%- groupAttrs %> class="<%- cssClass %>"><%= text %></a></li>')({ - url: url, - groupAttrs: groupAttrs, - cssClass: cssClass, - text: text - }); + + html.appendChild(link); } return html; }; |