PageSourceSearch

https://iskustva.net/qa-content/qa-global.js?1.8.6

js iskustva.net collected 2026-09-25 23:50:25 UTC 19,716 bytes, 834 lines download raw bytes

1/*
2	Question2Answer by Gideon Greenspan and contributors
3	http://www.question2answer.org/
4
5	Description: Common Javascript for Q2A pages including posting and AJAX
6
7	This program is free software; you can redistribute it and/or
8	modify it under the terms of the GNU General Public License
9	as published by the Free Software Foundation; either version 2
10	of the License, or (at your option) any later version.
11
12	This program is distributed in the hope that it will be useful,
13	but WITHOUT ANY WARRANTY; without even the implied warranty of
14	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15	GNU General Public License for more details.
16
17	More about this license: http://www.question2answer.org/license.php
18*/
19
20// General page functions
21
22function qa_reveal(elem, type, callback)
23{
24	if (elem)
25		$(elem).slideDown(400, callback);
26}
27
28function qa_conceal(elem, type, callback)
29{
30	if (elem)
31		$(elem).slideUp(400);
32}
33
34function qa_set_inner_html(elem, type, html)
35{
36	if (elem)
37		elem.innerHTML = html;
38}
39
40function qa_set_outer_html(elem, type, html)
41{
42	if (elem) {
43		var e = document.createElement('div');
44		e.innerHTML = html;
45		elem.parentNode.replaceChild(e.firstChild, elem);
46	}
47}
48
49function qa_show_waiting_after(elem, inside)
50{
51	if (elem && !elem.qa_waiting_shown) {
52		var w = document.getElementById('qa-waiting-template');
53
54		if (w) {
55			var c = w.cloneNode(true);
56			c.id = null;
57
58			if (inside)
59				elem.insertBefore(c, null);
60			else
61				elem.parentNode.insertBefore(c, elem.nextSibling);
62
63			elem.qa_waiting_shown = c;
64		}
65	}
66}
67
68function qa_hide_waiting(elem)
69{
70	var c = elem.qa_waiting_shown;
71
72	if (c) {
73		c.parentNode.removeChild(c);
74		elem.qa_waiting_shown = null;
75	}
76}
77
78function qa_vote_click(elem)
79{
80	var ens = elem.name.split('_');
81	var postid = ens[1];
82	var vote = parseInt(ens[2]);
83	var code = elem.form.elements.code.value;
84	var anchor = ens[3];
85
86	qa_ajax_post('vote', {postid: postid, vote: vote, code: code},
87		function(lines) {
88			if (lines[0] == '1') {
89				qa_set_inner_html(document.getElementById('voting_' + postid), 'voting', lines.slice(1).join("\n"));
90
91			} else if (lines[0] == '0') {
92				var mess = document.getElementById('errorbox');
93
94				if (!mess) {
95					mess = document.createElement('div');
96					mess.id = 'errorbox';
97					mess.className = 'qa-error';
98					mess.innerHTML = lines[1];
99					mess.style.display = 'none';
100				}
101
102				var postelem = document.getElementById(anchor);
103				var e = postelem.parentNode.insertBefore(mess, postelem);
104				qa_reveal(e);
105
106			} else
107				qa_ajax_error();
108		}
109	);
110
111	return false;
112}
113
114function qa_notice_click(elem)
115{
116	var ens = elem.name.split('_');
117	var code = elem.form.elements.code.value;
118
119	qa_ajax_post('notice', {noticeid: ens[1], code: code},
120		function(lines) {
121			if (lines[0] == '1')
122				qa_conceal(document.getElementById('notice_' + ens[1]), 'notice');
123			else if (lines[0] == '0')
124				alert(lines[1]);
125			else
126				qa_ajax_error();
127		}
128	);
129
130	return false;
131}
132
133function qa_favorite_click(elem)
134{
135	var ens = elem.name.split('_');
136	var code = elem.form.elements.code.value;
137
138	qa_ajax_post('favorite', {entitytype: ens[1], entityid: ens[2], favorite: parseInt(ens[3]), code: code},
139		function(lines) {
140			if (lines[0] == '1')
141				qa_set_inner_html(document.getElementById('favoriting'), 'favoriting', lines.slice(1).join("\n"));
142			else if (lines[0] == '0') {
143				alert(lines[1]);
144				qa_hide_waiting(elem);
145			} else
146				qa_ajax_error();
147		}
148	);
149
150	qa_show_waiting_after(elem, false);
151
152	return false;
153}
154
155function qa_ajax_post(operation, params, callback)
156{
157	$.extend(params, {qa: 'ajax', qa_operation: operation, qa_root: qa_root, qa_request: qa_request});
158
159	$.post(qa_root, params, function(response) {
160		var header = 'QA_AJAX_RESPONSE';
161		var headerpos = response.indexOf(header);
162
163		if (headerpos >= 0)
164			callback(response.substr(headerpos + header.length).replace(/^\s+/, '').split("\n"));
165		else
166			callback([]);
167
168	}, 'text').fail(function(jqXHR) {
169		if (jqXHR.readyState > 0)
170			callback([])
171	});
172}
173
174function qa_ajax_error()
175{
176	alert('Unexpected response from server - please try again or switch off Javascript.');
177}
178
179function qa_display_rule_show(target, show, first)
180{
181	var e = document.getElementById(target);
182	if (e) {
183		if (first || e.nodeName == 'SPAN')
184			e.style.display = (show ? '' : 'none');
185		else if (show)
186			$(e).fadeIn();
187		else
188			$(e).fadeOut();
189	}
190}
191
192
193// Question page actions
194
195var qa_element_revealed = null;
196
197function qa_toggle_element(elem)
198{
199	var e = elem ? document.getElementById(elem) : null;
200
201	if (e && e.qa_disabled)
202		e = null;
203
204	if (e && (qa_element_revealed == e)) {
205		qa_conceal(qa_element_revealed, 'form');
206		qa_element_revealed = null;
207
208	} else {
209		if (qa_element_revealed)
210			qa_conceal(qa_element_revealed, 'form');
211
212		if (e) {
213			if (e.qa_load && !e.qa_loaded) {
214				e.qa_load();
215				e.qa_loaded = true;
216			}
217
218			if (e.qa_show)
219				e.qa_show();
220
221			qa_reveal(e, 'form', function() {
222				var t = $(e).offset().top;
223				var h = $(e).height() + 16;
224				var wt = $(window).scrollTop();
225				var wh = $(window).height();
226
227				if ((t < wt) || (t > (wt + wh)))
228					qa_scroll_page_to(t);
229				else if ((t + h) > (wt + wh))
230					qa_scroll_page_to(t + h - wh);
231
232				if (e.qa_focus)
233					e.qa_focus();
234			});
235		}
236
237		qa_element_revealed = e;
238	}
239
240	return !(e || !elem); // failed to find item
241}
242
243function qa_submit_answer(questionid, elem)
244{
245	var params = qa_form_params('a_form');
246
247	params.a_questionid = questionid;
248
249	qa_ajax_post('answer', params,
250		function(lines) {
251			if (lines[0] == '1') {
252				if (lines[1] < 1) {
253					var b = document.getElementById('q_doanswer');
254					if (b)
255						b.style.display = 'none';
256				}
257
258				var t = document.getElementById('a_list_title');
259				qa_set_inner_html(t, 'a_list_title', lines[2]);
260				qa_reveal(t, 'a_list_title');
261
262				var e = document.createElement('div');
263				e.innerHTML = lines.slice(3).join("\n");
264
265				var c = e.firstChild;
266				c.style.display = 'none';
267
268				var l = document.getElementById('a_list');
269				l.insertBefore(c, l.firstChild);
270
271				var a = document.getElementById('anew');
272				a.qa_disabled = true;
273
274				qa_reveal(c, 'answer');
275				qa_conceal(a, 'form');
276
277			} else if (lines[0] == '0') {
278				document.forms['a_form'].submit();
279
280			} else {
281				qa_ajax_error();
282			}
283		}
284	);
285
286	qa_show_waiting_after(elem, false);
287
288	return false;
289}
290
291function qa_submit_comment(questionid, parentid, elem)
292{
293	var params = qa_form_params('c_form_' + parentid);
294
295	params.c_questionid = questionid;
296	params.c_parentid = parentid;
297
298	qa_ajax_post('comment', params,
299		function(lines) {
300
301			if (lines[0] == '1') {
302				var l = document.getElementById('c' + parentid + '_list');
303				l.innerHTML = lines.slice(2).join("\n");
304				l.style.display = '';
305
306				var a = document.getElementById('c' + parentid);
307				a.qa_disabled = true;
308
309				var c = document.getElementById(lines[1]); // id of comment
310				if (c) {
311					c.style.display = 'none';
312					qa_reveal(c, 'comment');
313				}
314
315				qa_conceal(a, 'form');
316
317			} else if (lines[0] == '0') {
318				document.forms['c_form_' + parentid].submit();
319
320			} else {
321				qa_ajax_error();
322			}
323
324		}
325	);
326
327	qa_show_waiting_after(elem, false);
328
329	return false;
330}
331
332function qa_answer_click(answerid, questionid, target)
333{
334	var params = {};
335
336	params.answerid = answerid;
337	params.questionid = questionid;
338	params.code = target.form.elements.code.value;
339	params[target.name] = target.value;
340
341	qa_ajax_post('click_a', params,
342		function(lines) {
343			if (lines[0] == '1') {
344				qa_set_inner_html(document.getElementById('a_list_title'), 'a_list_title', lines[1]);
345
346				var l = document.getElementById('a' + answerid);
347				var h = lines.slice(2).join("\n");
348
349				if (h.length)
350					qa_set_outer_html(l, 'answer', h);
351				else
352					qa_conceal(l, 'answer');
353
354			} else {
355				target.form.elements.qa_click.value = target.name;
356				target.form.submit();
357			}
358		}
359	);
360
361	qa_show_waiting_after(target, false);
362
363	return false;
364}
365
366function qa_comment_click(commentid, questionid, parentid, target)
367{
368	var params = {};
369
370	params.commentid = commentid;
371	params.questionid = questionid;
372	params.parentid = parentid;
373	params.code = target.form.elements.code.value;
374	params[target.name] = target.value;
375
376	qa_ajax_post('click_c', params,
377		function(lines) {
378			if (lines[0] == '1') {
379				var l = document.getElementById('c' + commentid);
380				var h = lines.slice(1).join("\n");
381
382				if (h.length)
383					qa_set_outer_html(l, 'comment', h);
384				else
385					qa_conceal(l, 'comment');
386
387			} else {
388				target.form.elements.qa_click.value = target.name;
389				target.form.submit();
390			}
391		}
392	);
393
394	qa_show_waiting_after(target, false);
395
396	return false;
397}
398
399function qa_show_comments(questionid, parentid, elem)
400{
401	var params = {};
402
403	params.c_questionid = questionid;
404	params.c_parentid = parentid;
405
406	qa_ajax_post('show_cs', params,
407		function(lines) {
408			if (lines[0] == '1') {
409				var l = document.getElementById('c' + parentid + '_list');
410				l.innerHTML = lines.slice(1).join("\n");
411				l.style.display = 'none';
412				qa_reveal(l, 'comments');
413
414			} else {
415				qa_ajax_error();
416			}
417		}
418	);
419
420	qa_show_waiting_after(elem, true);
421
422	return false;
423}
424
425function qa_form_params(formname)
426{
427	var es = document.forms[formname].elements;
428	var params = {};
429
430	for (var i = 0; i < es.length; i++) {
431		var e = es[i];
432		var t = (e.type || '').toLowerCase();
433
434		if (((t != 'checkbox') && (t != 'radio')) || e.checked)
435			params[e.name] = e.value;
436	}
437
438	return params;
439}
440
441function qa_scroll_page_to(scroll)
442{
443	$('html,body').animate({scrollTop: scroll}, 400);
444}
445
446
447// Ask form
448
449function qa_title_change(value)
450{
451	qa_ajax_post('asktitle', {title: value}, function(lines) {
452		if (lines[0] == '1') {
453			if (lines[1].length) {
454				qa_tags_examples = lines[1];
455				qa_tag_hints(true);
456			}
457
458			if (lines.length > 2) {
459				var simelem = document.getElementById('similar');
460				if (simelem)
461					simelem.innerHTML = lines.slice(2).join('\n');
462			}
463
464		} else if (lines[0] == '0')
465			alert(lines[1]);
466		else
467			qa_ajax_error();
468	});
469
470	qa_show_waiting_after(document.getElementById('similar'), true);
471}
472
473function qa_html_unescape(html)
474{
475	return html.replace(/&amp;/g, '&').replace(/&quot;/g, '"').replace(/&lt;/g, '<').replace(/&gt;/g, '>');
476}
477
478function qa_html_escape(text)
479{
480	return text.replace(/&/g, '&amp;').replace(/"/g, '&quot;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
481}
482
483function qa_tag_click(link)
484{
485	var elem = document.getElementById('tags');
486	var parts = qa_tag_typed_parts(elem);
487
488	// removes any HTML tags and ampersand
489	var tag = qa_html_unescape(link.innerHTML.replace(/<[^>]*>/g, ''));
490
491	var separator = qa_tag_onlycomma ? ', ' : ' ';
492
493	// replace if matches typed, otherwise append
494	var newvalue = (parts.typed && (tag.toLowerCase().indexOf(parts.typed.toLowerCase()) >= 0))
495		? (parts.before + separator + tag + separator + parts.after + separator) : (elem.value + separator + tag + separator);
496
497	// sanitize and set value
498	if (qa_tag_onlycomma)
499		elem.value = newvalue.replace(/[\s,]*,[\s,]*/g, ', ').replace(/^[\s,]+/g, '');
500	else
501		elem.value = newvalue.replace(/[\s,]+/g, ' ').replace(/^[\s,]+/g, '');
502
503	elem.focus();
504	qa_tag_hints();
505
506	return false;
507}
508
509function qa_tag_hints(skipcomplete)
510{
511	var elem = document.getElementById('tags');
512	var html = '';
513	var completed = false;
514
515	// first try to auto-complete
516	if (qa_tags_complete && !skipcomplete) {
517		var parts = qa_tag_typed_parts(elem);
518
519		if (parts.typed) {
520			html = qa_tags_to_html((qa_html_unescape(qa_tags_examples + ',' + qa_tags_complete)).split(','), parts.typed.toLowerCase());
521			completed = html ? true : false;
522		}
523	}
524
525	// otherwise show examples
526	if (qa_tags_examples && !completed)
527		html = qa_tags_to_html((qa_html_unescape(qa_tags_examples)).split(','), null);
528
529	// set title visiblity and hint list
530	document.getElementById('tag_examples_title').style.display = (html && !completed) ? '' : 'none';
531	document.getElementById('tag_complete_title').style.display = (html && completed) ? '' : 'none';
532	document.getElementById('tag_hints').innerHTML = html;
533}
534
535function qa_tags_to_html(tags, matchlc)
536{
537	var html = '';
538	var added = 0;
539	var tagseen = {};
540
541	for (var i = 0; i < tags.length; i++) {
542		var tag = tags[i];
543		var taglc = tag.toLowerCase();
544
545		if (!tagseen[taglc]) {
546			tagseen[taglc] = true;
547
548			if ((!matchlc) || (taglc.indexOf(matchlc) >= 0)) { // match if necessary
549				if (matchlc) { // if matching, show appropriate part in bold
550					var matchstart = taglc.indexOf(matchlc);
551					var matchend = matchstart + matchlc.length;
552					inner = '<span style="font-weight:normal;">' + qa_html_escape(tag.substring(0, matchstart)) + '<b>' +
553						qa_html_escape(tag.substring(matchstart, matchend)) + '</b>' + qa_html_escape(tag.substring(matchend)) + '</span>';
554				} else // otherwise show as-is
555					inner = qa_html_escape(tag);
556
557				html += qa_tag_template.replace(/\^/g, inner.replace('$', '$$$$')) + ' '; // replace ^ in template, escape $s
558
559				if (++added >= qa_tags_max)
560					break;
561			}
562		}
563	}
564
565	return html;
566}
567
568function qa_caret_from_end(elem)
569{
570	if (document.selection) { // for IE
571		elem.focus();
572		var sel = document.selection.createRange();
573		sel.moveStart('character', -elem.value.length);
574
575		return elem.value.length - sel.text.length;
576
577	} else if (typeof (elem.selectionEnd) != 'undefined') // other browsers
578		return elem.value.length - elem.selectionEnd;
579
580	else // by default return safest value
581		return 0;
582}
583
584function qa_tag_typed_parts(elem)
585{
586	var caret = elem.value.length - qa_caret_from_end(elem);
587	var active = elem.value.substring(0, caret);
588	var passive = elem.value.substring(active.length);
589
590	// if the caret is in the middle of a word, move the end of word from passive to active
591	if (
592		active.match(qa_tag_onlycomma ? /[^\s,][^,]*$/ : /[^\s,]$/) &&
593		(adjoinmatch = passive.match(qa_tag_onlycomma ? /^[^,]*[^\s,][^,]*/ : /^[^\s,]+/))
594		) {
595		active += adjoinmatch[0];
596		passive = elem.value.substring(active.length);
597	}
598
599	// find what has been typed so far
600	var typedmatch = active.match(qa_tag_onlycomma ? /[^\s,]+[^,]*$/ : /[^\s,]+$/) || [''];
601
602	return {before: active.substring(0, active.length - typedmatch[0].length), after: passive, typed: typedmatch[0]};
603}
604
605function qa_category_select(idprefix, startpath)
606{
607	var startval = startpath ? startpath.split("/") : [];
608	var setdescnow = true;
609
610	for (var l = 0; l <= qa_cat_maxdepth; l++) {
611		var elem = document.getElementById(idprefix + '_' + l);
612
613		if (elem) {
614			if (l) {
615				if (l < startval.length && startval[l].length) {
616					var val = startval[l];
617
618					for (var j = 0; j < elem.options.length; j++)
619						if (elem.options[j].value == val)
620							elem.selectedIndex = j;
621				} else
622					var val = elem.options[elem.selectedIndex].value;
623			} else
624				val = '';
625
626			if (elem.qa_last_sel !== val) {
627				elem.qa_last_sel = val;
628
629				var subelem = document.getElementById(idprefix + '_' + l + '_sub');
630				if (subelem)
631					subelem.parentNode.removeChild(subelem);
632
633				if (val.length || (l == 0)) {
634					subelem = elem.parentNode.insertBefore(document.createElement('span'), elem.nextSibling);
635					subelem.id = idprefix + '_' + l + '_sub';
636					qa_show_waiting_after(subelem, true);
637
638					qa_ajax_post('category', {categoryid: val},
639						(function(elem, l) {
640							return function(lines) {
641								var subelem = document.getElementById(idprefix + '_' + l + '_sub');
642								if (subelem)
643									subelem.parentNode.removeChild(subelem);
644
645								if (lines[0] == '1') {
646									elem.qa_cat_desc = lines[1];
647
648									var addedoption = false;
649
650									if (lines.length > 2) {
651										subelem = elem.parentNode.insertBefore(document.createElement('span'), elem.nextSibling);
652										subelem.id = idprefix + '_' + l + '_sub';
653										subelem.innerHTML = ' ';
654
655										var newelem = elem.cloneNode(false);
656
657										newelem.name = newelem.id = idprefix + '_' + (l + 1);
658										newelem.options.length = 0;
659
660										if (l ? qa_cat_allownosub : qa_cat_allownone)
661											newelem.options[0] = new Option(l ? '' : elem.options[0].text, '', true, true);
662
663										for (var i = 2; i < lines.length; i++) {
664											var parts = lines[i].split('/');
665
666											if (String(qa_cat_exclude).length && (String(qa_cat_exclude) == parts[0]))
667												continue;
668
669											newelem.options[newelem.options.length] = new Option(parts.slice(1).join('/'), parts[0]);
670											addedoption = true;
671										}
672
673										if (addedoption) {
674											subelem.appendChild(newelem);
675											qa_category_select(idprefix, startpath);
676
677										}
678
679										if (l == 0)
680											elem.style.display = 'none';
681									}
682
683									if (!addedoption)
684										set_category_description(idprefix);
685
686								} else if (lines[0] == '0')
687									alert(lines[1]);
688								else
689									qa_ajax_error();
690							}
691						})(elem, l)
692					);
693
694					setdescnow = false;
695				}
696
697				break;
698			}
699		}
700	}
701
702	if (setdescnow)
703		set_category_description(idprefix);
704}
705
706function set_category_description(idprefix)
707{
708	var n = document.getElementById(idprefix + '_note');
709
710	if (n) {
711		desc = '';
712
713		for (var l = 1; l <= qa_cat_maxdepth; l++) {
714			var elem = document.getElementById(idprefix + '_' + l);
715
716			if (elem && elem.options[elem.selectedIndex].value.length)
717				desc = elem.qa_cat_desc;
718		}
719
720		n.innerHTML = desc;
721	}
722}
723
724
725// User functions
726
727function qa_submit_wall_post(elem, morelink)
728{
729	var params = {};
730
731	params.message = document.forms.wallpost.message.value;
732	params.handle = document.forms.wallpost.handle.value;
733	params.start = document.forms.wallpost.start.value;
734	params.code = document.forms.wallpost.code.value;
735	params.morelink = morelink ? 1 : 0;
736
737	qa_ajax_post('wallpost', params,
738		function(lines) {
739			if (lines[0] == '1') {
740				var l = document.getElementById('wallmessages');
741				l.innerHTML = lines.slice(2).join("\n");
742
743				var c = document.getElementById(lines[1]); // id of new message
744				if (c) {
745					c.style.display = 'none';
746					qa_reveal(c, 'wallpost');
747				}
748
749				document.forms.wallpost.message.value = '';
750				qa_hide_waiting(elem);
751
752			} else if (lines[0] == '0') {
753				document.forms.wallpost.qa_click.value = elem.name;
754				document.forms.wallpost.submit();
755
756			} else {
757				qa_ajax_error();
758			}
759		}
760	);
761
762	qa_show_waiting_after(elem, false);
763
764	return false;
765}
766
767function qa_wall_post_click(messageid, target)
768{
769	var params = {};
770
771	params.messageid = messageid;
772	params.handle = document.forms.wallpost.handle.value;
773	params.start = document.forms.wallpost.start.value;
774	params.code = document.forms.wallpost.code.value;
775
776	params[target.name] = target.value;
777
778	qa_ajax_post('click_wall', params,
779		function(lines) {
780			if (lines[0] == '1') {
781				var l = document.getElementById('m' + messageid);
782				var h = lines.slice(1).join("\n");
783
784				if (h.length)
785					qa_set_outer_html(l, 'wallpost', h);
786				else
787					qa_conceal(l, 'wallpost');
788
789			} else {
790				document.forms.wallpost.qa_click.value = target.name;
791				document.forms.wallpost.submit();
792			}
793		}
794	);
795
796	qa_show_waiting_after(target, false);
797
798	return false;
799}
800
801function qa_pm_click(messageid, target, box)
802{
803	var params = {};
804
805	params.messageid = messageid;
806	params.box = box;
807	params.handle = document.forms.pmessage.handle.value;
808	params.start = document.forms.pmessage.start.value;
809	params.code = document.forms.pmessage.code.value;
810
811	params[target.name] = target.value;
812
813	qa_ajax_post('click_pm', params,
814		function(lines) {
815			if (lines[0] == '1') {
816				var l = document.getElementById('m' + messageid);
817				var h = lines.slice(1).join("\n");
818
819				if (h.length)
820					qa_set_outer_html(l, 'pmessage', h);
821				else
822					qa_conceal(l, 'pmessage');
823
824			} else {
825				document.forms.pmessage.qa_click.value = target.name;
826				document.forms.pmessage.submit();
827			}
828		}
829	);
830
831	qa_show_waiting_after(target, false);
832
833	return false
vendor: 4 bytes, lines 833-834
833;
834}

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.