Completed
Push — master ( 58d870...e50603 )
by
unknown
02:12
created

searchbox.init   A

Complexity

Conditions 5
Paths 4

Size

Total Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 14
rs 9.2333
cc 5
nc 4
nop 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
		var divHeaderRight = $('DIV.header-right');
59
		var divFullTextSearch = $('<div>', {id: 'fulltextsearch'});
60
		divHeaderRight.prepend(divFullTextSearch);
61
62
		box_elements.divFullTextSearchIcon = searchbox.generateFullTextSearchIcon();
63
		box_elements.divFullTextSearchPopup = searchbox.generateFullTextSearchPopup();
64
		divFullTextSearch.append(box_elements.divFullTextSearchIcon);
65
		divFullTextSearch.append(box_elements.divFullTextSearchPopup);
66
67
		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...
68
			searchbox.displayedSearchPopup);
69
70
		api.retrieveOptions(settings.searchProviderId);
71
72
		$(window).bind('keydown', function (event) {
73
			if (event.ctrlKey || event.metaKey) {
74
				if (String.fromCharCode(event.which).toLowerCase() === 'f') {
75
					event.preventDefault();
76
					searchbox.displaySearchPopup(true);
77
				}
78
79
				return;
80
			}
81
82
			if (event.which === 27) {
83
				searchbox.displaySearchPopup(false);
84
			}
85
		});
86
87
	},
88
89
90
	generateFullTextSearchIcon: function () {
91
		var className = 'icon-fulltextsearch';
92
		if (OCA.Theming === undefined || !OCA.Theming.inverted) {
93
			className = 'icon-fulltextsearch-white';
94
		}
95
96
		var icon = $('<div>', {
97
			id: 'fts-icon',
98
			tabindex: 0,
99
			role: 'link',
100
			class: className + ' menutoggle'
101
		});
102
103
		icon.fadeTo(0, 0.6);
104
105
		return icon;
106
	},
107
108
109
	generateFullTextSearchPopup: function () {
110
		var popup = $('<div>', {
111
			id: 'fts-popup'
112
		});
113
114
		box_elements.searchInput = $('<input>', {
115
			id: 'fts-input',
116
			placeholder: 'Search ' + settings.searchProviderName
117
		}).on('keyup', searchbox.timedSearch);
118
		box_elements.searchOptions = $('<div>', {id: 'fts-options'});
119
		box_elements.searchTemplate = $('<div>', {id: 'fts-options-template'});
120
		box_elements.searchError = $('<div>', {id: 'fts-error'});
121
122
		var divHeader = $('<div>', {id: 'fts-header'});
123
		divHeader.append($('<div>').append(box_elements.searchInput));
124
125
		popup.append(divHeader);
126
		popup.append(box_elements.searchOptions);
127
		popup.append(box_elements.searchTemplate);
128
		popup.append(box_elements.searchError.hide());
129
130
		return popup;
131
	},
132
133
134
	displaySearchPopup: function (display) {
135
		if (display) {
136
			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...
137
				searchbox.displayedSearchPopup);
138
		} else {
139
			OC.hideMenus(null);
140
		}
141
	},
142
143
144
	displayedSearchPopup: function () {
145
		box_elements.searchError.hide();
146
		box_elements.searchInput.focus();
147
	},
148
149
150
	searching: function () {
151
		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...
152
			window.clearTimeout(curr.lastRequestTimer);
153
			curr.lastRequestTimer = null;
154
		}
155
156
		if (curr.lastSearchTimer !== null) {
157
			window.clearTimeout(curr.lastSearchTimer);
158
		}
159
160
		var search = box_elements.searchInput.val();
161
		if (search.length < 1) {
162
			return;
163
		}
164
165
		curr.lastRequest = search;
166
		api.search({
167
			providers: settings.searchProviderId,
168
			search: search,
169
			page: curr.page,
170
			options: searchbox.getSearchOptions(),
171
			size: 20
172
		});
173
	},
174
175
176
	timedSearch: function () {
177
178
		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...
179
			window.clearTimeout(curr.lastSearchTimer);
180
		}
181
182
		curr.lastSearchTimer = window.setTimeout(function () {
183
			searchbox.searching();
184
		}, settings.searchEntryTimer);
185
186
		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...
187
			curr.lastRequestTimer = window.setTimeout(function () {
188
				searchbox.searching();
189
			}, settings.searchRequestTimer);
190
		}
191
	},
192
193
194
	onOptionsLoaded: function (result) {
195
		if (!result[settings.searchProviderId]) {
196
			return;
197
		}
198
199
		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...
200
			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...
201
			box_elements.searchOptions.find('INPUT').each(function () {
202
				searchbox.eventOnOptionsLoadedInput($(this));
203
			});
204
		}
205
206
		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...
207
			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...
208
			box_elements.searchTemplate.find('INPUT').each(function () {
209
				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...
210
			});
211
		}
212
	},
213
214
215
	eventOnOptionsLoadedInput: function (div) {
216
		div.on('change keyup', function () {
217
//			console.log('eventOnOptionsLoadedInput');
218
219
			searchbox.searching();
220
		});
221
	},
222
223
224
	generateOptionsHtml: function (options) {
225
		var div = $('<div>', {class: 'div-table'});
226
227
		for (var j = 0; j < options.length; j++) {
228
			var sub = options[j];
229
			searchbox.displayPanelCheckbox(div, sub);
230
			searchbox.displayPanelInput(div, sub);
231
		}
232
233
		box_elements.searchOptions.append(div);
234
	},
235
236
237
	displayPanelOptionTitle: function (sub) {
238
		var subDiv = $('<div>', {
239
			class: 'div-table-row'
240
		});
241
242
		subDiv.append($('<div>',
243
			{
244
				class: 'div-table-col div-table-col-left'
245
			}).append($('<span>', {
246
			class: 'leftcol',
247
			text: sub.title
248
		})));
249
250
		subDiv.append($('<div>',
251
			{class: 'div-table-col div-table-col-right'}));
252
253
		return subDiv;
254
	},
255
256
257
	displayPanelCheckbox: function (div, sub) {
258
		if (sub.type !== 'checkbox') {
259
			return;
260
		}
261
262
		var subDiv = searchbox.displayPanelOptionTitle(sub);
263
		var subDivInput = $('<input>', {
264
			type: 'checkbox',
265
			id: sub.name,
266
			value: 1
267
		});
268
		subDiv.find('.div-table-col-right').append(subDivInput);
269
		div.append(subDiv);
270
	},
271
272
273
	displayPanelInput: function (div, sub) {
274
		if (sub.type !== 'input') {
275
			return;
276
		}
277
278
		var subDiv = searchbox.displayPanelOptionTitle(sub);
279
		var subDivInput = $('<input>', {
280
			class: 'fts_options_input fts_options_input_' + sub.size,
281
			type: 'text',
282
			placeholder: sub.placeholder,
283
			id: sub.name
284
		});
285
		subDiv.find('.div-table-col-right').append(subDivInput);
286
		div.append(subDiv);
287
	},
288
289
290
	getSearchOptions: function () {
291
		var options = {};
292
293
		if (box_elements.searchTemplate === null) {
294
			return options;
295
		}
296
297
		box_elements.searchOptions.find('INPUT').each(function () {
298
			searchbox.getSearchOptionsFromInput($(this), options);
299
		});
300
		box_elements.searchTemplate.find('INPUT').each(function () {
301
			searchbox.getSearchOptionsFromInput($(this), options);
302
		});
303
304
		return options;
305
	},
306
307
308
	getSearchOptionsFromInput: function (div, options) {
309
		var value = div.val();
310
311
		if (div.attr('type') === 'checkbox' && !div.is(':checked')) {
312
			value = '';
313
		}
314
315
		options[div.attr('id')] = value;
316
	}
317
318
319
};
320
321
322