PageSourceSearch

http://kamenisty.ru/media/kunena/js/default.js

js kamenisty.ru collected 2026-10-08 16:47:19 UTC 29,388 bytes, 944 lines download raw bytes

1/**
2 * Kunena Component
3 * @package Kunena.Template.Blue_Eagle
4 *
5 * @copyright (C) 2008 - 2016 Kunena Team. All rights reserved.
6 * @license http://www.gnu.org/copyleft/gpl.html GNU/GPL
7 * @link https://www.kunena.org
8 **/
9
10/* Javascript file for default Kunena BlueEagle template */
11
12/* Tabs class */
13var KunenaTabs = new Class({
14	Implements: [Options, Events],
15
16	options: {
17		display            : 0,
18		onActive           : function(title, description) {
19			description.setStyle('display', 'block');
20			title.addClass('open').removeClass('closed');
21		},
22		onBackground       : function(title, description) {
23			description.setStyle('display', 'none');
24			title.addClass('closed').removeClass('open');
25		},
26		titleSelector      : 'dt',
27		descriptionSelector: 'dd'
28	},
29
30	initialize: function(dlist, options) {
31		this.setOptions(options);
32		this.dlist = document.id(dlist);
33		this.titles = this.dlist.getChildren(this.options.titleSelector);
34		this.descriptions = this.dlist.getChildren(this.options.descriptionSelector);
35		this.content = new Element('div').inject(this.dlist, 'after').addClass('current');
36
37		for (var i = 0, l = this.titles.length; i < l; i++) {
38			var title = this.titles[i];
39			var description = this.descriptions[i];
40			title.setStyle('cursor', 'pointer');
41			title.addEvent('click', this.display.bind(this, i));
42			description.inject(this.content);
43		}
44
45		if (this.options.display != null) this.display(this.options.display);
46
47		if (this.options.initialize) this.options.initialize.call(this);
48	},
49
50	hideAllBut: function(but) {
51		for (var i = 0, l = this.titles.length; i < l; i++) {
52			if (i != but) this.fireEvent('onBackground', [this.titles[i], this.descriptions[i]]);
53		}
54	},
55
56	display: function(i) {
57		this.hideAllBut(i);
58		this.fireEvent('onActive', [this.titles[i], this.descriptions[i]]);
59	}
60});
61
62//----------------- New Mootools extensions ---------------------------
63
64/**
65 * Autocompleter
66 *
67 * http://digitarald.de/project/autocompleter/
68 *
69 * @version        1.1.2
70 *
71 * @license        MIT-style license
72 * @author        Harald Kirschner <mail [at] digitarald.de>
73 * @copyright    Author
74 */
75
76var Autocompleter = new Class({
77
78	Implements: [Options, Events],
79
80	options: {
81		/*
82		 onOver: $empty,
83		 onSelect: $empty,
84		 onSelection: $empty,
85		 onShow: $empty,
86		 onHide: $empty,
87		 onBlur: $empty,
88		 onFocus: $empty,*/
89		minLength      : 1,
90		markQuery      : true,
91		width          : 'inherit',
92		maxChoices     : 10,
93		injectChoice   : null,
94		customChoices  : null,
95		emptyChoices   : null,
96		visibleChoices : true,
97		className      : 'autocompleter-choices',
98		zIndex         : 42,
99		delay          : 400,
100		observerOptions: {},
101		fxOptions      : {},
102
103		autoSubmit    : false,
104		overflow      : false,
105		overflowMargin: 25,
106		selectFirst   : false,
107		filter        : null,
108		filterCase    : false,
109		filterSubset  : false,
110		forceSelect   : false,
111		selectMode    : true,
112		choicesMatch  : null,
113
114		multiple      : false,
115		separator     : ', ',
116		separatorSplit: /\s*[,;]\s*/,
117		autoTrim      : false,
118		allowDupes    : false,
119
120		cache   : true,
121		relative: false
122	},
123
124	initialize: function(element, options) {
125		this.element = document.id(element);
126		this.setOptions(options);
127		this.build();
128		this.observer = new Observer(this.element, this.prefetch.bind(this), Object.merge({
129			'delay': this.options.delay
130		}, this.options.observerOptions));
131		this.queryValue = null;
132		if (this.options.filter) this.filter = this.options.filter.bind(this);
133		var mode = this.options.selectMode;
134		this.typeAhead = (mode == 'type-ahead');
135		this.selectMode = (mode === true) ? 'selection' : mode;
136		this.cached = [];
137	},
138
139	/**
140	 * build - Initialize DOM
141	 *
142	 * Builds the html structure for choices and appends the events to the element.
143	 * Override this function to modify the html generation.
144	 */
145	build: function() {
146		if (document.id(this.options.customChoices)) {
147			this.choices = this.options.customChoices;
148		} else {
149			this.choices = new Element('ul', {
150				'class' : this.options.className,
151				'styles': {
152					'zIndex': this.options.zIndex
153				}
154			}).inject(document.body);
155			this.relative = false;
156			if (this.options.relative) {
157				this.choices.inject(this.element, 'after');
158				this.relative = this.element.getOffsetParent();
159			}
160			this.fix = new OverlayFix(this.choices);
161		}
162		if (!this.options.separator.test(this.options.separatorSplit)) {
163			this.options.separatorSplit = this.options.separator;
164		}
165		this.fx = (!this.options.fxOptions) ? null : new Fx.Tween(this.choices, Ob
165ject.merge({
166			'property': 'opacity',
167			'link'    : 'cancel',
168			'duration': 200
169		}, this.options.fxOptions)).addEvent('onStart', Chain.prototype.clearChain).set(0);
170		this.element.setProperty('autocomplete', 'off')
171			.addEvent((Browser.ie || Browser.safari || Browser.chrome) ? 'keydown' : 'keypress', this.onCommand.bind(this))
172			.addEvent('click', this.onCommand.bind(this, [false]))
173			.addEvent('focus', this.toggleFocus.pass({bind: this, arguments: true, delay: 100}))
174			.addEvent('blur', this.toggleFocus.pass({bind: this, arguments: false, delay: 100}));
175	},
176
177	destroy: function() {
178		if (this.fix) this.fix.destroy();
179		this.choices = this.selected = this.choices.destroy();
180	},
181
182	toggleFocus: function(state) {
183		this.focussed = state;
184		if (!state) this.hideChoices(true);
185		this.fireEvent((state) ? 'onFocus' : 'onBlur', [this.element]);
186	},
187
188	onCommand: function(e) {
189		if (!e && this.focussed) return this.prefetch();
190		if (e && e.key && !e.shift) {
191			switch (e.key) {
192				case 'enter':
193					if (this.element.value != this.opted) return true;
194					if (this.selected && this.visible) {
195						this.choiceSelect(this.selected);
196						return !!(this.options.autoSubmit);
197					}
198					break;
199				case 'up':
200				case 'down':
201					if (!this.prefetch() && this.queryValue !== null) {
202						var up = (e.key == 'up');
203						this.choiceOver((this.selected || this.choices)[
204							(this.selected) ? ((up) ? 'getPrevious' : 'getNext') : ((up) ? 'getLast' : 'getFirst')
205							](this.options.choicesMatch), true);
206					}
207					return false;
208				case 'esc':
209				case 'tab':
210					this.hideChoices(true);
211					break;
212			}
213		}
214		return true;
215	},
216
217	setSelection: function(finish) {
218		var input = this.selected.inputValue, value = input;
219		var start = this.queryValue.length, end = input.length;
220		if (input.substr(0, start).toLowerCase() != this.queryValue.toLowerCase()) start = 0;
221		if (this.options.multiple) {
222			var split = this.options.separatorSplit;
223			value = this.element.value;
224			start += this.queryIndex;
225			end += this.queryIndex;
226			var old = value.substr(this.queryIndex).split(split, 1)[0];
227			value = value.substr(0, this.queryIndex) + input + value.substr(this.queryIndex + old.length);
228			if (finish) {
229				var tokens = value.split(this.options.separatorSplit).filter(function(entry) {
230					return this.test(entry);
231				}, /[^\s,]+/);
232				if (!this.options.allowDupes) tokens = [].combine(tokens);
233				var sep = this.options.separator;
234				value = tokens.join(sep) + sep;
235				end = value.length;
236			}
237		}
238		this.observer.setValue(value);
239		this.opted = value;
240		if (finish || this.selectMode == 'pick') start = end;
241		this.element.selectRange(start, end);
242		this.fireEvent('onSelection', [this.element, this.selected, value, input]);
243	},
244
245	showChoices: function() {
246		var match = this.options.choicesMatch, first = this.choices.getFirst(match);
247		this.selected = this.selectedValue = null;
248		if (this.fix) {
249			var pos = this.element.getCoordinates(this.relative), width = this.options.width || 'auto';
250			this.choices.setStyles({
251				'left' : pos.left,
252				'top'  : pos.bottom,
253				'width': (width === true || width == 'inherit') ? pos.width : width
254			});
255		}
256		if (!first) return;
257		if (!this.visible) {
258			this.visible = true;
259			this.choices.setStyle('display', '');
260			if (this.fx) this.fx.start(1);
261			this.fireEvent('onShow', [this.element, this.choices]);
262		}
263		if (this.options.selectFirst || this.typeAhead || first.inputValue == this.queryValue) this.choiceOver(first, this.typeAhead);
264		var items = this.choices.getChildren(match), max = this.options.maxChoices;
265		var styles = {'overflowY': 'hidden', 'height': ''};
266		this.overflown = false;
267		if (items.length > max) {
268			var item = items[max - 1];
269			styles.overflowY = 'scroll';
270			styles.height = item.getCoordinates(this.choices).bottom;
271			this.overflown = true;
272		}
273		;
274		this.choices.setStyles(styles);
275		this.fix.show();
276		if (this.options.visibleChoices) {
277			var scroll = document.getScroll(),
278				size = document.getSize(),
279				coords = this.choices.getCoordinates();
280			if (coords.right > scroll.x + size.x) scroll.x = coords.right - size.x;
281			if (coords.bottom > scroll.y + size.y) scroll.y = coords.bottom - size.y;
282			window.scrollTo(Math.min(scroll.x, coords.left), Math.min(scroll.y, coords.top));
283		}
284	},
285
286	hideChoices: function(clear) {
287		if (clear) {
288			var value = this.element.value;
289			if (this.options.forceSelect) value = this.opted;
290			if (this.options.autoTrim) {
291				value = value.split(this.options.separatorSplit).filter($arguments(0)).join(this.options.separator);
292			}
293			this.observer.setValue(value);
294		}
295		if (!this.visible) return;
296		this.visible = false;
297		if (this.selected) this.selected.removeClass('autocompleter-selected');
298		this.observer.clear();
299		var hide = function() {
300			this.choices.setStyle('display', 'none');
301			this.fix.hide();
302		}.bind(this);
303		if (this.fx) this.fx.start(0).chain(hide);
304		else hide();
305		this.fireEvent('onHide', [this.element, this.choices]);
306	},
307
308	prefetch: function() {
309		var value = this.element.value, query = value;
310		if (this.options.multiple) {
311			var split = this.options.separatorSplit;
312			var values = value.split(split);
313			var index = this.element.getSelectedRange().start;
314			var toIndex = value.substr(0, index).split(split);
315			var last = toIndex.length - 1;
316			index -= toIndex[last].length;
317			query = values[last];
318		}
319		if (query.length < this.options.minLength) {
320			this.hideChoices();
321		} else {
322			if (query === this.queryValue || (this.visible && query == this.selectedValue)) {
323				if (this.visible) return false;
324				this.showChoices();
325			} else {
326				this.queryValue = query;
327				this.queryIndex = index;
328				if (!this.fetchCached()) this.query();
329			}
330		}
331		return true;
332	},
333
334	fetchCached: function() {
335		if (!this.options.cache
336			|| !this.cached
337			|| !this.cached.length
338			|| this.cached.length >= this.options.maxChoices
339			|| this.queryValue) {
340			return false;
341		}
342		this.update(this.filter(this.cached));
343		return true;
344	},
345
346	update: function(tokens) {
347		this.choices.empty();
348		this.cached = tokens;
349		var type = tokens && typeOf(tokens);
350		if (!type || (type == 'array' && !tokens.length) || (type == 'hash' && !tokens.getLength())) {
351			(this.options.emptyChoices || this.hideChoices).call(this);
352		} else {
353			if (this.options.maxChoices < tokens.length && !this.options.overflow) tokens.length = this.options.maxChoices;
354			tokens.each(this.options.injectChoice || function(token) {
355					var choice = new Element('li', {'html': this.markQueryValue(token)});
356					choice.inputValue = token;
357					this.addChoiceEvents(choice).inject(this.choices);
358				}, this);
359			this.showChoices();
360		}
361	},
362
363	choiceOver: function(choice, selection) {
364		if (!choice || choice == this.selected) return;
365		if (this.selected) this.selected.removeClass('autocompleter-selected');
366		this.selected = choice.addClass('autocompleter-selected');
367		this.fireEvent('onSelect', [this.element, this.selected, selection]);
368		if (!this.selectMode) this.opted = this.element.value;
369		if (!selection) return;
370		this.selectedValue = this.selected.inputValue;
371		if (this.overflown) {
372			var coords = this.selected.getCoordinates(this.choices), margin = this.options.overflowMargin,
373				top = this.choices.scrollTop, height = this.choices.offsetHeight, bottom = top + height;
374			if (coords.top - margin < top && top) this.choices.scrollTop = Math.max(coords.top - margin, 0);
375			else if (coords.bottom + margin > bottom) this.choices.scrollTop = Math.min(coords.bottom - height + margin, bottom);
376		}
377		if (this.selectMode) this.setSelection();
378	},
379
380	choiceSelect: function(choice) {
381		if (choice) this.choiceOver(choice);
382		this.setSelection(true);
383		this.queryValue = false;
384		this.hideChoices();
385	},
386
387	filter: function(tokens) {
388		return (tokens || this.tokens).filter(function(token) {
389			return this.test(token);
390		}, new RegExp(((this.options.filterSubset) ? '' : '^') + this.queryValue.escapeRegExp(), (this.options.filterCase) ? '' : 'i'));
391	},
392
393	/**
394	 * markQueryValue
395	 *
396	 * Marks the queried word in the given string with <span class="autocompleter-queried">*</span>
397	 * Call this i.e. from your custom parseChoices, same for addChoiceEvents
398	 *
399	 * @param        {String} Text
400	 * @return        {String} Text
401	 */
402	markQueryValue: function(str) {
403		return (!this.options.markQuery || !this.queryValue) ? str
404			: str.replace(new RegExp('(' + ((this.options.filterSubset) ? '' : '^') + this.queryValue.escapeRegExp() + ')', (this.options.filterCase) ? '' : 'i'), '<span class="autocompleter-queried">$1</span>');
405	},
406
407	/**
408	 * addChoiceEvents
409	 *
410	 * Appends the needed event handlers for a choice-entry to the given element.
411	 *
412	 * @param        {Element} Choice entry
413	 * @return        {Element} Choice entry
414	 */
415	addChoiceEvents: function(el) {
416		return el.addEvents({
417			'mouseover': this.choiceOver.bind(this, el),
418			'click'    : this.choiceSelect.bind(this, el)
419		});
420	}
421});
422
423var OverlayFix = new Class({
424
425	initialize: function(el) {
426		if (Browser.ie) {
427			this.element = document.id(el);
428			this.relative = this.element.getOffsetParent();
429			this.fix = new Element('iframe', {
430				'frameborder': '0',
431				'scrolling'  : 'no',
432				'src'        : 'javascript:false;',
433				'styles'     : {
434					'position': 'absolute',
435					'border'  : 'none',
436					'display' : 'none',
437					'filter'  : 'progid:DXImageTransform.Microsoft.Alpha(opacity=0)'
438				}
439			}).inject(this.element, 'after');
440		}
441	},
442
443	show: function() {
444		if (this.fix) {
445			var coords = this.element.getCoordinates(this.relative);
446			delete coords.right;
447			delete coords.bottom;
448			this.fix.setStyles(Object.append(coords, {
449				'display': '',
450				'zIndex' : (this.element.getStyle('zIndex') || 1) - 1
451			}));
452		}
453		return this;
454	},
455
456	hide: function() {
457		if (this.fix) this.fix.setStyle('display', 'none');
458		return this;
459	},
460
461	destroy: function() {
462		if (this.fix) this.fix = this.fix.destroy();
463	}
464
465});
466
467Element.implement({
468
469	getSelectedRange: function() {
470		if (!Browser.ie) return {start: this.selectionStart, end: this.selectionEnd};
471		var pos = {start: 0, end: 0};
472		var range = this.getDocument().selection.createRange();
473		if (!range || range.parentElement() != this) return pos;
474		var dup = range.duplicate();
475		if (this.type == 'text') {
476			pos.start = 0 - dup.moveStart('character', -100000);
477			pos.end = pos.start + range.text.length;
478		} else {
479			var value = this.value;
480			var offset = value.length - value.match(/[\n\r]*$/)[0].length;
481			dup.moveToElementText(this);
482			dup.setEndPoint('StartToEnd', range);
483			pos.end = offset - dup.text.length;
484			dup.setEndPoint('StartToStart', range);
485			pos.start = offset - dup.text.length;
486		}
487		return pos;
488	},
489
490	selectRange: function(start, end) {
491		if (Browser.ie) {
492			var diff = this.value.substr(start, end - start).replace(/\r/g, '').length;
493			start = this.value.substr(0, start).replace(/\r/g, '').length;
494			var range = this.createTextRange();
495			range.collapse(true);
496			range.moveEnd('character', start + diff);
497			range.moveStart('character', start);
498			range.select();
499		} else {
500			this.focus();
501			this.setSelectionRange(start, end);
502		}
503		return this;
504	}
505
506});
507
508/* compatibility */
509
510Autocompleter.Base = Autocompleter;
511
512/**
513 * Autocompleter.Local
514 *
515 * http://digitarald.de/project/autocompleter/
516 *
517 * @version        1.1.2
518 *
519 * @license        MIT-style license
520 * @author        Harald Kirschner <mail [at] digitarald.de>
521 * @copyright    Author
522 */
523
524Autocompleter.Local = new Class({
525
526	Extends: Autocompleter,
527
528	options: {
529		minLength: 0,
530		delay    : 200
531	},
532
533	initialize: function(element, tokens, options) {
534		this.parent(element, options);
535		this.tokens = tokens;
536	},
537
538	query: function() {
539		this.update(this.filter());
540	}
541
542});
543
544/**
545 * Autocompleter.Request
546 *
547 * http://digitarald.de/project/autocompleter/
548 *
549 * @version        1.1.2
550 *
551 * @license        MIT-style license
552 * @author        Harald Kirschner <mail [at] digitarald.de>
553 * @copyright    Author
554 */
555
556Autocompleter.Request = new Class({
557
558	Extends: Autocompleter,
559
560	options: {
561		/*
562		 indicator: null,
563		 indicatorClass: null,
564		 onRequest: $empty,
565		 onComplete: $empty,*/
566		postData   : {},
567		ajaxOptions: {},
568		postVar    : 'value'
569
570	},
571
572	query: function() {
573		var data = Object.clone(this.options.postData) || {};
574		data[this.options.postVar] = this.queryValue;
575		var indicator = document.id(this.options.indicator);
576		if (indicator) indicator.setStyle('display', '');
577		var cls = this.options.indicatorClass;
578		if (cls) this.element.addClass(cls);
579		this.fireEvent('onRequest', [this.element, this.request, data, this.queryValue]);
580		this.request.send({'data': data});
581	},
582
583	/**
584	 * queryResponse - abstract
585	 *
586	 * Inherated classes have to extend this function and use this.parent()
587	 */
588	queryResponse: function() {
589		var indicator = document.id(this.options.indicator);
590		if (indicator) indicator.setStyle('display', 'none');
591		var cls = this.options.indicatorClass;
592		if (cls) this.element.removeClass(cls);
593		return this.fireEvent('onComplete', [this.element, this.request]);
594	}
595
596});
597
598Autocompleter.Request.JSON = new Class({
599	Extends: Autocompleter.Request,
600
601	secure    : false,
602	initialize: function(el, url, options) {
603		this.parent(el, options);
604		this.request = new Request.JSON(Object.merge({
605			'secure': false,
606			'url'   : url,
607			'link'  : 'cancel'
608		}, this.options.ajaxOptions)).addEvent('onComplete', this.queryResponse.bind(this));
609	},
610
611	queryResponse: function(response) {
612		this.parent();
613		this.update(response);
614	}
615
616});
617
618/* compatibility */
619
620Autocompleter.Ajax = {
621	Base : Autocompleter.Request,
622	Json : Autocompleter.Request.JSON,
623	Xhtml: Autocompleter.Request.HTML
624};
625
626/**
627 * Observer - Observe formelements for changes
628 *
629 * - Additional code from clientside.cnet.com
630 *
631 * @version        1.1
632 *
633 * @license        MIT-style license
634 * @author        Harald Kirschner <mail [at] digitarald.de>
635 * @copyright    Author
636 */
637var Observer = new Class({
638
639	Implements: [Options, Events],
640
641	options: {
642		periodical: false,
643		delay     : 1000
644	},
645
646	initialize: function(el, onFired, options) {
647		this.element = document.id(el) || $$(el);
648		this.addEvent('onFired', onFired);
649		this.setOptions(options);
650		this.bound = this.changed.bind(this);
651		this.resume();
652	},
653
654	changed: function() {
655		var value = this.element.get('value');
656		if ($equals(this.value, value)) return;
657		this.clear();
658		this.value = value;
659		this.timeout = this.onFired.delay(this.options.delay, this);
660	},
661
662	setValue: function(value) {
663		this.value = value;
664		this.element.set('value', value);
665		return this.clear();
666	},
667
668	onFired: function() {
669		this.fireEvent('onFired', [this.value, this.element]);
670	},
671
672	clear: function() {
673		clearInterval(this.timeout || null);
674		return this;
675	},
676
677	pause: function() {
678		if (this.timer) clearInterval(this.timer);
679		else this.element.removeEvent('keyup', this.bound);
680		return this.clear();
681	},
682
683	resume: function() {
684		this.value = this.element.get('value');
685		if (this.options.periodical) this.timer = this.changed.periodical(this.options.periodical, this);
686		else this.element.addEvent('keyup', this.bound);
687		return this;
688	}
689
690});
691
692var $equals = function(obj1, obj2) {
693	return (obj1 == obj2 || JSON.encode(obj1) == JSON.encode(obj2));
694};
695
696function kRequestShowTopics(catid, select, list) {
697	select.set('value', 0).fireEvent('change', select);
698	var first = select.getFirst().clone();
699	select.empty().grab(first);
700	list.each(function(item) {
701		var option = new Element('option', {'value': item.id, 'html': item.subject});
702		select.grab(option);
703	});
704}
705
706function kRequestGetTopics(el) {
707	var catid = el.get("value");
708	var select = document.id('kmod_topics');
709	request = new Request.JSON({
710		secure   : false, url: kunena_url_ajax,
711		onSuccess: function(response) {
712			kRequestShowTopics(catid, select, response.topiclist);
713		}
714	}).post({'catid': catid});
715}
716
717function kunenaSelectUsernameView(kobj, kuser) {
718	var kform = kobj.getParent('form');
719	if (kobj.get('checked')) {
720		kform.getElement('input[name=authorname]').removeProperty('disabled').setStyle('display', 'inline').set('value', kunena_anonymous_name);
721	} else {
722		kform.getElement('input[name=authorname]').set('disabled', 'disabled').setStyle('display', 'none').set('value', kuser);
723	}
724}
725
726function kunenatableOrdering(order, dir, task, form) {
727	var form = document.getElementById(form);
728	form.filter_order.value = order;
729	form.filter_order_Dir.value = dir;
730	form.submit(task);
731}
732
733//----------------- New Mootools based behaviors ----------------------
734
735window.addEvent('domready', function() {
736	/* Quick reply */
737	$$('.kqreply').each(function(el) {
738		el.addEvent('click', function(e) {
739			//prevent to load the page when click is detected on a button
740			e.stop();
741			var kreply = this.get('id');
742			var kstate = document.id(kreply + '_form').getStyle('display');
743			$$('.kreply-form').setStyle('display', 'none');
744			document.id(kreply + '_form').setStyle('display', 'block');
745			if (document.id(kreply + '_form').getElement('input[name=anonymous]')) {
746				var kuser = document.id(kreply + '_form').getElement('input[name=authorname]').get('value');
747				kunenaSelectUsernameView(document.id(kreply + '_form').getElement('input[name=anonymous]'), kuser);
748				document.id(kreply + '_form').getElement('input[name=anonymous]').addEvent('click', function(e) {
749					kunenaSelectUsernameView(this, kuser);
750				});
751			}
752		});
753	});
754
755	$$('.kreply-cancel').addEvent('click', function(e) {
756		$$('.kreply-form').setStyle('display', 'none');
757	});
758
759	/* Logic for bulkactions */
760	$$('input.kcheckall').addEvent('click', function(e) {
761		this.getParent('form').getElements('input.kcheck').each(function(el) {
762			if (el.get('checked') == false) {
763				el.set('checked', true);
764				el.set('value', '1');
765			} else {
766				el.set('value', '0');
767				el.set('checked', false);
768			}
769		});
770	});
771
772	$$('select.kchecktask').addEvent('change', function(e) {
773		ktarget = this.getSiblings('select[name=target]');
774		if (this.get('value') == 'move') {
775			ktarget.removeProperty('disabled');
776		} else {
777			ktarget.setProperty('disabled', 'disabled');
778		}
779	});
780
781	if (document.id('kmod_categories') != undefined) {
782		document.id('kmod_categories').addEvent('change', function(e) {
783			kRequestGetTopics(this);
784		});
785	}
786	if (document.id('kmod_topics') != undefined) {
787		document.id('kmod_topics').addEvent('change', function(e) {
788			id = this.get('value');
789			if (id != 0) {
790				targetid = this.get('value');
791				document.id('kmod_subject').setStyle('display', 'none');
792			} else {
793				targetid = '';
794				document.id('kmod_subject').setStyle('display', 'block');
795			}
796			if (id == -1) {
797				targetid = '';
798				document.id('kmod_targetid').setStyle('display', 'inline');
799			} else {
800				document.id('kmod_targetid').setStyle('display', 'none');
801			}
802			document.id('kmod_targetid').set('value', targetid);
803		});
804	}
805
806	// Get the kunena settings cookie data.
807	var KCookie = new Hash.Cookie('kunena_toggler', {path: '/', duration: 0});
808
809	// Setup the behavior for all kunena toggler elements.
810	$$('a.ktoggler').each(function(link) {
811		// Auto-hide if the cookie is set.
812		if (KCookie.get(link.getProperty('rel'))) {
813			link.removeClass('close').addClass('open');
814			link.set('title', kunena_toggler_open);
815			document.id(link.getProperty('rel')).setStyle('display', 'none');
816		}
817
818		// Add the onclick event.
819		link.addEvent('click', function() {
820			if (this.hasClass('close')) {
821				this.removeClass('close').addClass('open');
822				link.set('title', kunena_toggler_open);
823				document.id(this.getProperty('rel')).setStyle('display', 'none');
824				KCookie.set(this.getProperty('rel'), 1);
825			}
826			else {
827				this.removeClass('open').addClass('close');
828				link.set('title', kunena_toggler_close);
829				document.id(this.getProperty('rel')).setStyle('display', '');
830				KCookie.erase(this.getProperty('rel'));
831			}
832		});
833	});
834
835	// Set autocompleter to off
836	$$('.kautocomplete-off').each(function() {
837		this.setProperty('autocompleter', 'off');
838	});
839	if (document.id('kpassword') != undefined && document.id('kpassword2') != undefined) {
840		document.id('kpassword').setProperty('autocompleter', 'off');
841		document.id('kpassword2').setProperty('autocompleter', 'off');
842	}
843
844	if (document.id('kpoll-moreusers') != undefined) {
845		document.id('kpoll-moreusers').addEvent('click', function() {
846			var displaytype = document.id('kpoll-moreusers-div').getStyle('display');
847			if (displaytype == 'none') document.id('kpoll-moreusers-div').setStyle('display');
848			else document.id('kpoll-moreusers-div').setStyle('display', 'none');
849		});
850	}
851
852	if (document.id('kchecbox-all') != undefined) {
853		document.id('kchecbox-all').addEvent('click', function() {
854			if (document.id('kchecbox-all').getProperty('checked') == false) {
855				$$('.kmoderate-topic-checkbox').each(function(box) {
856					box.removeProperty('checked');
857				});
858			} else {
859				$$('.kmoderate-topic-checkbox').each(function(box) {
860					box.setProperty('checked', 'checked');
861				});
862			}
863		});
864	}
865
866	if (document.id('kmoderate-select') != undefined) {
867		document.id('kmoderate-select').addEvent('click', function() {
868			if (document.id('kmoderate-select').getSelected().get('value') == 'move') {
869				document.id('kcategorytarget').setStyle('display');
870			}
871		});
872	}
873
874	if (document.id('avatar_category_select') != undefined) {
875		document.id('avatar_category_select').addEvent('change', function(e) {
876			// we getting the name of gallery selected in drop-down by user
877			var avatar_selected = document.id('avatar_category_select').getSelected();
878
879			var td_avatar = document.id('kgallery_avatar_list');
880
881			// we remove avatar which exist in td tag to allow us to put new one items
882			document.id('kgallery_avatar_list').empty();
883			// we getting from hidden input the url of kunena image gallery
884			var url_gallery_main = document.id('Kunena_Image_Gallery_URL').get('value');
885			var id_to_select = document.id('Kunena_' + avatar_selected.get('value'));
886			var name_to_select = id_to_select.getProperty('name');
887			// Convert JSON to object
888			var image_object = JSON.decode(id_to_select.get('value'));
889
890			// Re-create all HTML items with avatars images from gallery selected by user
891			for (var i = 0, len = image_object.length; i < len; ++i) {
892				var SpanElement = new Element('span');
893				var LabelElement = new Element('label');
894				LabelElement.setProperty('for', 'kavatar' + i);
895				if (name_to_select != 'default') {
896					var ImageElement = new Element('img', {
897						src: url_gallery_main + '/' + name_to_select + '/' + image_object[i],
898						alt: ''
899					});
900					var InputElement = new Element('input', {
901						id   : 'kavatar' + i,
902						type : 'radio',
903						name : 'avatar',
904						value: 'gallery/' + name_to_select + '/' + image_object[i]
905					});
906				} else {
907					var ImageElement = new Element('img', {src: url_gallery_main + '/' + image_object[i], alt: ''});
908					var InputElement = new Element('input', {
909						id   : 'kavatar' + i,
910						type : 'radio',
911						name : 'avatar',
912						value: 'gallery/' + image_object[i]
913					});
914				}
915				SpanElement.inject(td_avatar);
916				LabelElement.inject(SpanElement);
917				ImageElement.inject(LabelElement);
918				InputElement.inject(SpanElement);
919			}
920		});
921	}
922
923	$$('.kspoiler').each(function(el) {
924		var contentElement = el.getElement('.kspoiler-content');
925		var expandElement = el.getElement('.kspoiler-expand');
926		var hideElement = el.getElement('.kspoiler-hide');
927		el.getElement('.kspoiler-header').addEvent('click', function(e) {
928			if (contentElement.style.display == "none") {
929				contentElement.setStyle('display');
930				expandElement.setStyle('display', 'none');
931				hideElement.setStyle('display');
932			} else {
933				contentElement.setStyle('display', 'none');
934				expandElement.setStyle('display');
935				hideElement.setStyle('display', 'none');
936			}
937		});
938	});
939
940	/* For profile tabs */
941	$$('dl.tabs').each(function(tabs) {
942		new KunenaTabs(tabs);
943	});
944});

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.