Commit 5589ab1e authored by Clement Ho's avatar Clement Ho

Refactor and add comments

parent 2bbc44cb
...@@ -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();
} }
} }
......
...@@ -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();
} }
} }
......
...@@ -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();
} }
} }
......
...@@ -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.listId}`); this.input.setAttribute(DATA_DROPDOWN_TRIGGER, `#${this.dropdown.id}`);
} }
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.listId) { } else if(currentHook.list.list.id !== this.dropdown.id) {
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);
} }
} }
......
...@@ -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 filteredSearchInput = document.querySelector('.filtered-search') const input = document.querySelector('.filtered-search')
const filteredSearchValue = filteredSearchInput.value; const value = input.value;
const hasExistingValue = filteredSearchValue.length !== 0; const hasExistingValue = value.length !== 0;
const { lastToken } = gl.FilteredSearchTokenizer.processTokens(filteredSearchValue); const { lastToken } = gl.FilteredSearchTokenizer.processTokens(value);
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 = filteredSearchValue.slice(0, -1 * (lengthToRemove)); input.value = value.slice(0, -1 * (lengthToRemove));
} }
filteredSearchInput.value += hasExistingValue && addSpace ? ` ${word}` : word; input.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');
......
/* 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('&');
......
/* 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,
......
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