Completed
Push — master ( 3b0b80...701bf9 )
by Maxence
04:54
created

searchbox.timedSearch   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 17

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 17
rs 9.4285
cc 3
nc 4
nop 0

1 Function

Rating   Name   Duplication   Size   Complexity  
A 0 3 1
1
/*
2
 * FullTextSearch - Full text search framework for Nextcloud
3
 *
4
 * This file is licensed under the Affero General Public License version 3 or
5
 * later. See the COPYING file.
6
 *
7
 * @author Maxence Lange <[email protected]>
8
 * @copyright 2018
9
 * @license GNU AGPL version 3 or any later version
10
 *
11
 * This program is free software: you can redistribute it and/or modify
12
 * it under the terms of the GNU Affero General Public License as
13
 * published by the Free Software Foundation, either version 3 of the
14
 * License, or (at your option) any later version.
15
 *
16
 * This program is distributed in the hope that it will be useful,
17
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19
 * GNU Affero General Public License for more details.
20
 *
21
 * You should have received a copy of the GNU Affero General Public License
22
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
23
 *
24
 */
25
26
/** global: OCA */
27
/** global: nav */
28
/** global: _ */
29
/** global: api */
30
/** global: search */
31
/** global: result */
32
/** global: fullTextSearch */
33
/** global: settings */
34
35
36
var box_elements = {
37
	searchInput: null,
38
	searchOptions: null,
39
	searchTemplate: null,
40
	searchError: null,
41
	divFullTextSearchIcon: null,
42
	divFullTextSearchPopup: null
43
};
44
45
46
var searchbox = {
47
48
	init: function () {
49
50
		var self = this;
0 ignored issues
show
Unused Code introduced by
The variable self seems to be never used. Consider removing it.
Loading history...
51
52
		// we remove old search
53
		var search_form = $('FORM.searchbox');
54
		if (search_form.length > 0) {
55
			search_form.remove();
56
		}
57
58
59
		var divHeaderRight = $('DIV.header-right');
60
		var divFullTextSearch = $('<div>', {id: 'fulltextsearch'});
61
		divHeaderRight.prepend(divFullTextSearch);
62
63
		box_elements.divFullTextSearchIcon = searchbox.generateFullTextSearchIcon();
64
		box_elements.divFullTextSearchPopup = searchbox.generateFullTextSearchPopup();
65
		divFullTextSearch.append(box_elements.divFullTextSearchIcon);
66
		divFullTextSearch.append(box_elements.divFullTextSearchPopup);
67
68
		OC.registerMenu(box_elements.divFullTextSearchIcon, box_elements.divFullTextSearchPopup,
0 ignored issues
show
Bug introduced by
The variable OC seems to be never declared. If this is a global, consider adding a /** global: OC */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
69
			searchbox.displayedSearchPopup);
70
71
		api.retrieveOptions(settings.searchProviderId);
72
73
		$(window).bind('keydown', function (event) {
74
			if (event.ctrlKey || event.metaKey) {
75
				if (String.fromCharCode(event.which).toLowerCase() === 'f') {
76
					event.preventDefault();
77
					searchbox.displaySearchPopup(true);
78
				}
79
80
				return;
81
			}
82
83
			if (event.which === 27) {
84
				searchbox.displaySearchPopup(false);
85
			}
86
		});
87
88
	},
89
90
91
	generateFullTextSearchIcon: function () {
92
		var className = 'icon-fulltextsearch';
93
		if (OCA.Theming === undefined || !OCA.Theming.inverted) {
94
			className = 'icon-fulltextsearch-white';
95
		}
96
97
		var icon = $('<div>', {
98
			id: 'fts-icon',
99
			tabindex: 0,
100
			role: 'link',
101
			class: className + ' menutoggle'
102
		});
103
104
		icon.fadeTo(0, 0.6);
105
106
		return icon;
107
	},
108
109
110
	generateFullTextSearchPopup: function () {
111
		var popup = $('<div>', {
112
			id: 'fts-popup'
113
		});
114
115
		box_elements.searchInput = $('<input>', {
116
			id: 'fts-input',
117
			placeholder: 'Search ' + settings.searchProviderName
118
		}).on('keyup', searchbox.timedSearch);
119
		box_elements.searchOptions = $('<div>', {id: 'fts-options'});
120
		box_elements.searchTemplate = $('<div>', {id: 'fts-options-template'});
121
		box_elements.searchError = $('<div>', {id: 'fts-error'});
122
123
		var divHeader = $('<div>', {id: 'fts-header'});
124
		divHeader.append($('<div>').append(box_elements.searchInput));
125
126
		popup.append(divHeader);
127
		popup.append(box_elements.searchOptions);
128
		popup.append(box_elements.searchTemplate);
129
		popup.append(box_elements.searchError.hide());
130
131
		return popup;
132
	},
133
134
135
	displaySearchPopup: function (display) {
136
		if (display) {
137
			OC.showMenu(box_elements.divFullTextSearchIcon, box_elements.divFullTextSearchPopup,
0 ignored issues
show
Bug introduced by
The variable OC seems to be never declared. If this is a global, consider adding a /** global: OC */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
138
				searchbox.displayedSearchPopup);
139
		} else {
140
			OC.hideMenus(null);
141
		}
142
	},
143
144
145
	displayedSearchPopup: function () {
146
		box_elements.searchError.hide();
147
		box_elements.searchInput.focus();
148
	},
149
150
151
	searching: function () {
152
		if (curr.lastRequestTimer !== null) {
0 ignored issues
show
Bug introduced by
The variable curr seems to be never declared. If this is a global, consider adding a /** global: curr */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
153
			window.clearTimeout(curr.lastRequestTimer);
154
			curr.lastRequestTimer = null;
155
		}
156
157
		if (curr.lastSearchTimer !== null) {
158
			window.clearTimeout(curr.lastSearchTimer);
159
		}
160
161
		var search = box_elements.searchInput.val();
162
		if (search.length < 1) {
163
			return;
164
		}
165
166
		curr.lastRequest = search;
167
		api.search({
168
			providers: settings.searchProviderId,
169
			search: search,
170
			page: curr.page,
171
			options: searchbox.getSearchOptions(),
172
			size: 20
173
		});
174
	},
175
176
177
	timedSearch: function () {
178
179
		if (curr.lastSearchTimer !== null) {
0 ignored issues
show
Bug introduced by
The variable curr seems to be never declared. If this is a global, consider adding a /** global: curr */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
180
			window.clearTimeout(curr.lastSearchTimer);
181
		}
182
183
		curr.lastSearchTimer = window.setTimeout(function () {
184
			searchbox.searching();
185
		}, settings.searchEntryTimer);
186
187
		if (curr.lastRequestTimer === null) {
0 ignored issues
show
Bug introduced by
The variable curr seems to be never declared. If this is a global, consider adding a /** global: curr */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
188
			curr.lastRequestTimer = window.setTimeout(function () {
189
				console.log('lastRequestTimer');
0 ignored issues
show
Debugging Code introduced by
console.log looks like debug code. Are you sure you do not want to remove it?
Loading history...
190
				searchbox.searching();
191
			}, settings.searchRequestTimer);
192
		}
193
	},
194
195
	onOptionsLoaded: function (result) {
196
		if (!result[settings.searchProviderId]) {
197
			return;
198
		}
199
200
		if (result[settings.searchProviderId]['options']) {
0 ignored issues
show
Coding Style introduced by
['options'] could be written in dot notation.

You can rewrite this statement in dot notation:

var obj = { };
obj['foo'] = 'bar'; // Bad
obj.foo = 'bar'; // Good
Loading history...
201
			searchbox.generateOptionsHtml(result[settings.searchProviderId]['options']);
0 ignored issues
show
Coding Style introduced by
['options'] could be written in dot notation.

You can rewrite this statement in dot notation:

var obj = { };
obj['foo'] = 'bar'; // Bad
obj.foo = 'bar'; // Good
Loading history...
202
			box_elements.searchOptions.find('INPUT').each(function () {
203
				searchbox.eventOnOptionsLoadedInput($(this));
204
			});
205
		}
206
207
		if (result[settings.searchProviderId]['template']) {
0 ignored issues
show
Coding Style introduced by
['template'] could be written in dot notation.

You can rewrite this statement in dot notation:

var obj = { };
obj['foo'] = 'bar'; // Bad
obj.foo = 'bar'; // Good
Loading history...
208
			box_elements.searchTemplate.html(result[settings.searchProviderId]['template']);
0 ignored issues
show
Coding Style introduced by
['template'] could be written in dot notation.

You can rewrite this statement in dot notation:

var obj = { };
obj['foo'] = 'bar'; // Bad
obj.foo = 'bar'; // Good
Loading history...
209
			box_elements.searchTemplate.find('INPUT').each(function () {
210
				searchbox.eventOnOptionsLoadedInput($(this))
0 ignored issues
show
Coding Style introduced by
There should be a semicolon.

Requirement of semicolons purely is a coding style issue since JavaScript has specific rules about semicolons which are followed by all browsers.

Further Readings:

Loading history...
211
			});
212
		}
213
	},
214
215
216
	eventOnOptionsLoadedInput: function (div) {
217
		div.on('change keyup', function () {
218
			console.log('eventOnOptionsLoadedInput');
0 ignored issues
show
Debugging Code introduced by
console.log looks like debug code. Are you sure you do not want to remove it?
Loading history...
219
220
			searchbox.searching();
221
		});
222
	},
223
224
225
	generateOptionsHtml: function (options) {
226
		var div = $('<div>', {class: 'div-table'});
227
228
		for (var j = 0; j < options.length; j++) {
229
			var sub = options[j];
230
			searchbox.displayPanelCheckbox(div, sub);
231
			searchbox.displayPanelInput(div, sub);
232
		}
233
234
		box_elements.searchOptions.append(div);
235
	},
236
237
238
	displayPanelOptionTitle (sub) {
0 ignored issues
show
Backwards Compatibility introduced by
'concise methods' is available in ES6 (use 'esversion: 6') or Mozilla JS extensions (use moz).
Loading history...
239
		var subDiv = $('<div>', {
240
			class: 'div-table-row'
241
		});
242
243
		subDiv.append($('<div>',
244
			{
245
				class: 'div-table-col div-table-col-left'
246
			}).append($('<span>', {
247
			class: 'leftcol',
248
			text: sub.title
249
		})));
250
251
		subDiv.append($('<div>',
252
			{class: 'div-table-col div-table-col-right'}));
253
254
		return subDiv;
255
	},
256
257
258
	displayPanelCheckbox: function (div, sub) {
259
		if (sub.type !== 'checkbox') {
260
			return;
261
		}
262
263
		var subDiv = searchbox.displayPanelOptionTitle(sub);
264
		var subDivInput = $('<input>', {
265
			type: 'checkbox',
266
			id: sub.name,
267
			value: 1
268
		});
269
		subDiv.find('.div-table-col-right').append(subDivInput);
270
		div.append(subDiv);
271
	},
272
273
274
	displayPanelInput: function (div, sub) {
275
		if (sub.type !== 'input') {
276
			return;
277
		}
278
279
		var subDiv = searchbox.displayPanelOptionTitle(sub);
280
		var subDivInput = $('<input>', {
281
			class: 'fts_options_input fts_options_input_' + sub.size,
282
			type: 'text',
283
			placeholder: sub.placeholder,
284
			id: sub.name
285
		});
286
		subDiv.find('.div-table-col-right').append(subDivInput);
287
		div.append(subDiv);
288
	},
289
290
291
	getSearchOptions: function () {
292
		var options = {};
293
294
		if (box_elements.searchTemplate === null) {
295
			return options;
296
		}
297
298
		box_elements.searchOptions.find('INPUT').each(function () {
299
			searchbox.getSearchOptionsFromInput($(this), options);
300
		});
301
		box_elements.searchTemplate.find('INPUT').each(function () {
302
			searchbox.getSearchOptionsFromInput($(this), options);
303
		});
304
305
		return options;
306
	},
307
308
309
	getSearchOptionsFromInput: function (div, options) {
310
		var value = div.val();
311
312
		if (div.attr('type') === 'checkbox' && !div.is(':checked')) {
313
			value = '';
314
		}
315
316
		options[div.attr('id')] = value;
317
	}
318
319
320
};
321
322
323