1/* DOKUWIKI:include_once script/select2/select2.js */
2/* DOKUWIKI:include_once script/select2/select2_locale_de.js */
3/* DOKUWIKI:include_once script/jquery.history.js */
4/**
5 * DokuWiki Plugin tagfilter (JavaScript Component)
6 *
7 * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
8 * @author  lisps
9 */
10var tagfilter_container = {};
11function getSelectByFormId(id){
12	return jQuery('select.tagdd_select_'+id);
13}
14
15function tagfilter_cleanform(id,refresh){
16	//elements = getElementsByClass('tagdd_select',document.getElementById('tagdd_'+id),'select');
17	const $elements = getSelectByFormId(id);
18	$elements.val('');
19	if(refresh) $elements[0].onchange();
20}
21
22function tagfilter_submit(id,ns,flags)
23{
24	var form = new Array();
25	var pagesearch= new Array();
26	var $elements = getSelectByFormId(id);
27
28
29	var tags = jQuery('#tagdd_'+id).data('tags');
30
31	jQuery.each(tags,function(index,select_r) {
32		jQuery.each(select_r,function(index2,page_r){
33			tags[index][index2] = jQuery.map(page_r,function(value){
34				return [value];
35			});
36		});
37	});
38
39	count = 0;
40	for(var i=0;i<$elements.length;i++){
41		e = $elements[i];
42		//if(e.selectedIndex != -1)
43			form[i] = new Array();
44		for(var k=0;k<e.options.length;k++){
45			if(e.options[k].selected && e.options[k].value != ''){
46				if(e.id == '__tagfilter_page_'+id) {
47					pagesearch.push(e.options[k].value);
48				}
49				else {
50					form[i].push(e.options[k].value);
51					count++;
52				}
53			}
54		}
55	}
56
57	if(flags[1]['pagesearch'] == true) { //delete pagesearch element
58		form.shift();
59	}
60
61	var pages = new Array();
62	var page_idx = 0;
63
64	jQuery.each(form,function(index,select) { //loop through select boxes and collect the pages
65		if(jQuery.isArray(select) && select.length) {
66			pages[page_idx] = new Array();
67			jQuery.each(select,function(index2,tag) {
68				pages[page_idx] = jQuery.merge(pages[page_idx],tags[index][tag]);
69			});
70			pages[page_idx] = jQuery.unique(pages[page_idx]);
71			page_idx++;
72		}
73	});
74
75	if(flags[1]['tagintersect'] == true) {
76		// Tags intersection
77		page_idx = 0;
78		jQuery.each(form,function(index,select) { //loop through select boxes and collect the pages
79			if(jQuery.isArray(select) && select.length) {
80				jQuery.each(select,function(index2,tag) {
81					pages[page_idx] = pages[page_idx].filter(function(n) {
82						return tags[index][tag].indexOf(n) !== -1;
83					});
84				});
85				page_idx++;
86			}
87		});
88	}
89
90
91	let pages_filtered = pages.length == 0 ? [] : pages.reduce(
92		(accumulator, currentValue) => accumulator.filter(elt => currentValue.includes(elt))
93	);
94
95	if (pagesearch.length != 0) {
96		if(page_idx == 0) {
97			pages_filtered = pagesearch;
98		} else { //intersect pagesearch
99			pages_filtered = pages_filtered.filter(elt => pagesearch.includes(elt));
100		}
101	}
102
103	const presentAll = pagesearch.length == 0 && page_idx == 0 && !flags[1]['noneonclear'];
104
105	//loop all found searchentries
106	/*
107	 * Handle all pagelist styles,
108	 * cf. https://github.com/dokufreaks/plugin-pagelist/blob/e48b7725cf940d21381ef32851bf82aa6736ee9c/helper.php#L334
109         * standard:   div.table > table.pagelist.plgn__pglist"
110	 * table:      div.table > table.inline.plgn__pglist"
111         * list:       div.table > table.ul.plgn__pglist"
112	 * simplelist: ul > li
113	 *
114	 * Handle include plugin style: div.plugin_include_content
115	 */
116	document
117		.querySelectorAll(`
118			#tagfilter_ergebnis_${id}.tagfilter > div.table > table.plgn__pglist > tbody > tr,
119			#tagfilter_ergebnis_${id}.tagfilter > ul > li,
120			#tagfilter_ergebnis_${id}.tagfilter > div.plugin_include_content
121		`)
122		.forEach(elt => {
123			let pageId;
124			switch(elt.nodeName) {
125				case 'DIV': // handling for include plugin
126					const prefix = 'plugin_include__';
127					pageId = Array.from(elt.classList)
128						.filter(a => a.startsWith(prefix))[0]
129						.substring(prefix.length);
130					break;
131				case 'TR': // handling for pagelist plugin, style=table
132				case 'LI': // handling for pagelist plugin, style=simplelist
133					pageId = elt.querySelector('a')?.title;
134					break;
135				default:
136					throw new Error('Unexpected element:' + elt.nodeName);
137			}
138
139			elt.style.display = (presentAll || pages_filtered.includes(pageId)) ? '' : 'none';
140		});
141
142
143	if(flags[1]['count']) {
144		if(jQuery('#tagfilter_ergebnis_'+id+' tr > td[class=page]').length > 0) {
145			jQuery('#__tagfilter_'+id).find('.tagfilter_count_number').text(
146					jQuery('#tagfilter_ergebnis_'+id+' tr:visible > td[class=page]').length + ' / ' +
147
148					jQuery('#tagfilter_ergebnis_'+id+' tr > td[class=page]').length);
149		} else {
150			jQuery('#__tagfilter_'+id).find('.tagfilter_count_number').text(
151					jQuery('#tagfilter_ergebnis_'+id+'.tagfilter li:visible').length + ' / ' +
152
153					jQuery('#tagfilter_ergebnis_'+id+'.tagfilter li').length);
154		}
155	}
156}
157
158jQuery().ready(function(){
159	var clean_r = [];
160	if(JSINFO['tagfilter']){
161		jQuery(JSINFO['tagfilter']).each(function(k,tf_elmt){
162			var $tf_dd = jQuery('#tagdd_'+tf_elmt.key +' [data-label="'+tf_elmt.label+'"]');
163
164			if($tf_dd){
165				if(jQuery.inArray(tf_elmt.key,clean_r) === -1){
166					tagfilter_cleanform(tf_elmt.key,false);
167					clean_r.push(tf_elmt.key);
168				}
169				$tf_dd.val(tf_elmt.values);
170			}
171		});
172	} else if (History.getState().data.tagfilter) { //Fix for IE9
173		var params = History.getState().data.tagfilter;
174
175		jQuery(params).each(function(k,tf_elmt){
176			var $tf_dd = jQuery('#tagdd_'+tf_elmt.key +' [data-label="'+tf_elmt.label+'"]');
177			if($tf_dd){
178				if(jQuery.inArray(tf_elmt.key,clean_r) === -1){
179					tagfilter_cleanform(tf_elmt.key,false);
180					clean_r.push(tf_elmt.key);
181				}
182
183				if($tf_dd.val()){
184					var val_tmp = $tf_dd.val();
185					if(!jQuery.isArray(val_tmp)) val_tmp = new Array(val_tmp);
186					val_tmp.push(tf_elmt.value);
187					$tf_dd.val(val_tmp);
188				}
189				else
190					$tf_dd.val(tf_elmt.value);
191			}
192		});
193	}
194
195	jQuery('form[data-plugin=tagfilter]').each(function(i,v){
196		jQuery(v).find('select')[0].onchange();
197	});
198
199	jQuery('form[data-plugin=tagfilter]').each(function(i,v){
200		jQuery(v).find('select.chosen').select2({
201			width:'200',
202			allowClear: true,
203			dropdownAutoWidth:true,
204			formatResult:tagfilter_selectFormatSelection,
205			formatSelection:tagfilter_selectFormatSelection
206		});
207	});
208
209	//console.log(jQuery('fieldset'));
210	/**
211	 * put the selected tags into the url for later use (browser history)
212	 *
213	 */
214	jQuery(window).on('beforeunload',function(e){
215		var $tagfilter_r = jQuery('form[data-plugin="tagfilter"]');
216		//tagfilter found?
217		if($tagfilter_r.length){
218			var tf_params = [];
219			var tf_object = [];
220			$tagfilter_r.each(function(i,tagfilter){
221				var $tagfilter = jQuery(tagfilter);
222				//search for each dropdown field inside a tagfilter
223				$tagfilter.find('select').each(function(i,dd){
224					var $dd = jQuery(dd);
225					var value = $dd.val();
226					var type = jQuery.type(value);
227					if(!value)return;
228
229					//add selected fields to tf_params
230					if(type === 'string') {
231						tf_params.push(encodeURIComponent('tf' + $tagfilter.attr('data-idx')+'_'+$dd.attr('data-label'))+'[]='+encodeURIComponent(value));
232						tf_object.push({'key':$tagfilter.attr('data-idx'),'label':$dd.attr('data-label'),'value':value});
233					}
234					if(type === 'array') {
235						jQuery(value).each(function(i,v){
236							tf_params.push(encodeURIComponent('tf' + $tagfilter.attr('data-idx')+'_'+$dd.attr('data-label'))+'[]='+encodeURIComponent(v));
237							tf_object.push({'key':$tagfilter.attr('data-idx'),'label':$dd.attr('data-label'),'value':v});
238						});
239					}
240				});
241
242			});
243
244			var state = History.getState();
245
246			var url = state.url.split('?');
247			if(url[1])
248				var url_params = url[1].split('&');
249			else
250				var url_params = [];
251
252			var old_params = [];
253			jQuery(url_params).each(function(k,v){
254				if(tagfilter_strpos(v,'tf',0) !== 0) //hack but should almost work ;)
255					old_params.push(v);
256			});
257
258			old_params = old_params.concat(tf_params);
259			//console.log(old_params.join('&'));
260			//console.log(History.getState())
261
262			History.replaceState({'tagfilter':tf_object},'tagfilter',url[0] + '?' + old_params.join('&'));
263		}
264	});
265
266});
267/**
268 * copied from http://phpjs.org/functions/strpos/
269 */
270function tagfilter_strpos (haystack, needle, offset) {
271  // http://kevin.vanzonneveld.net
272  // +   original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
273  // +   improved by: Onno Marsman
274  // +   bugfixed by: Daniel Esteban
275  // +   improved by: Brett Zamir (http://brett-zamir.me)
276  // *     example 1: strpos('Kevin van Zonneveld', 'e', 5);
277  // *     returns 1: 14
278  var i = (haystack + '').indexOf(needle, (offset || 0));
279  return i === -1 ? false : i;
280}
281
282function tagfilter_selectFormatResult(val) {
283	//console.log('tagfilter_selectFormatResult',val);
284	return (val.text);
285	/*
286	if(!(value in '.$jsVar.')) {return "";}
287	return [
288		('.$jsVar.'[value]["link"] == false) ? "":
289			"<span style=\'float:right;height:100%;vertical-align:center;padding-top:3px;\'>"+
290				"<img style=\'height:'.($flags['multi']?'32px':'32px').'\' src=\'"+'.$jsVar.'[value]["link"]+"\'>"+
291			"</span>",
292			"<span>"+text+"</span>",
293		('.$jsVar.'[value]["link"] == false) ? "":"<div style=\'clear:both;\'></div>"
294	].join("");
295	}*/
296}
297function tagfilter_selectFormatSelection(val) {
298	//console.log('tagfilter_selectFormatSelection',val);
299	var $select = jQuery(val.element).parent();
300	var tagimage = $select.data('tagimage');
301	var tagtext = "<span>"+val.text+"</span>";
302
303	if(!tagimage) return tagtext;
304	var tagimage_link = tagfilter_container[tagimage][val.id]['link'];
305	if(tagimage && tagimage_link) {
306		return [
307			"<span style=\'float:right;height:100%;vertical-align:center;padding-top:3px;\'>"+
308				"<img style='height:32px' src='"+tagimage_link+"'></span>",
309			"<span>"+val.text+"</span>",
310			"<div style=\'clear:both;\'></div>"
311			].join("");
312	} else {
313		return tagtext;
314	}
315
316}
317
318jQuery(function(){
319	jQuery('div.plugin_tagcompare form[data-plugin=tagcompare]').each(function(i,v){
320		jQuery(v).find('select').select2({
321			width:'200',
322			allowClear: true,
323			dropdownAutoWidth:true,
324			placeholder: "",
325
326		}).on('change', function(){
327			this.form.submit();
328//			$form = jQuery(this.form);
329//
330//			jQuery.ajay({
331//				//url:$form.attr('')
332//				data:
333//			});
334		});
335	});
336});
337
338