summaryrefslogtreecommitdiff
path: root/app/assets/javascripts/gl_dropdown.js
diff options
context:
space:
mode:
Diffstat (limited to 'app/assets/javascripts/gl_dropdown.js')
-rw-r--r--app/assets/javascripts/gl_dropdown.js705
1 files changed, 705 insertions, 0 deletions
diff --git a/app/assets/javascripts/gl_dropdown.js b/app/assets/javascripts/gl_dropdown.js
new file mode 100644
index 00000000000..c5d92831fbe
--- /dev/null
+++ b/app/assets/javascripts/gl_dropdown.js
@@ -0,0 +1,705 @@
+(function() {
+ var GitLabDropdown, GitLabDropdownFilter, GitLabDropdownRemote,
+ bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },
+ indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };
+
+ GitLabDropdownFilter = (function() {
+ var ARROW_KEY_CODES, BLUR_KEYCODES, HAS_VALUE_CLASS;
+
+ BLUR_KEYCODES = [27, 40];
+
+ ARROW_KEY_CODES = [38, 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');
+ this.indeterminateIds = [];
+ $clearButton.on('click', (function(_this) {
+ return function(e) {
+ e.preventDefault();
+ e.stopPropagation();
+ return _this.input.val('').trigger('keyup').focus();
+ };
+ })(this));
+ timeout = "";
+ this.input.on("keyup", (function(_this) {
+ return function(e) {
+ var keyCode;
+ keyCode = e.which;
+ if (ARROW_KEY_CODES.indexOf(keyCode) >= 0) {
+ return;
+ }
+ 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) {
+ return false;
+ }
+ if (_this.options.remote) {
+ clearTimeout(timeout);
+ return timeout = setTimeout(function() {
+ var blur_field;
+ blur_field = _this.shouldBlur(keyCode);
+ if (blur_field && _this.filterInputBlur) {
+ _this.input.blur();
+ }
+ return _this.options.query(_this.input.val(), function(data) {
+ return _this.options.callback(data);
+ });
+ }, 250);
+ } else {
+ return _this.filter(_this.input.val());
+ }
+ };
+ })(this));
+ }
+
+ GitLabDropdownFilter.prototype.shouldBlur = function(keyCode) {
+ return BLUR_KEYCODES.indexOf(keyCode) >= 0;
+ };
+
+ GitLabDropdownFilter.prototype.filter = function(search_text) {
+ var data, elements, group, key, results, tmp;
+ if (this.options.onFilter) {
+ this.options.onFilter(search_text);
+ }
+ data = this.options.data();
+ if ((data != null) && !this.options.filterByText) {
+ results = data;
+ if (search_text !== '') {
+ if (_.isArray(data)) {
+ results = fuzzaldrinPlus.filter(data, search_text, {
+ key: this.options.keys
+ });
+ } else {
+ if (gl.utils.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(function(item) {
+ return item;
+ });
+ }
+ }
+ }
+ }
+ }
+ return this.options.callback(results);
+ } else {
+ elements = this.options.elements();
+ if (search_text) {
+ return elements.each(function() {
+ var $el, matches;
+ $el = $(this);
+ matches = fuzzaldrinPlus.match($el.text().trim(), search_text);
+ if (!$el.is('.dropdown-header')) {
+ if (matches.length) {
+ return $el.show();
+ } else {
+ return $el.hide();
+ }
+ }
+ });
+ } else {
+ return elements.show();
+ }
+ }
+ };
+
+ return GitLabDropdownFilter;
+
+ })();
+
+ GitLabDropdownRemote = (function() {
+ function GitLabDropdownRemote(dataEndpoint, options) {
+ this.dataEndpoint = dataEndpoint;
+ this.options = options;
+ }
+
+ GitLabDropdownRemote.prototype.execute = function() {
+ if (typeof this.dataEndpoint === "string") {
+ return this.fetchData();
+ } else if (typeof this.dataEndpoint === "function") {
+ if (this.options.beforeSend) {
+ this.options.beforeSend();
+ }
+ return this.dataEndpoint("", (function(_this) {
+ return function(data) {
+ if (_this.options.success) {
+ _this.options.success(data);
+ }
+ if (_this.options.beforeSend) {
+ return _this.options.beforeSend();
+ }
+ };
+ })(this));
+ }
+ };
+
+ GitLabDropdownRemote.prototype.fetchData = function() {
+ return $.ajax({
+ url: this.dataEndpoint,
+ dataType: this.options.dataType,
+ beforeSend: (function(_this) {
+ return function() {
+ if (_this.options.beforeSend) {
+ return _this.options.beforeSend();
+ }
+ };
+ })(this),
+ success: (function(_this) {
+ return function(data) {
+ if (_this.options.success) {
+ return _this.options.success(data);
+ }
+ };
+ })(this)
+ });
+ };
+
+ return GitLabDropdownRemote;
+
+ })();
+
+ GitLabDropdown = (function() {
+ var ACTIVE_CLASS, FILTER_INPUT, INDETERMINATE_CLASS, LOADING_CLASS, PAGE_TWO_CLASS, currentIndex;
+
+ LOADING_CLASS = "is-loading";
+
+ PAGE_TWO_CLASS = "is-page-two";
+
+ ACTIVE_CLASS = "is-active";
+
+ INDETERMINATE_CLASS = "is-indeterminate";
+
+ currentIndex = -1;
+
+ FILTER_INPUT = '.dropdown-input .dropdown-input-field';
+
+ function GitLabDropdown(el1, options) {
+ var ref, ref1, ref2, ref3, searchFields, selector, self;
+ this.el = el1;
+ this.options = options;
+ this.updateLabel = bind(this.updateLabel, this);
+ this.hidden = bind(this.hidden, this);
+ this.opened = bind(this.opened, this);
+ this.shouldPropagate = bind(this.shouldPropagate, this);
+ self = this;
+ selector = $(this.el).data("target");
+ this.dropdown = selector != null ? $(selector) : $(this.el).parent();
+ ref = this.options, this.filterInput = (ref1 = ref.filterInput) != null ? ref1 : this.getElement(FILTER_INPUT), this.highlight = (ref2 = ref.highlight) != null ? ref2 : false, this.filterInputBlur = (ref3 = ref.filterInputBlur) != null ? ref3 : true;
+ self = this;
+ if (_.isString(this.filterInput)) {
+ this.filterInput = this.getElement(this.filterInput);
+ }
+ searchFields = this.options.search ? this.options.search.fields : [];
+ if (this.options.data) {
+ if (_.isObject(this.options.data) && !_.isFunction(this.options.data)) {
+ this.fullData = this.options.data;
+ this.parseData(this.options.data);
+ } else {
+ this.remote = new GitLabDropdownRemote(this.options.data, {
+ dataType: this.options.dataType,
+ beforeSend: this.toggleLoading.bind(this),
+ success: (function(_this) {
+ return function(data) {
+ _this.fullData = data;
+ _this.parseData(_this.fullData);
+ if (_this.options.filterable && _this.filter && _this.filter.input) {
+ return _this.filter.input.trigger('keyup');
+ }
+ };
+ })(this)
+ });
+ }
+ }
+ if (this.options.filterable) {
+ this.filter = new GitLabDropdownFilter(this.filterInput, {
+ filterInputBlur: this.filterInputBlur,
+ filterByText: this.options.filterByText,
+ onFilter: this.options.onFilter,
+ remote: this.options.filterRemote,
+ query: this.options.data,
+ keys: searchFields,
+ elements: (function(_this) {
+ return function() {
+ selector = '.dropdown-content li:not(.divider)';
+ if (_this.dropdown.find('.dropdown-toggle-page').length) {
+ selector = ".dropdown-page-one " + selector;
+ }
+ return $(selector);
+ };
+ })(this),
+ data: (function(_this) {
+ return function() {
+ return _this.fullData;
+ };
+ })(this),
+ callback: (function(_this) {
+ return function(data) {
+ _this.parseData(data);
+ if (_this.filterInput.val() !== '') {
+ selector = '.dropdown-content li:not(.divider):visible';
+ if (_this.dropdown.find('.dropdown-toggle-page').length) {
+ selector = ".dropdown-page-one " + selector;
+ }
+ $(selector, _this.dropdown).first().find('a').addClass('is-focused');
+ return currentIndex = 0;
+ }
+ };
+ })(this)
+ });
+ }
+ this.dropdown.on("shown.bs.dropdown", this.opened);
+ this.dropdown.on("hidden.bs.dropdown", this.hidden);
+ $(this.el).on("update.label", this.updateLabel);
+ this.dropdown.on("click", ".dropdown-menu, .dropdown-menu-close", this.shouldPropagate);
+ this.dropdown.on('keyup', (function(_this) {
+ return function(e) {
+ if (e.which === 27) {
+ return $('.dropdown-menu-close', _this.dropdown).trigger('click');
+ }
+ };
+ })(this));
+ this.dropdown.on('blur', 'a', (function(_this) {
+ return function(e) {
+ var $dropdownMenu, $relatedTarget;
+ if (e.relatedTarget != null) {
+ $relatedTarget = $(e.relatedTarget);
+ $dropdownMenu = $relatedTarget.closest('.dropdown-menu');
+ if ($dropdownMenu.length === 0) {
+ return _this.dropdown.removeClass('open');
+ }
+ }
+ };
+ })(this));
+ if (this.dropdown.find(".dropdown-toggle-page").length) {
+ this.dropdown.find(".dropdown-toggle-page, .dropdown-menu-back").on("click", (function(_this) {
+ return function(e) {
+ e.preventDefault();
+ e.stopPropagation();
+ return _this.togglePage();
+ };
+ })(this));
+ }
+ 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, function(e) {
+ var $el, selected;
+ $el = $(this);
+ selected = self.rowClicked($el);
+ if (self.options.clicked) {
+ self.options.clicked(selected, $el, e);
+ }
+ return $el.trigger('blur');
+ });
+ }
+ }
+
+ GitLabDropdown.prototype.getElement = function(selector) {
+ return this.dropdown.find(selector);
+ };
+
+ GitLabDropdown.prototype.toggleLoading = function() {
+ return $('.dropdown-menu', this.dropdown).toggleClass(LOADING_CLASS);
+ };
+
+ GitLabDropdown.prototype.togglePage = function() {
+ var menu;
+ menu = $('.dropdown-menu', this.dropdown);
+ if (menu.hasClass(PAGE_TWO_CLASS)) {
+ if (this.remote) {
+ this.remote.execute();
+ }
+ }
+ menu.toggleClass(PAGE_TWO_CLASS);
+ return this.dropdown.find('[class^="dropdown-page-"]:visible :text:visible:first').focus();
+ };
+
+ GitLabDropdown.prototype.parseData = function(data) {
+ var full_html, groupData, html, name;
+ this.renderedData = data;
+ if (this.options.filterable && data.length === 0) {
+ html = [this.noResults()];
+ } else {
+ if (gl.utils.isObject(data)) {
+ html = [];
+ for (name in data) {
+ groupData = data[name];
+ html.push(this.renderItem({
+ header: name
+ }, name));
+ this.renderData(groupData, name).map(function(item) {
+ return html.push(item);
+ });
+ }
+ } else {
+ html = this.renderData(data);
+ }
+ }
+ full_html = this.renderMenu(html);
+ return this.appendMenu(full_html);
+ };
+
+ GitLabDropdown.prototype.renderData = function(data, group) {
+ if (group == null) {
+ group = false;
+ }
+ return data.map((function(_this) {
+ return function(obj, index) {
+ return _this.renderItem(obj, group, index);
+ };
+ })(this));
+ };
+
+ GitLabDropdown.prototype.shouldPropagate = function(e) {
+ var $target;
+ if (this.options.multiSelect) {
+ $target = $(e.target);
+ if (!$target.hasClass('dropdown-menu-close') && !$target.hasClass('dropdown-menu-close-icon') && !$target.data('is-link')) {
+ e.stopPropagation();
+ return false;
+ } else {
+ return true;
+ }
+ }
+ };
+
+ GitLabDropdown.prototype.opened = function() {
+ var contentHtml;
+ this.addArrowKeyEvent();
+ if (this.options.setIndeterminateIds) {
+ this.options.setIndeterminateIds.call(this);
+ }
+ if (this.options.setActiveIds) {
+ this.options.setActiveIds.call(this);
+ }
+ if (this.fullData && this.dropdown.find('.dropdown-menu-toggle').hasClass('js-filter-bulk-update')) {
+ this.parseData(this.fullData);
+ }
+ contentHtml = $('.dropdown-content', this.dropdown).html();
+ if (this.remote && contentHtml === "") {
+ this.remote.execute();
+ }
+ if (this.options.filterable) {
+ this.filterInput.focus();
+ }
+ return this.dropdown.trigger('shown.gl.dropdown');
+ };
+
+ GitLabDropdown.prototype.hidden = function(e) {
+ var $input;
+ this.removeArrayKeyEvent();
+ $input = this.dropdown.find(".dropdown-input-field");
+ if (this.options.filterable) {
+ $input.blur().val("");
+ }
+ if (!this.options.persistWhenHide) {
+ $input.trigger("keyup");
+ }
+ 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');
+ };
+
+ GitLabDropdown.prototype.renderMenu = function(html) {
+ var menu_html;
+ menu_html = "";
+ if (this.options.renderMenu) {
+ menu_html = this.options.renderMenu(html);
+ } else {
+ menu_html = $('<ul />').append(html);
+ }
+ return menu_html;
+ };
+
+ GitLabDropdown.prototype.appendMenu = function(html) {
+ var selector;
+ selector = '.dropdown-content';
+ if (this.dropdown.find(".dropdown-toggle-page").length) {
+ selector = ".dropdown-page-one .dropdown-content";
+ }
+ return $(selector, this.dropdown).empty().append(html);
+ };
+
+ GitLabDropdown.prototype.renderItem = function(data, group, index) {
+ var cssClass, field, fieldName, groupAttrs, html, selected, text, url, value;
+ if (group == null) {
+ group = false;
+ }
+ if (index == null) {
+ index = false;
+ }
+ html = "";
+ if (data === "divider") {
+ return "<li class='divider'></li>";
+ }
+ if (data === "separator") {
+ return "<li class='separator'></li>";
+ }
+ if (data.header != null) {
+ return "<li class='dropdown-header'>" + data.header + "</li>";
+ }
+ if (this.options.renderRow) {
+ html = this.options.renderRow.call(this.options, data, this);
+ } else {
+ if (!selected) {
+ value = this.options.id ? this.options.id(data) : data.id;
+ fieldName = this.options.fieldName;
+ field = this.dropdown.parent().find("input[name='" + fieldName + "'][value='" + value + "']");
+ if (field.length) {
+ selected = true;
+ }
+ }
+ if (this.options.url != null) {
+ url = this.options.url(data);
+ } else {
+ url = data.url != null ? data.url : '#';
+ }
+ if (this.options.text != null) {
+ text = this.options.text(data);
+ } else {
+ text = data.text != null ? data.text : '';
+ }
+ cssClass = "";
+ if (selected) {
+ cssClass = "is-active";
+ }
+ if (this.highlight) {
+ text = this.highlightTextMatches(text, this.filterInput.val());
+ }
+ if (group) {
+ groupAttrs = "data-group='" + group + "' data-index='" + index + "'";
+ } else {
+ groupAttrs = '';
+ }
+ html = "<li> <a href='" + url + "' " + groupAttrs + " class='" + cssClass + "'> " + text + " </a> </li>";
+ }
+ return html;
+ };
+
+ GitLabDropdown.prototype.highlightTextMatches = function(text, term) {
+ var occurrences;
+ occurrences = fuzzaldrinPlus.match(text, term);
+ return text.split('').map(function(character, i) {
+ if (indexOf.call(occurrences, i) >= 0) {
+ return "<b>" + character + "</b>";
+ } else {
+ return character;
+ }
+ }).join('');
+ };
+
+ GitLabDropdown.prototype.noResults = function() {
+ var html;
+ return html = "<li class='dropdown-menu-empty-link'> <a href='#' class='is-focused'> No matching results. </a> </li>";
+ };
+
+ GitLabDropdown.prototype.highlightRow = function(index) {
+ var selector;
+ if (this.filterInput.val() !== "") {
+ selector = '.dropdown-content li:first-child a';
+ if (this.dropdown.find(".dropdown-toggle-page").length) {
+ selector = ".dropdown-page-one .dropdown-content li:first-child a";
+ }
+ return this.getElement(selector).addClass('is-focused');
+ }
+ };
+
+ GitLabDropdown.prototype.rowClicked = function(el) {
+ var field, fieldName, groupName, isInput, selectedIndex, selectedObject, value;
+ fieldName = this.options.fieldName;
+ 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();
+ selectedObject = this.renderedData[selectedIndex];
+ }
+ }
+ value = this.options.id ? this.options.id(selectedObject, el) : selectedObject.id;
+ if (isInput) {
+ field = $(this.el);
+ } else {
+ field = this.dropdown.parent().find("input[name='" + fieldName + "'][value='" + value + "']");
+ }
+ if (el.hasClass(ACTIVE_CLASS)) {
+ el.removeClass(ACTIVE_CLASS);
+ if (isInput) {
+ field.val('');
+ } else {
+ field.remove();
+ }
+ if (this.options.toggleLabel) {
+ return this.updateLabel(selectedObject, el, this);
+ } else {
+ return selectedObject;
+ }
+ } else if (el.hasClass(INDETERMINATE_CLASS)) {
+ el.addClass(ACTIVE_CLASS);
+ el.removeClass(INDETERMINATE_CLASS);
+ if (value == null) {
+ field.remove();
+ }
+ if (!field.length && fieldName) {
+ this.addInput(fieldName, value);
+ }
+ return selectedObject;
+ } else {
+ 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 (value == null) {
+ field.remove();
+ }
+ el.addClass(ACTIVE_CLASS);
+ if (this.options.toggleLabel) {
+ this.updateLabel(selectedObject, el, this);
+ }
+ if (value != null) {
+ if (!field.length && fieldName) {
+ this.addInput(fieldName, value);
+ } else {
+ field.val(value).trigger('change');
+ }
+ }
+ return selectedObject;
+ }
+ };
+
+ GitLabDropdown.prototype.addInput = function(fieldName, value) {
+ var $input;
+ $input = $('<input>').attr('type', 'hidden').attr('name', fieldName).val(value);
+ if (this.options.inputId != null) {
+ $input.attr('id', this.options.inputId);
+ }
+ return this.dropdown.before($input);
+ };
+
+ GitLabDropdown.prototype.selectRowAtIndex = function(e, index) {
+ var $el, selector;
+ selector = ".dropdown-content li:not(.divider,.dropdown-header,.separator):eq(" + index + ") a";
+ if (this.dropdown.find(".dropdown-toggle-page").length) {
+ selector = ".dropdown-page-one " + selector;
+ }
+ $el = $(selector, this.dropdown);
+ if ($el.length) {
+ e.preventDefault();
+ e.stopImmediatePropagation();
+ return $el.first().trigger('click');
+ }
+ };
+
+ GitLabDropdown.prototype.addArrowKeyEvent = function() {
+ var $input, ARROW_KEY_CODES, selector;
+ ARROW_KEY_CODES = [38, 40];
+ $input = this.dropdown.find(".dropdown-input-field");
+ selector = '.dropdown-content li:not(.divider,.dropdown-header,.separator)';
+ if (this.dropdown.find(".dropdown-toggle-page").length) {
+ selector = ".dropdown-page-one " + selector;
+ }
+ return $('body').on('keydown', (function(_this) {
+ return function(e) {
+ var $listItems, PREV_INDEX, currentKeyCode;
+ currentKeyCode = e.which;
+ if (ARROW_KEY_CODES.indexOf(currentKeyCode) >= 0) {
+ e.preventDefault();
+ e.stopImmediatePropagation();
+ PREV_INDEX = currentIndex;
+ $listItems = $(selector, _this.dropdown);
+ if (currentKeyCode === 40) {
+ if (currentIndex < ($listItems.length - 1)) {
+ currentIndex += 1;
+ }
+ } else if (currentKeyCode === 38) {
+ if (currentIndex > 0) {
+ currentIndex -= 1;
+ }
+ }
+ if (currentIndex !== PREV_INDEX) {
+ _this.highlightRowAtIndex($listItems, currentIndex);
+ }
+ return false;
+ }
+ if (currentKeyCode === 13 && currentIndex !== -1) {
+ return _this.selectRowAtIndex(e, currentIndex);
+ }
+ };
+ })(this));
+ };
+
+ GitLabDropdown.prototype.removeArrayKeyEvent = function() {
+ return $('body').off('keydown');
+ };
+
+ GitLabDropdown.prototype.highlightRowAtIndex = function($listItems, index) {
+ var $dropdownContent, $listItem, dropdownContentBottom, dropdownContentHeight, dropdownContentTop, dropdownScrollTop, listItemBottom, listItemHeight, listItemTop;
+ $('.is-focused', this.dropdown).removeClass('is-focused');
+ $listItem = $listItems.eq(index);
+ $listItem.find('a:first-child').addClass("is-focused");
+ $dropdownContent = $listItem.closest('.dropdown-content');
+ dropdownScrollTop = $dropdownContent.scrollTop();
+ dropdownContentHeight = $dropdownContent.outerHeight();
+ dropdownContentTop = $dropdownContent.prop('offsetTop');
+ dropdownContentBottom = dropdownContentTop + dropdownContentHeight;
+ listItemHeight = $listItem.outerHeight();
+ listItemTop = $listItem.prop('offsetTop');
+ listItemBottom = listItemTop + listItemHeight;
+ if (listItemBottom > dropdownContentBottom + dropdownScrollTop) {
+ return $dropdownContent.scrollTop(listItemBottom - dropdownContentBottom);
+ } else if (listItemTop < dropdownContentTop + dropdownScrollTop) {
+ return $dropdownContent.scrollTop(listItemTop - dropdownContentTop);
+ }
+ };
+
+ 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).find(".dropdown-toggle-text").text(this.options.toggleLabel(selected, el, instance));
+ };
+
+ return GitLabDropdown;
+
+ })();
+
+ $.fn.glDropdown = function(opts) {
+ return this.each(function() {
+ if (!$.data(this, 'glDropdown')) {
+ return $.data(this, 'glDropdown', new GitLabDropdown(this, opts));
+ }
+ });
+ };
+
+}).call(this);