Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gitlab-ce
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
1
Merge Requests
1
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
gitlab-ce
Commits
5589ab1e
Commit
5589ab1e
authored
Dec 12, 2016
by
Clement Ho
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Refactor and add comments
parent
2bbc44cb
Changes
7
Show whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
58 additions
and
66 deletions
+58
-66
app/assets/javascripts/filtered_search/dropdown_hint.js.es6
app/assets/javascripts/filtered_search/dropdown_hint.js.es6
+1
-2
app/assets/javascripts/filtered_search/dropdown_non_user.js.es6
...sets/javascripts/filtered_search/dropdown_non_user.js.es6
+9
-8
app/assets/javascripts/filtered_search/dropdown_user.js.es6
app/assets/javascripts/filtered_search/dropdown_user.js.es6
+1
-2
app/assets/javascripts/filtered_search/filtered_search_dropdown.js.es6
...vascripts/filtered_search/filtered_search_dropdown.js.es6
+20
-19
app/assets/javascripts/filtered_search/filtered_search_dropdown_manager.js.es6
...s/filtered_search/filtered_search_dropdown_manager.js.es6
+22
-19
app/assets/javascripts/filtered_search/filtered_search_manager.js.es6
...avascripts/filtered_search/filtered_search_manager.js.es6
+5
-4
app/assets/javascripts/filtered_search/filtered_search_tokenizer.es6
...javascripts/filtered_search/filtered_search_tokenizer.es6
+0
-12
No files found.
app/assets/javascripts/filtered_search/dropdown_hint.js.es6
View file @
5589ab1e
...
@@ -23,7 +23,6 @@
...
@@ -23,7 +23,6 @@
class DropdownHint extends gl.FilteredSearchDropdown {
class DropdownHint extends gl.FilteredSearchDropdown {
constructor(droplab, dropdown, input) {
constructor(droplab, dropdown, input) {
super(droplab, dropdown, input);
super(droplab, dropdown, input);
this.listId = dropdown.id;
this.config = {
this.config = {
droplabFilter: {
droplabFilter: {
template: 'hint',
template: 'hint',
...
@@ -66,7 +65,7 @@
...
@@ -66,7 +65,7 @@
return item;
return item;
}
}
configure
() {
init
() {
this.droplab.addHook(this.input, this.dropdown, [droplabFilter], this.config).init();
this.droplab.addHook(this.input, this.dropdown, [droplabFilter], this.config).init();
}
}
}
}
...
...
app/assets/javascripts/filtered_search/dropdown_non_user.js.es6
View file @
5589ab1e
...
@@ -5,7 +5,6 @@
...
@@ -5,7 +5,6 @@
class DropdownNonUser extends gl.FilteredSearchDropdown {
class DropdownNonUser extends gl.FilteredSearchDropdown {
constructor(droplab, dropdown, input, endpoint, symbol) {
constructor(droplab, dropdown, input, endpoint, symbol) {
super(droplab, dropdown, input);
super(droplab, dropdown, input);
this.listId = dropdown.id;
this.symbol = symbol;
this.symbol = symbol;
this.config = {
this.config = {
droplabAjax: {
droplabAjax: {
...
@@ -28,15 +27,17 @@
...
@@ -28,15 +27,17 @@
getEscapedText(text) {
getEscapedText(text) {
let escapedText = text;
let escapedText = text;
const hasSpace = text.indexOf(' ') !== -1;
const hasDoubleQuote = text.indexOf('"') !== -1;
const hasSingleQuote = text.indexOf('\'') !== -1;
// Encapsulate value with quotes if it has spaces
// Encapsulate value with quotes if it has spaces
if (text.indexOf(' ') !== -1) {
if (text.indexOf('"') !== -1) {
// Use single quotes if value contains double quotes
escapedText = `'${text}'`;
} else {
// Known side effect: values's with both single and double quotes
// Known side effect: values's with both single and double quotes
// won't escape properly
// won't escape properly
if (hasSpace) {
if (hasDoubleQuote) {
escapedText = `'${text}'`;
} else if (hasSingleQuote) {
escapedText = `"${text}"`;
escapedText = `"${text}"`;
}
}
}
}
...
@@ -65,7 +66,7 @@
...
@@ -65,7 +66,7 @@
super.renderContent(forceShowList);
super.renderContent(forceShowList);
}
}
configure
() {
init
() {
this.droplab.addHook(this.input, this.dropdown, [droplabAjax, droplabFilter], this.config).init();
this.droplab.addHook(this.input, this.dropdown, [droplabAjax, droplabFilter], this.config).init();
}
}
}
}
...
...
app/assets/javascripts/filtered_search/dropdown_user.js.es6
View file @
5589ab1e
...
@@ -5,7 +5,6 @@
...
@@ -5,7 +5,6 @@
class DropdownUser extends gl.FilteredSearchDropdown {
class DropdownUser extends gl.FilteredSearchDropdown {
constructor(droplab, dropdown, input) {
constructor(droplab, dropdown, input) {
super(droplab, dropdown, input);
super(droplab, dropdown, input);
this.listId = dropdown.id;
this.config = {
this.config = {
droplabAjaxFilter: {
droplabAjaxFilter: {
endpoint: '/autocomplete/users.json',
endpoint: '/autocomplete/users.json',
...
@@ -47,7 +46,7 @@
...
@@ -47,7 +46,7 @@
return hasPrefix ? valueWithoutPrefix : valueWithoutColon;
return hasPrefix ? valueWithoutPrefix : valueWithoutColon;
}
}
configure
() {
init
() {
this.droplab.addHook(this.input, this.dropdown, [droplabAjaxFilter], this.config).init();
this.droplab.addHook(this.input, this.dropdown, [droplabAjaxFilter], this.config).init();
}
}
}
}
...
...
app/assets/javascripts/filtered_search/filtered_search_dropdown.js.es6
View file @
5589ab1e
...
@@ -46,14 +46,8 @@
...
@@ -46,14 +46,8 @@
this.dismissDropdown();
this.dismissDropdown();
}
}
renderContent(forceShowList = false) {
if (forceShowList && this.getCurrentHook().list.hidden) {
this.getCurrentHook().list.show();
}
}
setAsDropdown() {
setAsDropdown() {
this.input.setAttribute(DATA_DROPDOWN_TRIGGER, `#${this.
listI
d}`);
this.input.setAttribute(DATA_DROPDOWN_TRIGGER, `#${this.
dropdown.i
d}`);
}
}
setOffset(offset = 0) {
setOffset(offset = 0) {
...
@@ -67,17 +61,14 @@
...
@@ -67,17 +61,14 @@
gl.FilteredSearchDropdownManager.addWordToInput(dataValue);
gl.FilteredSearchDropdownManager.addWordToInput(dataValue);
}
}
// Return boolean based on whether it was set
return dataValue !== null;
return dataValue !== null;
}
}
dismissDropdown() {
renderContent(forceShowList = false) {
this.input.focus();
if (forceShowList && this.getCurrentHook().list.hidden) {
this.getCurrentHook().list.show();
}
}
dispatchInputEvent() {
// Propogate input change to FilteredSearchManager
// so that it can determine which dropdowns to open
this.input.dispatchEvent(new Event('input'));
}
}
render(forceRenderContent = false, forceShowList = false) {
render(forceRenderContent = false, forceShowList = false) {
...
@@ -88,11 +79,23 @@
...
@@ -88,11 +79,23 @@
if (firstTimeInitialized || forceRenderContent) {
if (firstTimeInitialized || forceRenderContent) {
this.renderContent(forceShowList);
this.renderContent(forceShowList);
} else if(currentHook.list.list.id !== this.
listI
d) {
} else if(currentHook.list.list.id !== this.
dropdown.i
d) {
this.renderContent(forceShowList);
this.renderContent(forceShowList);
}
}
}
}
dismissDropdown() {
// Focusing on the input will dismiss dropdown
// (default droplab functionality)
this.input.focus();
}
dispatchInputEvent() {
// Propogate input change to FilteredSearchDropdownManager
// so that it can determine which dropdowns to open
this.input.dispatchEvent(new Event('input'));
}
hideDropdown() {
hideDropdown() {
this.getCurrentHook().list.hide();
this.getCurrentHook().list.hide();
}
}
...
@@ -100,9 +103,7 @@
...
@@ -100,9 +103,7 @@
resetFilters() {
resetFilters() {
const hook = this.getCurrentHook();
const hook = this.getCurrentHook();
const data = hook.list.data;
const data = hook.list.data;
const results = data.map(function(o) {
const results = data.map(o => o.droplab_hidden = false);
o.droplab_hidden = false;
});
hook.list.render(results);
hook.list.render(results);
}
}
}
}
...
...
app/assets/javascripts/filtered_search/filtered_search_dropdown_manager.js.es6
View file @
5589ab1e
...
@@ -5,6 +5,8 @@
...
@@ -5,6 +5,8 @@
this.tokenizer = gl.FilteredSearchTokenizer;
this.tokenizer = gl.FilteredSearchTokenizer;
this.filteredSearchInput = document.querySelector('.filtered-search');
this.filteredSearchInput = document.querySelector('.filtered-search');
this.setupMapping();
this.cleanupWrapper = this.cleanup.bind(this);
this.cleanupWrapper = this.cleanup.bind(this);
document.addEventListener('page:fetch', this.cleanupWrapper);
document.addEventListener('page:fetch', this.cleanupWrapper);
}
}
...
@@ -52,21 +54,22 @@
...
@@ -52,21 +54,22 @@
}
}
}
}
static addWordToInput(word, addSpace) {
static addWordToInput(word, addSpace
= false
) {
const
filteredSearchI
nput = document.querySelector('.filtered-search')
const
i
nput = document.querySelector('.filtered-search')
const
filteredSearchValue = filteredSearchI
nput.value;
const
value = i
nput.value;
const hasExistingValue =
filteredSearchV
alue.length !== 0;
const hasExistingValue =
v
alue.length !== 0;
const { lastToken } = gl.FilteredSearchTokenizer.processTokens(
filteredSearchV
alue);
const { lastToken } = gl.FilteredSearchTokenizer.processTokens(
v
alue);
if (lastToken.hasOwnProperty('key')) {
if (lastToken.hasOwnProperty('key')) {
console.log(lastToken);
// Spaces inside the token means that the token value will be escaped by quotes
// Spaces inside the token means that the token value will be escaped by quotes
const hasQuotes = lastToken.value.indexOf(' ') !== -1;
const hasQuotes = lastToken.value.indexOf(' ') !== -1;
// Add 2 length to account for the length of the front and back quotes
const lengthToRemove = hasQuotes ? lastToken.value.length + 2 : lastToken.value.length;
const lengthToRemove = hasQuotes ? lastToken.value.length + 2 : lastToken.value.length;
filteredSearchInput.value = filteredSearchV
alue.slice(0, -1 * (lengthToRemove));
input.value = v
alue.slice(0, -1 * (lengthToRemove));
}
}
filteredSearchI
nput.value += hasExistingValue && addSpace ? ` ${word}` : word;
i
nput.value += hasExistingValue && addSpace ? ` ${word}` : word;
}
}
updateCurrentDropdownOffset() {
updateCurrentDropdownOffset() {
...
@@ -74,6 +77,10 @@
...
@@ -74,6 +77,10 @@
}
}
updateDropdownOffset(key) {
updateDropdownOffset(key) {
if (!this.font) {
this.font = window.getComputedStyle(this.filteredSearchInput).font;
}
const filterIconPadding = 27;
const filterIconPadding = 27;
const offset = gl.text.getTextWidth(this.filteredSearchInput.value, this.font) + filterIconPadding;
const offset = gl.text.getTextWidth(this.filteredSearchInput.value, this.font) + filterIconPadding;
...
@@ -87,19 +94,20 @@
...
@@ -87,19 +94,20 @@
let forceShowList = false;
let forceShowList = false;
if (!this.mapping[key].reference) {
if (!this.mapping[key].reference) {
var
dl = this.droplab;
const
dl = this.droplab;
const defaultArguments = [null, dl, element, this.filteredSearchInput];
const defaultArguments = [null, dl, element, this.filteredSearchInput];
const glArguments = defaultArguments.concat(this.mapping[key].extraArguments || []);
const glArguments = defaultArguments.concat(this.mapping[key].extraArguments || []);
// Passing glArguments to `new gl[glClass](<arguments>)`
this.mapping[key].reference = new (Function.prototype.bind.apply(gl[glClass], glArguments));
this.mapping[key].reference = new (Function.prototype.bind.apply(gl[glClass], glArguments));
}
}
if (firstLoad) {
if (firstLoad) {
this.mapping[key].reference.
configure
();
this.mapping[key].reference.
init
();
}
}
if (this.currentDropdown === 'hint') {
if (this.currentDropdown === 'hint') {
//
Clicked from
hint dropdown
//
Force the dropdown to show if it was clicked from the
hint dropdown
forceShowList = true;
forceShowList = true;
}
}
...
@@ -117,15 +125,12 @@
...
@@ -117,15 +125,12 @@
this.droplab = new DropLab();
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 match = gl.FilteredSearchTokenKeys.get().filter(value => value.key === dropdownName.toLowerCase())[0];
const shouldOpenFilterDropdown = match && this.currentDropdown !== match.key && this.mapping.hasOwnProperty(match.key);
const shouldOpenFilterDropdown = match && this.currentDropdown !== match.key && this.mapping.hasOwnProperty(match.key);
const shouldOpenHintDropdown = !match && this.currentDropdown !== 'hint';
const shouldOpenHintDropdown = !match && this.currentDropdown !== 'hint';
if (shouldOpenFilterDropdown || shouldOpenHintDropdown) {
if (shouldOpenFilterDropdown || shouldOpenHintDropdown) {
// `hint` is not listed as a tokenKey (since it is not a real `filter`)
const key = match && match.hasOwnProperty('key') ? match.key : 'hint';
const key = match && match.hasOwnProperty('key') ? match.key : 'hint';
this.load(key, firstLoad);
this.load(key, firstLoad);
}
}
...
@@ -137,14 +142,12 @@
...
@@ -137,14 +142,12 @@
const { lastToken } = this.tokenizer.processTokens(this.filteredSearchInput.value);
const { lastToken } = this.tokenizer.processTokens(this.filteredSearchInput.value);
if (typeof lastToken === 'string') {
if (typeof lastToken === 'string') {
// Token is not fully initialized yet
// Token is not fully initialized yet because it has no value
// because it has no value
// Eg. token = 'label:'
// Eg. token = 'label:'
const { tokenKey } = this.tokenizer.parseToken(lastToken);
const { tokenKey } = this.tokenizer.parseToken(lastToken);
this.loadDropdown(tokenKey);
this.loadDropdown(tokenKey);
} else if (lastToken.hasOwnProperty('key')) {
} else if (lastToken.hasOwnProperty('key')) {
// Token has been initialized into an object
// Token has been initialized into an object because it has a value
// because it has a value
this.loadDropdown(lastToken.key);
this.loadDropdown(lastToken.key);
} else {
} else {
this.loadDropdown('hint');
this.loadDropdown('hint');
...
...
app/assets/javascripts/filtered_search/filtered_search_manager.js.es6
View file @
5589ab1e
/* eslint-disable no-param-reassign */
/* eslint-disable no-param-reassign */
((global) => {
((global) => {
// TODO: Encapsulate inside class?
function toggleClearSearchButton(e) {
function toggleClearSearchButton(e) {
const clearSearchButton = document.querySelector('.clear-search');
const clearSearchButton = document.querySelector('.clear-search');
...
@@ -25,6 +26,7 @@
...
@@ -25,6 +26,7 @@
let conditionIndex = 0;
let conditionIndex = 0;
const validCondition = gl.FilteredSearchTokenKeys.get()
const validCondition = gl.FilteredSearchTokenKeys.get()
.filter(v => v.conditions && v.conditions.filter((c, index) => {
.filter(v => v.conditions && v.conditions.filter((c, index) => {
// TODO: Add comment here
if (c.url === p) {
if (c.url === p) {
conditionIndex = index;
conditionIndex = index;
}
}
...
@@ -32,6 +34,7 @@
...
@@ -32,6 +34,7 @@
})[0])[0];
})[0])[0];
if (validCondition) {
if (validCondition) {
// Parse params based on rules provided in the conditions key of gl.FilteredSearchTokenKeys.get()
inputValue += `${validCondition.key}:${validCondition.conditions[conditionIndex].keyword}`;
inputValue += `${validCondition.key}:${validCondition.conditions[conditionIndex].keyword}`;
inputValue += ' ';
inputValue += ' ';
} else {
} else {
...
@@ -77,7 +80,6 @@
...
@@ -77,7 +80,6 @@
this.clearSearchButton = document.querySelector('.clear-search');
this.clearSearchButton = document.querySelector('.clear-search');
this.dropdownManager = new gl.FilteredSearchDropdownManager();
this.dropdownManager = new gl.FilteredSearchDropdownManager();
this.dropdownManager.setupMapping();
this.bindEvents();
this.bindEvents();
loadSearchParamsFromURL();
loadSearchParamsFromURL();
this.dropdownManager.setDropdown();
this.dropdownManager.setDropdown();
...
@@ -130,7 +132,6 @@
...
@@ -130,7 +132,6 @@
}
}
checkForEnter(e) {
checkForEnter(e) {
// Enter KeyCode
if (e.keyCode === 13) {
if (e.keyCode === 13) {
e.stopPropagation();
e.stopPropagation();
e.preventDefault();
e.preventDefault();
...
@@ -143,7 +144,6 @@
...
@@ -143,7 +144,6 @@
}
}
search() {
search() {
console.log('search');
let path = '?scope=all&utf8=✓';
let path = '?scope=all&utf8=✓';
// Check current state
// Check current state
...
@@ -152,9 +152,10 @@
...
@@ -152,9 +152,10 @@
const defaultState = 'opened';
const defaultState = 'opened';
let currentState = defaultState;
let currentState = defaultState;
const { tokens, searchToken } = this.tokenizer.processTokens(
document.querySelector('.filtered-search')
.value);
const { tokens, searchToken } = this.tokenizer.processTokens(
this.filteredSearchInput
.value);
if (stateIndex !== -1) {
if (stateIndex !== -1) {
// TODO: Add comment here
const remaining = currentPath.slice(stateIndex + 6);
const remaining = currentPath.slice(stateIndex + 6);
const separatorIndex = remaining.indexOf('&');
const separatorIndex = remaining.indexOf('&');
...
...
app/assets/javascripts/filtered_search/filtered_search_tokenizer.es6
View file @
5589ab1e
/* eslint-disable no-param-reassign */
/* eslint-disable no-param-reassign */
((global) => {
((global) => {
class FilteredSearchTokenizer {
class FilteredSearchTokenizer {
// TODO: Remove when going to pro
static printTokens(tokens, searchToken, lastToken) {
console.log('tokens:');
tokens.forEach(token => console.log(token));
console.log(`search: ${searchToken}`);
console.log('last token:');
console.log(lastToken);
}
static parseToken(input) {
static parseToken(input) {
const colonIndex = input.indexOf(':');
const colonIndex = input.indexOf(':');
let tokenKey;
let tokenKey;
...
@@ -163,9 +154,6 @@
...
@@ -163,9 +154,6 @@
searchToken = searchTerms.trim();
searchToken = searchTerms.trim();
// TODO: Remove when going to PRO
gl.FilteredSearchTokenizer.printTokens(tokens, searchToken, lastToken);
return {
return {
tokens,
tokens,
searchToken,
searchToken,
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment