Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
authorClement Ho <ClemMakesApps@gmail.com>2016-12-12 18:21:38 +0300
committerClement Ho <ClemMakesApps@gmail.com>2017-01-10 01:01:17 +0300
commit513cdda31667f0058b24e8f66d87ddfcf89b7fb4 (patch)
tree60524b8ae21300c02f2b52647e58762c7a7c82d6 /app
parentf4db75728e8c16876cb3f74e12d4d707ab8f47c1 (diff)
Refactor filtered search manager
Diffstat (limited to 'app')
-rw-r--r--app/assets/javascripts/filtered_search/dropdown_hint.js.es62
-rw-r--r--app/assets/javascripts/filtered_search/dropdown_non_user.js.es62
-rw-r--r--app/assets/javascripts/filtered_search/dropdown_user.js.es62
-rw-r--r--app/assets/javascripts/filtered_search/filtered_search_dropdown.js.es62
-rw-r--r--app/assets/javascripts/filtered_search/filtered_search_dropdown_manager.js.es6174
-rw-r--r--app/assets/javascripts/filtered_search/filtered_search_manager.js.es6160
6 files changed, 185 insertions, 157 deletions
diff --git a/app/assets/javascripts/filtered_search/dropdown_hint.js.es6 b/app/assets/javascripts/filtered_search/dropdown_hint.js.es6
index d445a796f43..53952e6bc63 100644
--- a/app/assets/javascripts/filtered_search/dropdown_hint.js.es6
+++ b/app/assets/javascripts/filtered_search/dropdown_hint.js.es6
@@ -42,7 +42,7 @@
const tag = selected.querySelector('.js-filter-tag').innerText.trim();
if (tag.length) {
- gl.FilteredSearchManager.addWordToInput(this.getSelectedText(token));
+ gl.FilteredSearchDropdownManager.addWordToInput(this.getSelectedText(token));
}
this.dismissDropdown();
this.dispatchInputEvent();
diff --git a/app/assets/javascripts/filtered_search/dropdown_non_user.js.es6 b/app/assets/javascripts/filtered_search/dropdown_non_user.js.es6
index f03c27c3ec0..e4df39cfde1 100644
--- a/app/assets/javascripts/filtered_search/dropdown_non_user.js.es6
+++ b/app/assets/javascripts/filtered_search/dropdown_non_user.js.es6
@@ -25,7 +25,7 @@
if (!dataValueSet) {
const title = e.detail.selected.querySelector('.js-data-value').innerText.trim();
const name = `${this.symbol}${this.getEscapedText(title)}`;
- gl.FilteredSearchManager.addWordToInput(this.getSelectedText(name));
+ gl.FilteredSearchDropdownManager.addWordToInput(this.getSelectedText(name));
}
this.dismissDropdown(!dataValueSet);
diff --git a/app/assets/javascripts/filtered_search/dropdown_user.js.es6 b/app/assets/javascripts/filtered_search/dropdown_user.js.es6
index 6827ab1658a..d3c3be9b914 100644
--- a/app/assets/javascripts/filtered_search/dropdown_user.js.es6
+++ b/app/assets/javascripts/filtered_search/dropdown_user.js.es6
@@ -27,7 +27,7 @@
if (!dataValueSet) {
const username = e.detail.selected.querySelector('.dropdown-light-content').innerText.trim();
- gl.FilteredSearchManager.addWordToInput(this.getSelectedText(username));
+ gl.FilteredSearchDropdownManager.addWordToInput(this.getSelectedText(username));
}
this.dismissDropdown(!dataValueSet);
diff --git a/app/assets/javascripts/filtered_search/filtered_search_dropdown.js.es6 b/app/assets/javascripts/filtered_search/filtered_search_dropdown.js.es6
index c63ba1acf0b..38ecbbf552d 100644
--- a/app/assets/javascripts/filtered_search/filtered_search_dropdown.js.es6
+++ b/app/assets/javascripts/filtered_search/filtered_search_dropdown.js.es6
@@ -57,7 +57,7 @@
const dataValue = selected.getAttribute('data-value');
if (dataValue) {
- gl.FilteredSearchManager.addWordToInput(dataValue);
+ gl.FilteredSearchDropdownManager.addWordToInput(dataValue);
}
return dataValue !== null;
diff --git a/app/assets/javascripts/filtered_search/filtered_search_dropdown_manager.js.es6 b/app/assets/javascripts/filtered_search/filtered_search_dropdown_manager.js.es6
new file mode 100644
index 00000000000..67a474985c0
--- /dev/null
+++ b/app/assets/javascripts/filtered_search/filtered_search_dropdown_manager.js.es6
@@ -0,0 +1,174 @@
+/* eslint-disable no-param-reassign */
+((global) => {
+ class FilteredSearchDropdownManager {
+ constructor() {
+ this.tokenizer = gl.FilteredSearchTokenizer;
+ this.filteredSearchInput = document.querySelector('.filtered-search');
+
+ this.cleanupWrapper = this.cleanup.bind(this);
+ document.addEventListener('page:fetch', this.cleanupWrapper);
+ }
+
+ cleanup() {
+ if (this.droplab) {
+ this.droplab.destroy();
+ this.droplab = null;
+ }
+
+ this.setupMapping();
+
+ document.removeEventListener('page:fetch', this.cleanupWrapper);
+ }
+
+ setupMapping() {
+ this.mapping = {
+ author: {
+ reference: null,
+ gl: 'DropdownUser',
+ element: document.querySelector('#js-dropdown-author'),
+ },
+ assignee: {
+ reference: null,
+ gl: 'DropdownUser',
+ element: document.querySelector('#js-dropdown-assignee'),
+ },
+ milestone: {
+ reference: null,
+ gl: 'DropdownNonUser',
+ extraArguments: ['milestones.json', '%'],
+ element: document.querySelector('#js-dropdown-milestone'),
+ },
+ label: {
+ reference: null,
+ gl: 'DropdownNonUser',
+ extraArguments: ['labels.json', '~'],
+ element: document.querySelector('#js-dropdown-label'),
+ },
+ hint: {
+ reference: null,
+ gl: 'DropdownHint',
+ element: document.querySelector('#js-dropdown-hint'),
+ },
+ }
+ }
+
+ static addWordToInput(word, addSpace) {
+ const filteredSearchInput = document.querySelector('.filtered-search')
+ const filteredSearchValue = filteredSearchInput.value;
+ const hasExistingValue = filteredSearchValue.length !== 0;
+ const { lastToken } = gl.FilteredSearchTokenizer.processTokens(filteredSearchValue);
+
+ if (lastToken.hasOwnProperty('key')) {
+ console.log(lastToken);
+ // Spaces inside the token means that the token value will be escaped by quotes
+ const hasQuotes = lastToken.value.indexOf(' ') !== -1;
+ const lengthToRemove = hasQuotes ? lastToken.value.length + 2 : lastToken.value.length;
+ filteredSearchInput.value = filteredSearchValue.slice(0, -1 * (lengthToRemove));
+ }
+
+ filteredSearchInput.value += hasExistingValue && addSpace ? ` ${word}` : word;
+ }
+
+ updateCurrentDropdownOffset() {
+ this.updateDropdownOffset(this.currentDropdown);
+ }
+
+ updateDropdownOffset(key) {
+ const filterIconPadding = 27;
+ const offset = gl.text.getTextWidth(this.filteredSearchInput.value, this.font) + filterIconPadding;
+
+ this.mapping[key].reference.setOffset(offset);
+ }
+
+ load(key, firstLoad = false) {
+ console.log(`🦄 load ${key} dropdown`);
+ const glClass = this.mapping[key].gl;
+ const element = this.mapping[key].element;
+ let forceShowList = false;
+
+ if (!this.mapping[key].reference) {
+ var dl = this.droplab;
+ const defaultArguments = [null, dl, element, this.filteredSearchInput];
+ const glArguments = defaultArguments.concat(this.mapping[key].extraArguments || []);
+
+ this.mapping[key].reference = new (Function.prototype.bind.apply(gl[glClass], glArguments));
+ }
+
+ if (firstLoad) {
+ this.mapping[key].reference.configure();
+ }
+
+ if (this.currentDropdown === 'hint') {
+ // Clicked from hint dropdown
+ forceShowList = true;
+ }
+
+ this.updateDropdownOffset(key);
+ this.mapping[key].reference.render(firstLoad, forceShowList);
+
+ this.currentDropdown = key;
+ }
+
+ loadDropdown(dropdownName = '') {
+ let firstLoad = false;
+
+ if(!this.droplab) {
+ firstLoad = true;
+ this.droplab = new DropLab();
+ }
+
+ if (!this.font) {
+ this.font = window.getComputedStyle(this.filteredSearchInput).font;
+ }
+
+ const match = gl.FilteredSearchTokenKeys.get().filter(value => value.key === dropdownName.toLowerCase())[0];
+ const shouldOpenFilterDropdown = match && this.currentDropdown !== match.key && this.mapping.hasOwnProperty(match.key);
+ const shouldOpenHintDropdown = !match && this.currentDropdown !== 'hint';
+
+ if (shouldOpenFilterDropdown || shouldOpenHintDropdown) {
+ const key = match && match.hasOwnProperty('key') ? match.key : 'hint';
+ this.load(key, firstLoad);
+ }
+
+ gl.droplab = this.droplab;
+ }
+
+ setDropdown() {
+ const { lastToken } = this.tokenizer.processTokens(this.filteredSearchInput.value);
+
+ if (typeof lastToken === 'string') {
+ // Token is not fully initialized yet
+ // because it has no value
+ // Eg. token = 'label:'
+ const { tokenKey } = this.tokenizer.parseToken(lastToken);
+ this.loadDropdown(tokenKey);
+ } else if (lastToken.hasOwnProperty('key')) {
+ // Token has been initialized into an object
+ // because it has a value
+ this.loadDropdown(lastToken.key);
+ } else {
+ this.loadDropdown('hint');
+ }
+ }
+
+ resetDropdowns() {
+ // Force current dropdown to hide
+ this.mapping[this.currentDropdown].reference.hideDropdown();
+
+ // Re-Load dropdown
+ this.setDropdown();
+
+ // Reset filters for current dropdown
+ this.mapping[this.currentDropdown].reference.resetFilters();
+
+ // Reposition dropdown so that it is aligned with cursor
+ this.updateDropdownOffset(this.currentDropdown);
+ }
+
+ destroyDroplab() {
+ this.droplab.destroy();
+ }
+ }
+
+ global.FilteredSearchDropdownManager = FilteredSearchDropdownManager;
+})(window.gl || (window.gl = {}));
diff --git a/app/assets/javascripts/filtered_search/filtered_search_manager.js.es6 b/app/assets/javascripts/filtered_search/filtered_search_manager.js.es6
index c92d669114e..d9ea44b3a13 100644
--- a/app/assets/javascripts/filtered_search/filtered_search_manager.js.es6
+++ b/app/assets/javascripts/filtered_search/filtered_search_manager.js.es6
@@ -75,159 +75,24 @@
this.tokenizer = gl.FilteredSearchTokenizer;
this.filteredSearchInput = document.querySelector('.filtered-search');
this.clearSearchButton = document.querySelector('.clear-search');
+ this.dropdownManager = new gl.FilteredSearchDropdownManager();
- this.setupMapping();
+ this.dropdownManager.setupMapping();
this.bindEvents();
loadSearchParamsFromURL();
- this.setDropdown();
+ this.dropdownManager.setDropdown();
this.cleanupWrapper = this.cleanup.bind(this);
document.addEventListener('page:fetch', this.cleanupWrapper);
}
cleanup() {
- console.log('cleanup')
-
- if (this.droplab) {
- this.droplab.destroy();
- this.droplab = null;
- }
-
- this.setupMapping();
-
this.unbindEvents();
document.removeEventListener('page:fetch', this.cleanupWrapper);
}
- setupMapping() {
- this.mapping = {
- author: {
- reference: null,
- gl: 'DropdownUser',
- element: document.querySelector('#js-dropdown-author'),
- },
- assignee: {
- reference: null,
- gl: 'DropdownUser',
- element: document.querySelector('#js-dropdown-assignee'),
- },
- milestone: {
- reference: null,
- gl: 'DropdownNonUser',
- extraArguments: ['milestones.json', '%'],
- element: document.querySelector('#js-dropdown-milestone'),
- },
- label: {
- reference: null,
- gl: 'DropdownNonUser',
- extraArguments: ['labels.json', '~'],
- element: document.querySelector('#js-dropdown-label'),
- },
- hint: {
- reference: null,
- gl: 'DropdownHint',
- element: document.querySelector('#js-dropdown-hint'),
- },
- }
- }
-
- static addWordToInput(word, addSpace) {
- const filteredSearchInput = document.querySelector('.filtered-search')
- const filteredSearchValue = filteredSearchInput.value;
- const hasExistingValue = filteredSearchValue.length !== 0;
- const { lastToken } = gl.FilteredSearchTokenizer.processTokens(filteredSearchValue);
-
- if (lastToken.hasOwnProperty('key')) {
- console.log(lastToken);
- // Spaces inside the token means that the token value will be escaped by quotes
- const hasQuotes = lastToken.value.indexOf(' ') !== -1;
- const lengthToRemove = hasQuotes ? lastToken.value.length + 2 : lastToken.value.length;
- filteredSearchInput.value = filteredSearchValue.slice(0, -1 * (lengthToRemove));
- }
-
- filteredSearchInput.value += hasExistingValue && addSpace ? ` ${word}` : word;
- }
-
- updateDropdownOffset(key) {
- const filterIconPadding = 27;
- const offset = gl.text.getTextWidth(this.filteredSearchInput.value, this.font) + filterIconPadding;
-
- this.mapping[key].reference.setOffset(offset);
- }
-
- load(key, firstLoad = false) {
- console.log(`🦄 load ${key} dropdown`);
- const glClass = this.mapping[key].gl;
- const element = this.mapping[key].element;
- let forceShowList = false;
-
- if (!this.mapping[key].reference) {
- var dl = this.droplab;
- const defaultArguments = [null, dl, element, this.filteredSearchInput];
- const glArguments = defaultArguments.concat(this.mapping[key].extraArguments || []);
-
- this.mapping[key].reference = new (Function.prototype.bind.apply(gl[glClass], glArguments));
- }
-
- if (firstLoad) {
- this.mapping[key].reference.configure();
- }
-
- if (this.currentDropdown === 'hint') {
- // Clicked from hint dropdown
- forceShowList = true;
- }
-
- this.updateDropdownOffset(key);
- this.mapping[key].reference.render(firstLoad, forceShowList);
-
- this.currentDropdown = key;
- }
-
- loadDropdown(dropdownName = '') {
- let firstLoad = false;
-
- if(!this.droplab) {
- firstLoad = true;
- this.droplab = new DropLab();
- }
-
- if (!this.font) {
- this.font = window.getComputedStyle(this.filteredSearchInput).font;
- }
-
- const match = gl.FilteredSearchTokenKeys.get().filter(value => value.key === dropdownName.toLowerCase())[0];
- const shouldOpenFilterDropdown = match && this.currentDropdown !== match.key && this.mapping.hasOwnProperty(match.key);
- const shouldOpenHintDropdown = !match && this.currentDropdown !== 'hint';
-
- if (shouldOpenFilterDropdown || shouldOpenHintDropdown) {
- const key = match && match.hasOwnProperty('key') ? match.key : 'hint';
- this.load(key, firstLoad);
- }
-
- gl.droplab = this.droplab;
- }
-
- setDropdown() {
- const { lastToken } = this.tokenizer.processTokens(this.filteredSearchInput.value);
-
- if (typeof lastToken === 'string') {
- // Token is not fully initialized yet
- // because it has no value
- // Eg. token = 'label:'
- const { tokenKey } = this.tokenizer.parseToken(lastToken);
- this.loadDropdown(tokenKey);
- } else if (lastToken.hasOwnProperty('key')) {
- // Token has been initialized into an object
- // because it has a value
- this.loadDropdown(lastToken.key);
- } else {
- this.loadDropdown('hint');
- }
- }
-
bindEvents() {
- this.setDropdownWrapper = this.setDropdown.bind(this);
+ this.setDropdownWrapper = this.dropdownManager.setDropdown.bind(this.dropdownManager);
this.checkForEnterWrapper = this.checkForEnter.bind(this);
this.clearSearchWrapper = this.clearSearch.bind(this);
this.checkForBackspaceWrapper = this.checkForBackspace.bind(this);
@@ -254,24 +119,13 @@
this.filteredSearchInput.value = '';
this.clearSearchButton.classList.add('hidden');
-
- // Force current dropdown to hide
- this.mapping[this.currentDropdown].reference.hideDropdown();
-
- // Re-Load dropdown
- this.setDropdown();
-
- // Reset filters for current dropdown
- this.mapping[this.currentDropdown].reference.resetFilters();
-
- // Reposition dropdown so that it is aligned with cursor
- this.updateDropdownOffset(this.currentDropdown);
+ this.dropdownManager.resetDropdowns();
}
checkForBackspace(e) {
if (e.keyCode === 8) {
// Reposition dropdown so that it is aligned with cursor
- this.updateDropdownOffset(this.currentDropdown);
+ this.dropdownManager.updateCurrentDropdownOffset();
}
}
@@ -282,7 +136,7 @@
e.preventDefault();
// Prevent droplab from opening dropdown
- this.droplab.destroy();
+ this.dropdownManager.destroyDroplab();
this.search();
}