1/*----------------------------------------------------|
2  | dTree 2.05 | www.destroydrop.com/javascript/tree/ |
3  |---------------------------------------------------|
4  | Copyright (c) 2002-2003 Geir Landro               |
5  |                                                   |
6  | This script can be used freely as long as all     |
7  | copyright messages are intact.                    |
8  |                                                   |
9  | Updated: 17.04.2003                               |
10  |---------------------------------------------------|
11  | Modified for Dokuwiki by                          |
12  | Samuele Tognini <samuele@netsons.org>             |
13  | under GPL 2 license                               |
14  | (http://www.gnu.org/licenses/gpl.html)            |
15  | Updated: 29.08.2009                               |
16  |---------------------------------------------------|
17  | Modified for Dokuwiki by                          |
18  | Rene Hadler <rene.hadler@iteas.at>                |
19  | under GPL 2 license                               |
20  | (http://www.gnu.org/licenses/gpl.html)            |
21  | Updated: 07.08.2012                               |
22  |---------------------------------------------------|
23  | tindexmenu | https://bitbucket.org/iteas/tindexmenu/ |
24  |--------------------------------------------------*/
25
26// Node object
27function Node(dokuid, id, pid, name, hns, isdir, ajax) {
28	this.dokuid = dokuid;
29	this.id = id;
30	this.pid = pid;
31	this.name = name;
32	this.hns = hns;
33	this.isdir = isdir;
34	this.ajax = ajax;
35	this._io = 0;
36	this._is = false;
37	this._ls = false;
38	this._hc = ajax;
39	this._ai = 0;
40	this._p = false;
41	this._lv = 0;
42	this._ok = false;
43	this._cp = false;
44}
45// Tree object
46function dTree(objName, theme) {
47	var objExt = indexmenu_findExt(theme);
48	this.config = {
49		urlbase : DOKU_BASE + 'doku.php?id=',
50		plugbase : DOKU_BASE + 'lib/plugins/indexmenu',
51		useCookies : true,
52		scroll : true,
53		toc : true,
54		maxjs : 1,
55		jsajax : '',
56		sepchar : ':',
57		theme : theme
58	};
59	var objImg = this.config.plugbase + '/images/' + theme + '/';
60	this.icon = {
61		root : objImg + 'base.' + objExt,
62		folder : objImg + 'folder.' + objExt,
63		folderH : objImg + 'folderh.' + objExt,
64		folderOpen : objImg + 'folderopen.' + objExt,
65		folderHOpen : objImg + 'folderhopen.' + objExt,
66		node : objImg + 'page.' + objExt,
67		empty : objImg + 'empty.' + objExt,
68		line : objImg + 'line.' + objExt,
69		join : objImg + 'join.' + objExt,
70		joinBottom : objImg + 'joinbottom.' + objExt,
71		plus : objImg + 'plus.' + objExt,
72		plusBottom : objImg + 'plusbottom.' + objExt,
73		minus : objImg + 'minus.' + objExt,
74		minusBottom : objImg + 'minusbottom.' + objExt,
75		nlPlus : objImg + 'nolines_plus.' + objExt,
76		nlMinus : objImg + 'nolines_minus.' + objExt
77	};
78	this.obj = objName;
79	this.aNodes = [];
80	this.aIndent = [];
81	this.root = new Node(false, -1);
82	this.selectedNode = null;
83	this.selectedFound = false;
84	this.completed = false;
85	this.scrllTmr = 0;
86	this.pageid = window.indexmenu_ID || '';
87	this.fajax = false;
88}
89
90// Adds a new node to the node array
91dTree.prototype.add = function(dokuid, id, pid, name, hns, isdir, ajax) {
92	this.aNodes[this.aNodes.length] = new Node(dokuid, id, pid, name, hns,
93			isdir, ajax);
94};
95
96// Open/close all nodes
97dTree.prototype.openAll = function() {
98	if (!this.getCookie('co' + this.obj)) {
99		this.oAll(true);
100	}
101};
102
103// Outputs the tree to the page
104dTree.prototype.toString = function() {
105	var str = '';
106	if (this.config.scroll) {
107		str += '<div id="cdtree_'
108				+ this.obj
109				+ '" class="dtree" style="position:relative;overflow:hidden;width:100%;">';
110	}
111	str += '<div id="dtree_' + this.obj + '" class="dtree ' + this.config.theme
112			+ '" style="overflow:';
113	if (this.config.scroll) {
114		str += 'visible;position:relative;width:100%"';
115	} else {
116		str += 'hidden;"';
117	}
118	str += '>';
119	if (jQuery('#dtree_' + this.obj)[0]) {
120		str += '<div class="error">Indexmenu id conflict</div>';
121	}
122	if (this.config.toc) {
123		str += '<div id="t' + this.obj + '" class="indexmenu_tocbullet '
124				+ this.config.theme
125				+ '" style="display:none;" title="Table of contents"></div>';
126		str += '<div id="toc_' + this.obj + '" style="display:none;"></div>';
127	}
128	if (this.config.useCookies) {
129		this.selectedNode = this.getSelected();
130	}
131	str += this.addNode(this.root) + '</div>';
132	if (this.config.scroll) {
133		str += '<div id="z' + this.obj + '" class="indexmenu_rarrow"></div>';
134		str += '<div id="left_'
135				+ this.obj
136				+ '" class="indexmenu_larrow" style="display:none;" title="Click to scroll back" onmousedown="javascript:'
137				+ this.obj + '.scroll(\'r\',1);" onmouseup="javascript:'
138				+ this.obj + '.stopscroll();"></div>';
139		str += '</div>';
140	}
141	this.completed = true;
142	this.divdisplay('nojs_', 0);
143	return str;
144};
145
146// Creates the tree structure
147dTree.prototype.addNode = function(pNode) {
148	var str = '', cn, n = pNode._ai, l = pNode._lv + 1;
149	for (n; n < this.aNodes.length; n++) {
150		if (this.aNodes[n].pid == pNode.id) {
151			cn = this.aNodes[n];
152			cn._p = pNode;
153			cn._ai = n;
154			cn._lv = l;
155			this.setCS(cn);
156			if (cn._hc && !cn._io && this.config.useCookies) {
157				cn._io = this.isOpen(cn.id);
158			}
159			if (this.pageid == (!cn.hns && cn.dokuid || cn.hns)) {
160				cn._cp = true;
161			} else if (cn.id == this.selectedNode && !this.selectedFound) {
162				cn._is = true;
163				this.selectedNode = n;
164				this.selectedFound = true;
165			}
166			if (!cn._hc && cn.isdir && !cn.ajax && !cn.hns) {
167				if (cn._ls) {
168					str += this.noderr(cn, n);
169				}
170			} else {
171				str += this.node(cn, n);
172			}
173			if (cn._ls) {
174				break;
175			}
176		}
177	}
178	return str;
179};
180
181dTree.prototype.noderr = function(node, nodeId) {
182	var str = '<div class="dTreeNode">' + this.indent(node, nodeId);
183	str += '<div class="emptynode" title="Empty"></div></div>';
184	return str;
185};
186
187// Creates the node icon, url and text
188dTree.prototype.node = function(node, nodeId) {
189	var h = 1, jsfnc, str;
190	jsfnc = 'onmouseover="' + this.obj + '.show_feat(\'' + nodeId
191			+ '\');" onmousedown="return indexmenu_checkcontextm(\'' + nodeId
192			+ '\',' + this.obj
193			+ ',event);" oncontextmenu="return indexmenu_stopevt(event)"';
194	if (node._lv > this.config.maxjs) {
195		h = 0;
196	} else {
197		node._ok = true;
198	}
199	str = '<div class="dTreeNode">' + this.indent(node, nodeId);
200	node.icon = (this.root.id == node.pid) ? this.icon.root
201			: ((node.hns) ? this.icon.folderH : ((node._hc) ? this.icon.folder
202					: this.icon.node));
203	node.iconOpen = (node._hc) ? ((node.hns) ? this.icon.folderHOpen
204			: this.icon.folderOpen) : this.icon.node;
205	if (this.root.id == node.pid) {
206		node.icon = this.icon.root;
207		node.iconOpen = this.icon.root;
208	}
209	str += '<img id="i' + this.obj + nodeId + '" src="'
210			+ ((node._io) ? node.iconOpen : node.icon) + '" alt="" />';
211	if (!node._hc || node.hns) {
212		str += '<a id="s'
213				+ this.obj
214				+ nodeId
215				+ '" class="'
216				+ ((node._cp) ? 'navSel' : ((node._is) ? 'nodeSel'
217						: (node._hc) ? 'nodeFdUrl' : 'nodeUrl'));
218		str += '" href="' + this.config.urlbase;
219		(node.hns) ? str += node.hns : str += node.dokuid;
220		str += '"' + ' title="' + node.name + '"' + jsfnc;
221		str += ' onclick="javascript: ' + this.obj + '.s(' + nodeId + ');"';
222		str += '>' + node.name + '</a>';
223	} else if (node.pid != this.root.id) {
224		str += '<a id="s' + this.obj + nodeId + '" href="javascript: '
225				+ this.obj + '.o(' + nodeId + '); " class="node"' + jsfnc + '>'
226				+ node.name + '</a>';
227	} else {
228		str += node.name;
229	}
230	str += '</div>';
231	if (node._hc) {
232		str += '<div id="d' + this.obj + nodeId
233				+ '" class="clip" style="display:'
234				+ ((this.root.id == node.pid || node._io) ? 'block' : 'none')
235				+ ';">';
236		if (h) {
237			str += this.addNode(node);
238		}
239		str += '</div>';
240	}
241	this.aIndent.pop();
242	return str;
243};
244
245// Adds the empty and line icons
246dTree.prototype.indent = function(node, nodeId) {
247	var n, str = '';
248	if (this.root.id != node.pid) {
249		for (n = 0; n < this.aIndent.length; n++) {
250			str += '<img src="'
251					+ ((this.aIndent[n] == 1) ? this.icon.line
252							: this.icon.empty) + '" alt="" />';
253		}
254		if (node._ls) {
255			this.aIndent.push(0);
256		} else {
257			this.aIndent.push(1);
258		}
259		if (node._hc) {
260			str += '<a href="javascript: ' + this.obj + '.o(' + nodeId
261					+ ');"><img id="j' + this.obj + nodeId + '" src="';
262			str += ((node._io) ? ((node._ls) ? this.icon.minusBottom
263					: this.icon.minus) : ((node._ls) ? this.icon.plusBottom
264					: this.icon.plus));
265			str += '" alt="" /></a>';
266		} else {
267			str += '<img src="'
268					+ ((node._ls) ? this.icon.joinBottom : this.icon.join)
269					+ '" alt="" />';
270		}
271	}
272	return str;
273};
274
275// Checks if a node has any children and if it is the last sibling
276dTree.prototype.setCS = function(node) {
277	var lastId, n;
278	for (n = 0; n < this.aNodes.length; n++) {
279		if (this.aNodes[n].pid == node.id) {
280			node._hc = true;
281		}
282		if (this.aNodes[n].pid == node.pid) {
283			lastId = this.aNodes[n].id;
284		}
285	}
286	if (lastId == node.id) {
287		node._ls = true;
288	}
289};
290
291// Returns the selected node
292dTree.prototype.getSelected = function() {
293	var sn = this.getCookie('cs' + this.obj);
294	return (sn) ? sn : null;
295};
296
297// Highlights the selected node
298dTree.prototype.s = function(id) {
299	var eOld, eNew, cn = this.aNodes[id];
300	if (this.selectedNode != id) {
301		eNew = $("s" + this.obj + id);
302		if (!eNew) {
303			return;
304		}
305		if (this.selectedNode || this.selectedNode === 0) {
306			eOld = $("s" + this.obj + this.selectedNode);
307			eOld.className = "node";
308		}
309		eNew.className = "nodeSel";
310		this.selectedNode = id;
311		if (this.config.useCookies) {
312			this.setCookie('cs' + this.obj, cn.id);
313		}
314	}
315};
316
317// Toggle Open or close
318dTree.prototype.o = function(id) {
319	var cn = this.aNodes[id];
320	this.nodeStatus(!cn._io, id, cn._ls);
321	cn._io = !cn._io;
322	if (this.config.useCookies) {
323		this.updateCookie();
324	}
325	this.divdisplay('z', 0);
326	this.resizescroll("block");
327};
328
329// Open or close all nodes
330dTree.prototype.oAll = function(status) {
331	for ( var n = 0; n < this.aNodes.length; n++) {
332		if (this.aNodes[n]._hc && this.aNodes[n].pid != this.root.id) {
333			this.nodeStatus(status, n, this.aNodes[n]._ls);
334			this.aNodes[n]._io = status;
335		}
336	}
337	if (this.config.useCookies) {
338		this.updateCookie();
339	}
340};
341
342// Opens the tree to a specific node
343dTree.prototype.openTo = function(nId, bSelect, bFirst) {
344	var n, cn;
345	if (!bFirst) {
346		for (n = 0; n < this.aNodes.length; n++) {
347			if (this.aNodes[n].id == nId) {
348				nId = n;
349				break;
350			}
351		}
352	}
353	this.fill(this.aNodes[nId].pid);
354	cn = this.aNodes[nId];
355	if (cn.pid == this.root.id || !cn._p) {
356		return;
357	}
358	cn._io = 1;
359	if (this.completed && cn._hc) {
360		this.nodeStatus(true, cn._ai, cn._ls);
361	}
362	if (cn._is) {
363		(this.completed) ? this.s(cn._ai) : this._sn = cn._ai;
364	}
365	this.openTo(cn._p._ai, false, true);
366};
367
368dTree.prototype.getOpenTo = function(nodes) {
369	if (nodes === '') {
370		this.openAll();
371	} else if (!this.config.useCookies || !this.getCookie('co' + this.obj)) {
372		for ( var n = 0; n < nodes.length; n++) {
373			this.openTo(nodes[n], false, true);
374		}
375	}
376};
377
378// Change the status of a node(open or closed)
379dTree.prototype.nodeStatus = function(status, id, bottom) {
380	if (status && !this.fill(id)) {
381		return;
382	}
383	var eJoin, eIcon;
384	eJoin = jQuery('#j' + this.obj + id)[0];
385	eIcon = jQuery('#i' + this.obj + id)[0];
386	eIcon.src = (status) ? this.aNodes[id].iconOpen : this.aNodes[id].icon;
387	eJoin.src = ((status) ? ((bottom) ? this.icon.minusBottom : this.icon.minus)
388			: ((bottom) ? this.icon.plusBottom : this.icon.plus));
389	jQuery('#d' + this.obj + id)[0].style.display = (status) ? 'block' : 'none';
390};
391
392// [Cookie] Clears a cookie
393dTree.prototype.clearCookie = function() {
394	var now, yday;
395	now = new Date();
396	yday = new Date(now.getTime() - 1000 * 60 * 60 * 24);
397	this.setCookie('co' + this.obj, 'cookieValue', yday);
398	this.setCookie('cs' + this.obj, 'cookieValue', yday);
399};
400
401// [Cookie] Sets value in a cookie
402dTree.prototype.setCookie = function(cookieName, cookieValue, expires, path,
403		domain, secure) {
404	document.cookie = escape(cookieName) + '=' + escape(cookieValue)
405			+ (expires ? '; expires=' + expires.toGMTString() : '') + ';path=/'
406			+ (domain ? '; domain=' + domain : '') + (secure ? '; secure' : '');
407};
408
409// [Cookie] Gets a value from a cookie
410dTree.prototype.getCookie = function(cookieName) {
411	var cookieValue = '', pN, posValue, endPos;
412	pN = document.cookie.indexOf(escape(cookieName) + '=');
413	if (pN != -1) {
414		posValue = pN + (escape(cookieName) + '=').length;
415		endPos = document.cookie.indexOf(';', posValue);
416		if (endPos != -1) {
417			cookieValue = unescape(document.cookie.substring(posValue, endPos));
418		} else {
419			cookieValue = unescape(document.cookie.substring(posValue));
420		}
421	}
422	return (cookieValue);
423};
424
425// [Cookie] Returns ids of open nodes as a string
426dTree.prototype.updateCookie = function() {
427	var str = '', n;
428	for (n = 0; n < this.aNodes.length; n++) {
429		if (this.aNodes[n]._io && this.aNodes[n].pid != this.root.id) {
430			if (str) {
431				str += '.';
432			}
433			str += this.aNodes[n].id;
434		}
435	}
436	this.setCookie('co' + this.obj, str);
437};
438
439// [Cookie] Checks if a node id is in a cookie
440dTree.prototype.isOpen = function(id) {
441	var n, aOpen = this.getCookie('co' + this.obj).split('.');
442	for (n = 0; n < aOpen.length; n++) {
443		if (aOpen[n] == id) {
444			return true;
445		}
446	}
447	return false;
448};
449
450dTree.prototype.openCurNS = function(max) {
451	var r, cn, match, t, i, n, cnsa, cna, cns = this.pageid;
452	r = new RegExp("\\b" + this.config.sepchar + "\\b", "g");
453	match = cns.match(r) || -1;
454	if (max > 0 && match.length >= max) {
455		t = cns.split(this.config.sepchar);
456		n = (this.aNodes[0].dokuid == '') ? 0 : this.aNodes[0].dokuid
457				.split(this.config.sepchar).length;
458		t.splice(max + n, t.length);
459		cnsa = t.join(this.config.sepchar);
460	}
461	for (i = 0; i < this.aNodes.length; i++) {
462		cn = this.aNodes[i];
463		if (cns == cn.dokuid || cns == cn.hns) {
464			this.openTo(cn.id, false, true);
465			this.fajax = false;
466			if (cn.pid >= 0) {
467				jQuery(this.scroll("l", 4, cn.pid, 1));
468			}
469			break;
470		}
471		if (cnsa == cn.dokuid || cnsa == cn.hns) {
472			cna = cn;
473			this.fajax = true;
474		}
475	}
476	if (cna) {
477		this.openTo(cna.id, false, true);
478	}
479};
480
481dTree.prototype.fill = function(id) {
482	if (id == -1 || this.aNodes[id]._ok) {
483		return true;
484	}
485	var n = id, eLoad, node, a, rd, ln, eDiv;
486	if (this.aNodes[n].ajax) {
487		eLoad = $('l' + this.obj);
488		node = $('s' + this.obj + n);
489		if (!eLoad) {
490			eLoad = indexmenu_createPicker('l' + this.obj);
491		}
492		eLoad.innerHTML = 'Loading ...';
493		$('s' + this.obj + n).parentNode.appendChild(eLoad);
494		eLoad.style.width = 'auto';
495		eLoad.style.display = 'inline';
496		this.getAjax(n);
497		return true;
498	}
499	rd = [];
500	while (!this.aNodes[n]._ok) {
501		rd[rd.length] = n;
502		n = this.aNodes[n].pid;
503	}
504	for (ln = rd.length - 1; ln >= 0; ln--) {
505		id = rd[ln];
506		a = this.aNodes[id];
507		eDiv = jQuery('#d' + this.obj + id)[0];
508		if (!eDiv) {
509			return false;
510		}
511		this.aIndent = [];
512		n = a;
513		while (n.pid >= 0) {
514			if (n._ls) {
515				this.aIndent.unshift(0);
516			} else {
517				this.aIndent.unshift(1);
518			}
519			n = n._p;
520		}
521		eDiv.innerHTML = this.addNode(a);
522		a._ok = true;
523	}
524	return true;
525};
526
527dTree.prototype.openCookies = function() {
528	var n, cn, aOpen = this.getCookie('co' + this.obj).split('.');
529	for (n = 0; n < aOpen.length; n++) {
530		if (aOpen[n] === "") {
531			break;
532		}
533		cn = this.aNodes[aOpen[n]];
534		if (!cn._ok) {
535			this.nodeStatus(true, aOpen[n], cn._ls);
536			cn._io = 1;
537		}
538	}
539};
540
541dTree.prototype.scroll = function(where, s, n, i) {
542	if (!this.config.scroll) {
543		return false;
544	}
545	var w, dtree, dtreel, nodeId;
546	dtree = jQuery('#dtree_' + this.obj)[0];
547	dtreel = parseInt(dtree.offsetLeft, 0);
548	if (where == "r") {
549		$('left_' + this.obj).style.border = "thin inset";
550		this.scrollRight(dtreel, s);
551	} else {
552		nodeId = jQuery('#s' + this.obj + n)[0];
553		w = parseInt(dtree.parentNode.offsetWidth - nodeId.offsetWidth
554				- nodeId.offsetLeft, 0);
555		if (this.config.toc) {
556			w = w - 11;
557		}
558		if (dtreel <= w) {
559			return;
560		}
561		this.resizescroll("none");
562		this.stopscroll();
563		this.scrollLeft(dtreel, s, w - 3, i);
564	}
565};
566
567dTree.prototype.scrollLeft = function(lft, s, w, i) {
568	if (lft < w - i - 10) {
569		this.divdisplay('z', 0);
570		this.scrllTmr = 0;
571		return;
572	}
573	var self = this;
574	$('dtree_' + self.obj).style.left = lft + "px";
575	this.scrllTmr = setTimeout(function() {
576		self.scrollLeft(lft - s, s + i, w, i);
577	}, 20);
578};
579
580// Scroll Back
581dTree.prototype.scrollRight = function(lft, s) {
582	if (lft >= s) {
583		this.divdisplay('left_', 0);
584		this.stopscroll();
585		return;
586	}
587	var self = this;
588	$('dtree_' + self.obj).style.left = lft + "px";
589	if (lft > -15) {
590		s = 1;
591	}
592	this.scrllTmr = setTimeout(function() {
593		self.scrollRight(lft + s, s + 1);
594	}, 20);
595};
596
597dTree.prototype.stopscroll = function() {
598	$('left_' + this.obj).style.border = "none";
599	clearTimeout(this.scrllTmr);
600	this.scrllTmr = 0;
601};
602
603dTree.prototype.show_feat = function(n) {
604	var w, div, id, dtree, dtreel, self, node = jQuery('#s' + this.obj + n)[0];
605	self = this;
606	if (this.config.toc && node.className != "node") {
607		div = jQuery('#t' + this.obj)[0];
608		id = (this.aNodes[n].hns) ? this.aNodes[n].hns : this.aNodes[n].dokuid;
609		div.onmousedown = function() {
610			indexmenu_createTocMenu('req=toc&id=' + decodeURIComponent(id),
611					'picker_' + self.obj, 't' + self.obj);
612		};
613		node.parentNode.appendChild(div);
614		if (div.style.display == "none") {
615			div.style.display = "inline";
616		}
617	}
618	if (this.config.scroll) {
619		div = jQuery('#z' + this.obj)[0];
620		div.onmouseover = function() {
621			div.style.border = "none";
622			self.scroll("l", 1, n, 0);
623		};
624		div.onmousedown = function() {
625			div.style.border = "thin inset";
626			self.scroll("l", 4, n, 1);
627		};
628		div.onmouseout = function() {
629			div.style.border = "none";
630			self.stopscroll();
631		};
632		div.onmouseup = div.onmouseover;
633		dtree = jQuery('#dtree_' + this.obj)[0];
634		dtreel = parseInt(dtree.offsetLeft, 0);
635		w = parseInt(dtree.parentNode.offsetWidth - node.offsetWidth
636				- node.offsetLeft + 1, 0);
637		if (dtreel > w) {
638			div.style.display = "none";
639			div.style.top = node.offsetTop + "px";
640			div.style.left = parseInt(node.offsetLeft + node.offsetWidth + w
641					- 12, 0)
642					+ "px";
643			div.style.display = "block";
644		}
645	}
646};
647
648dTree.prototype.resizescroll = function(status) {
649	var dtree, w, h, left = jQuery('#left_' + this.obj)[0];
650	if (!left) {
651		return;
652	}
653	if (left.style.display == status) {
654		dtree = $('dtree_' + this.obj);
655		w = parseInt(dtree.offsetHeight / 3, 0);
656		h = parseInt(w / 50, 0) * 50;
657		if (h < 50) {
658			h = 50;
659		}
660		left.style.height = h + "px";
661		left.style.top = w + "px";
662		if (status == "none") {
663			left.style.display = "block";
664		}
665	}
666};
667
668// Toggle Open or close
669dTree.prototype.getAjax = function(n) {
670	var node, req, curns, selft = this;
671	node = selft.aNodes[n];
672	// We use SACK to do the AJAX requests
673	var Ajax = new sack(DOKU_BASE + 'lib/plugins/indexmenu/ajax.php');
674	req = 'req=index&idx=' + node.dokuid
675			+ decodeURIComponent(this.config.jsajax);
676	curns = this.pageid.substring(0, this.pageid
677			.lastIndexOf(this.config.sepchar));
678	Ajax.encodeURIString = false;
679	Ajax.onCompletion = function() {
680		var i, ajxnodes, ajxnode, plus;
681		plus = selft.aNodes.length - 1;
682		eval(this.response);
683		if (!isArray(ajxnodes) || ajxnodes.length < 1) {
684			ajxnodes = [ [ '', 1, 0, '', 0, 1, 0 ] ];
685		}
686		node.ajax = false;
687		for (i = 0; i < ajxnodes.length; i++) {
688			ajxnode = ajxnodes[i];
689			ajxnode[2] = (ajxnode[2] == 0) ? node.id : ajxnode[2] + plus;
690			ajxnode[1] += plus;
691			selft.add(ajxnode[0], ajxnode[1], ajxnode[2], ajxnode[3],
692					ajxnode[4], ajxnode[5], ajxnode[6]);
693		}
694		if (selft.fajax) {
695			selft.fajax = false;
696			selft.openCurNS(0);
697		} else {
698			selft.openTo(node.id, false, true);
699		}
700		$('l' + selft.obj).style.display = 'none';
701	};
702	if (this.fajax) {
703		req += '&nss=' + curns + '&max=1';
704	}
705	Ajax.encodeURIString = false;
706	Ajax.runAJAX(encodeURI(req));
707};
708
709// Load custom css
710dTree.prototype.loadCss = function() {
711	var oLink = document.createElement("link");
712	oLink.href = this.config.plugbase + '/images/' + this.config.theme
713			+ '/style.css';
714	oLink.rel = "stylesheet";
715	oLink.type = "text/css";
716	document.getElementsByTagName('head')[0].appendChild(oLink);
717};
718
719// Right click
720dTree.prototype.contextmenu = function(n, e) {
721	var li, id, html, type, node, self, cmenu, cdtree, rmenu, X = 0, Y = 0, i;
722	cdtree = jQuery("#cdtree_" + this.obj)[0];
723	rmenu = jQuery('#r' + this.obj)[0];
724	if (!rmenu) {
725		return true;
726	}
727	indexmenu_mouseposition(rmenu, e);
728	cmenu = window.indexmenu_contextmenu[0];
729	node = this.aNodes[n];
730	self = this;
731	rmenu.innerHTML = '<div class="indexmenu_rmenuhead" title="' + node.name
732			+ '">' + node.name + "</div>";
733	for (i = 0; i < cmenu.length; i++, i++, i++, i++) {
734		if (((!node._hc || node.hns) && !cmenu[i + 2])
735				|| (node._hc && !node.hns && !cmenu[i + 3])) {
736			continue;
737		}
738		html = cmenu[i];
739		if (cmenu[i + 1]) {
740			type = 'li';
741			id = (node.hns) ? node.hns : node.dokuid;
742			html = '<a title="' + cmenu[i] + '" href="' + eval(cmenu[i + 1])
743					+ '">' + html + '</a>';
744		} else {
745			type = 'span';
746			rmenu.appendChild(document.createElement('ul'));
747		}
748		li = document.createElement(type);
749		li.innerHTML = html;
750		rmenu.lastChild.appendChild(li);
751	}
752	rmenu.style.display = 'inline';
753	return false;
754};
755
756dTree.prototype.divdisplay = function(obj, v) {
757	var o = jQuery('#' + obj + this.obj)[0];
758	if (!o) {
759		return false;
760	}
761	(v) ? o.style.display = 'inline' : o.style.display = 'none';
762};
763
764dTree.prototype.init = function(s, c, n, nav, max) {
765	if (s) {
766		this.loadCss();
767	}
768	if (!c) {
769		this.openCookies();
770	}
771	if (n) {
772		this.getOpenTo(n.split(" "));
773	}
774	if (nav) {
775		this.openCurNS(max);
776	}
777	if (window.indexmenu_contextmenu) {
778		var self = this;
779		indexmenu_createPicker('r' + this.obj, 'indexmenu_rmenu '
780				+ this.config.theme);
781		jQuery('#r' + this.obj)[0].oncontextmenu = indexmenu_stopevt;
782		jQuery(document).click(
783			function() {
784				self.divdisplay('r', 0);
785			}
786		);
787	}
788};
789
790// If Push and pop is not implemented by the browser
791if (!Array.prototype.push) {
792	Array.prototype.push = function array_push() {
793		for ( var i = 0; i < arguments.length; i++) {
794			this[this.length] = arguments[i];
795		}
796		return this.length;
797	};
798}
799if (!Array.prototype.pop) {
800	Array.prototype.pop = function array_pop() {
801		var lstEl = this[this.length - 1];
802		this.length = Math.max(this.length - 1, 0);
803		return lstEl;
804	};
805}
806