Completed
Push — master ( 54ca05...ad390e )
by Maxence
02:47
created

nav.onEntrySelected   A

Complexity

Conditions 1
Paths 2

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
c 0
b 0
f 0
nc 2
nop 2
dl 0
loc 4
rs 10
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: api */
28
/** global: search */
29
/** global: result */
30
/** global: settings */
31
32
33
34
var curr = {
35
	providerResult: [],
36
	page: 1,
37
	lastRequest: '',
38
	lastRequestTimer: null,
39
	lastSearchTimer: null,
40
41
	setProviderResult: function (id, value) {
42
		curr.providerResult[id] = value;
43
	},
44
45
	getProviderResult: function (id) {
46
		var current = curr.providerResult[id];
47
		if (!current) {
48
			current = [];
49
		}
50
51
		return current;
52
	}
53
54
};
55
56
57
var nav = {
58
		manageDivProviderNavigation: function (divProviderNavigation, request, meta) {
59
60
			var maxPage = Math.ceil(meta.total / request.size);
61
62
			divProviderNavigation.attr('data-time', meta.time);
63
			divProviderNavigation.attr('data-page', request.page);
64
			divProviderNavigation.attr('data-options', JSON.stringify(request.options));
65
			divProviderNavigation.attr('data-search', request.search);
66
			divProviderNavigation.attr('data-max-page', maxPage);
67
			divProviderNavigation.attr('data-size', request.size);
68
			divProviderNavigation.attr('data-total', meta.total);
69
70
			var providerTitle = divProviderNavigation.attr('data-provider-title');
71
			var left = "the search in " + providerTitle + " for '" + request.search + "' returned " +
72
				meta.total + " results in " + meta.time + "ms";
73
			divProviderNavigation.find('.provider_navigation_left').text(left);
74
75
			if (maxPage > 1) {
76
				divProviderNavigation.find('.provider_navigation_curr').text(request.page + ' / ' +
77
					maxPage).stop().fadeTo(200, 1);
78
79
				divProviderNavigation.find('.provider_navigation_prev').stop().fadeTo(200,
80
					(request.page > 1) ? 1 : 0);
81
				divProviderNavigation.find('.provider_navigation_next').stop().fadeTo(200,
82
					(request.page < maxPage) ? 1 : 0);
83
			} else {
84
				divProviderNavigation.find('.provider_navigation_prev').stop().fadeTo(200, 0);
85
				divProviderNavigation.find('.provider_navigation_curr').stop().fadeTo(200, 0);
86
				divProviderNavigation.find('.provider_navigation_next').stop().fadeTo(200, 0);
87
			}
88
		},
89
90
91
		manageDivProviderResult: function (divProviderResult, newResult, oldResult) {
92
			//replaceWith();
93
			nav.divProviderResultAddItems(divProviderResult, newResult, oldResult);
94
			if (oldResult) {
95
				nav.divProviderResultRemoveItems(divProviderResult, newResult, oldResult);
96
				nav.divProviderResultMoveItems(divProviderResult, newResult, oldResult);
97
			}
98
		},
99
100
101
		divProviderResultAddItems: function (divProviderResult, newResult, oldResult) {
102
103
			var precItem = null;
104
			for (var i = 0; i < newResult.length; i++) {
105
				var entry = newResult[i];
106
				if (result.getResultIndex(entry.id, oldResult) > -1) {
107
					precItem = nav.getDivEntry(entry.id, divProviderResult);
108
					nav.fillDivEntry(precItem, entry);
109
					continue;
110
				}
111
112
				var divResult = nav.generateDivEntry(entry, nav.generateTemplateEntry(entry));
113
				if (precItem === null) {
114
					divProviderResult.prepend(divResult);
115
				} else {
116
					precItem.after(divResult);
117
				}
118
119
				divResult.slideDown(settings.delay_result, function () {
0 ignored issues
show
Bug introduced by
It is generally not recommended to make functions within a loop.

While making functions in a loop will not lead to any runtime error, the code might not behave as you expect as the variables in the scope are not imported by value, but by reference. Let’s take a look at an example:

var funcs = [];
for (var i=0; i<10; i++) {
    funcs.push(function() {
        alert(i);
    });
}

funcs[0](); // alert(10);
funcs[1](); // alert(10);
/// ...
funcs[9](); // alert(10);

If you would instead like to bind the function inside the loop to the value of the variable during that specific iteration, you can create the function from another function:

var createFunc = function(i) {
    return function() {
        alert(i);
    };
};

var funcs = [];
for (var i=0; i<10; i++) {
    funcs.push(createFunc(i));
}

funcs[0](); // alert(0)
funcs[1](); // alert(1)
// ...
funcs[9](); // alert(9)
Loading history...
120
					$(this).children('.result_template').fadeTo(settings.delay_result, 1);
121
				});
122
123
				precItem = divResult;
124
			}
125
126
		},
127
128
129
		divProviderResultRemoveItems: function (divProviderResult, newResult, oldResult) {
130
			for (var i = 0; i < oldResult.length; i++) {
131
				var entry = oldResult[i];
132
				if (result.getResultIndex(entry.id, newResult) === -1) {
133
					var divResult = nav.getDivEntry(entry.id, divProviderResult);
134
					divResult.fadeTo(settings.delay_result, 0, function () {
0 ignored issues
show
Bug introduced by
It is generally not recommended to make functions within a loop.

While making functions in a loop will not lead to any runtime error, the code might not behave as you expect as the variables in the scope are not imported by value, but by reference. Let’s take a look at an example:

var funcs = [];
for (var i=0; i<10; i++) {
    funcs.push(function() {
        alert(i);
    });
}

funcs[0](); // alert(10);
funcs[1](); // alert(10);
/// ...
funcs[9](); // alert(10);

If you would instead like to bind the function inside the loop to the value of the variable during that specific iteration, you can create the function from another function:

var createFunc = function(i) {
    return function() {
        alert(i);
    };
};

var funcs = [];
for (var i=0; i<10; i++) {
    funcs.push(createFunc(i));
}

funcs[0](); // alert(0)
funcs[1](); // alert(1)
// ...
funcs[9](); // alert(9)
Loading history...
135
						$(this).slideUp(settings.delay_result, function () {
136
							$(this).remove();
137
						});
138
					});
139
				}
140
			}
141
		},
142
143
144
		divProviderResultMoveItems: function (divProviderResult, newResult, oldResult) {
145
146
			var precId = '';
147
148
			oldResult = result.recalibrateResult(oldResult, newResult);
149
			newResult = result.recalibrateResult(newResult, oldResult);
150
			for (var i = 0; i < newResult.length; i++) {
151
				var entry = newResult[i];
152
153
				var pos = result.getResultIndex(entry.id, oldResult);
154
				if (pos > -1 && pos !== i) {
155
					nav.animateMoveDivResult(entry.id, divProviderResult, precId);
156
				}
157
158
				precId = newResult[i].id;
159
			}
160
		},
161
162
163
		animateMoveDivResult: function (entryId, divProviderResult, precId) {
164
165
			var divResult = nav.getDivEntry(entryId, divProviderResult);
166
167
			if (precId === '') {
168
				divResult.fadeTo(settings.delay_result, 0.35, function () {
169
					$(this).prependTo(divProviderResult).fadeTo(100, 1);
170
				});
171
			} else {
172
				var precItem = nav.getDivEntry(precId, divProviderResult);
173
				divResult.fadeTo(settings.delay_result, 0.35, function () {
174
					$(this).insertAfter(precItem).fadeTo(100, 1);
175
				});
176
			}
177
178
		},
179
180
181
		getDivProvider: function (providerId, providerName) {
182
			var ret = null;
183
			settings.resultContainer.children('.provider_header').each(function () {
184
				if ($(this).attr('data-id') === providerId) {
185
					ret = $(this);
186
				}
187
			});
188
189
			if (ret === null) {
190
				ret = nav.generateDivProvider(providerId, providerName);
191
				settings.resultContainer.append(ret);
192
			}
193
194
			return ret;
195
		},
196
197
198
		getDivEntry: function (resultId, divProviderResult) {
199
			var ret = null;
200
201
			divProviderResult.children('.result_entry').each(function () {
202
				if ($(this).attr('data-id') === resultId) {
203
					ret = $(this);
204
				}
205
			});
206
207
			return ret;
208
		},
209
210
211
		fillDivEntry: function (divEntry, entry) {
212
			divEntry.find('#title').text(entry.title);
213
214
			divEntry.find('#info').text('');
215
			if (settings.options.show_hash === '1') {
216
				divEntry.find('#info').text(entry.hash);
217
			}
218
219
			nav.fillDivResultExcepts(divEntry, entry);
220
221
			if (entry.link !== '') {
222
				divEntry.off('click').on('click', function (event) {
223
					if (nav.onEntrySelected($(this), event)) {
224
						return;
225
					}
226
227
					window.open(entry.link);
228
				});
229
				divEntry.find('div').each(function () {
230
					$(this).css('cursor', 'pointer');
231
				});
232
			}
233
234
			nav.onEntryGenerated(divEntry, entry);
235
		},
236
237
238
		/**
239
		 * @namespace entry.excerpts
240
		 */
241
		fillDivResultExcepts: function (divResult, entry) {
242
			if (entry.excerpts === null) {
243
				return;
244
			}
245
246
			if (entry.excerpts.length > 0) {
247
				divResult.find('#extract').text(entry.excerpts[0]);
248
			} else {
249
				divResult.find('#extract').text('');
250
			}
251
		},
252
253
254
		onEntryGenerated: function (divEntry, entry) {
255
			if (settings.parentHasMethod('onEntryGenerated')) {
256
				settings.parent.onEntryGenerated(divEntry, entry);
257
			}
258
		},
259
260
261
		onEntrySelected: function (divEntry, event) {
262
			return !!(settings.parentHasMethod('onEntrySelected') &&
263
				settings.parent.onEntrySelected(divEntry, event));
264
		},
265
266
267
		onSearchRequest: function (data) {
268
			if (settings.parentHasMethod('onSearchRequest')) {
269
				settings.parent.onSearchRequest(data);
270
			}
271
		},
272
273
274
		onSearchReset: function () {
275
			if (settings.parentHasMethod('onSearchReset')) {
276
				settings.parent.onSearchReset();
277
			}
278
		},
279
280
281
		onResultDisplayed: function (data) {
282
			if (settings.parentHasMethod('onResultDisplayed')) {
283
				settings.parent.onResultDisplayed(data);
284
			}
285
		},
286
287
		onResultClose: function () {
288
			if (settings.parentHasMethod('onResultClose')) {
289
				settings.parent.onResultClose();
290
			}
291
		},
292
293
		onError: function (data) {
294
			if (settings.parentHasMethod('onError')) {
295
				settings.parent.onError(data);
296
			}
297
		},
298
299
		// deleteEmptyDiv: function (entry, divId) {
300
		// 	var div = entry.find(divId);
301
		// 	if (div.text() === '') {
302
		// 		div.remove();
303
		// 	}
304
		// },
305
306
307
		generateTemplateEntry: function () {
308
			var divTemplate = settings.entryTemplate;
309
			if (divTemplate === null) {
310
				divTemplate = settings.generateDefaultTemplate();
311
			}
312
313
			if (!divTemplate.length) {
314
				console.log('FullTextSearch Error: entryTemplate is not defined');
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...
315
				return;
316
			}
317
318
			var tmpl = divTemplate.html();
319
			// var divNavToggle = $('<div>', {
320
			// 	id: 'app-navigation-toggle',
321
			// 	class: 'icon-menu'
322
			// });
323
			//
324
			var div = $('<div>', {class: 'result_template'});
325
			div.html(tmpl).fadeTo(0);
326
327
			return div;
328
		},
329
330
331
		generateDivEntry: function (entry, divResultContent) {
332
			var divEntry = $('<div>', {class: 'result_entry'});
333
334
			divEntry.hide();
335
			divEntry.attr('data-id', entry.id);
336
			divEntry.attr('data-link', entry.link);
337
			divEntry.attr('data-source', entry.source);
338
			divEntry.attr('data-info', JSON.stringify(entry.info));
339
			divEntry.attr('data-result', JSON.stringify(entry));
340
			divEntry.append(divResultContent);
341
342
			nav.fillDivEntry(divEntry, entry);
343
344
			return divEntry;
345
		},
346
347
348
		generateDivProvider: function (providerId, providerName) {
349
350
			var divProviderNavigation = $('<div>', {class: 'provider_navigation'});
351
			divProviderNavigation.attr('data-provider-id', providerId);
352
			divProviderNavigation.attr('data-provider-title', providerName);
353
354
			var divProviderLeftNav = $('<div>', {class: 'provider_navigation_left'});
355
			if (settings.searchProviderId !== '') {
356
				console.log('--- !!');
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...
357
				var divProviderPaginationClose = $('<div>',
358
					{class: 'icon-close provider_navigation_close'});
359
				divProviderPaginationClose.on('click', function () {
360
					nav.onResultClose();
361
				});
362
				divProviderNavigation.append(divProviderPaginationClose);
363
			}
364
365
			divProviderNavigation.append(divProviderLeftNav);
366
367
368
			var divProviderPagination = $('<div>', {class: 'provider_navigation_right'});
369
			var divProviderPaginationPrev = $('<div>', {class: 'provider_navigation_prev'}).append(
370
				$('<div>', {class: 'provider_navigation_page'}).text('previous page'));
371
372
			divProviderPaginationPrev.on('click', function () {
373
				var prevPage = Number(divProviderNavigation.attr('data-page')) - 1;
374
				if (prevPage < 1) {
375
					return;
376
				}
377
378
				fullTextSearch.search({
0 ignored issues
show
Bug introduced by
The variable fullTextSearch seems to be never declared. If this is a global, consider adding a /** global: fullTextSearch */ 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...
379
					providers: providerId,
380
					options: JSON.parse(divProviderNavigation.attr('data-options')),
381
					search: divProviderNavigation.attr('data-search'),
382
					page: prevPage,
383
					size: divProviderNavigation.attr('data-size')
384
				});
385
			});
386
			divProviderPagination.append(divProviderPaginationPrev);
387
388
			divProviderPagination.append($('<div>', {class: 'provider_navigation_curr'}));
389
390
			var divProviderPaginationNext = $('<div>',
391
				{class: 'provider_navigation_next'}).append(
392
				$('<div>', {class: 'provider_navigation_page'}).text('next page'));
393
394
			divProviderPaginationNext.on('click', function () {
395
				var nextPage = Number(divProviderNavigation.attr('data-page')) + 1;
396
				if (nextPage > Number(divProviderNavigation.attr('data-max-page'))) {
397
					return;
398
				}
399
400
				fullTextSearch.search({
0 ignored issues
show
Bug introduced by
The variable fullTextSearch seems to be never declared. If this is a global, consider adding a /** global: fullTextSearch */ 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...
401
					providers: providerId,
402
					options: JSON.parse(divProviderNavigation.attr('data-options')),
403
					search: divProviderNavigation.attr('data-search'),
404
					page: nextPage,
405
					size: divProviderNavigation.attr('data-size')
406
				});
407
			});
408
			divProviderPagination.append(divProviderPaginationNext);
409
410
			divProviderNavigation.append(divProviderPagination);
411
412
			var divProviderResult = $('<div>', {class: 'provider_result'});
413
414
			var divProvider = $('<div>', {class: 'provider_header'});
415
			divProvider.hide();
416
			divProvider.attr('data-id', providerId);
417
			divProvider.append(divProviderNavigation);
418
419
			if (settings.resultHeader !== null) {
420
				divProvider.append(settings.resultHeader);
421
			}
422
423
			divProvider.append(divProviderResult);
424
425
			if (settings.resultFooter !== null) {
426
				divProvider.append(settings.resultFooter);
427
			}
428
429
			return divProvider;
430
		}
431
432
	}
433
;
434