xref: /dokuwiki/lib/scripts/script.js (revision 875f9efe0c294b53cdde087b617be4e88510de2f)
1/**
2 * Some of these scripts were taken from wikipedia.org and were modified for DokuWiki
3 */
4
5/**
6 * Some browser detection
7 */
8var clientPC  = navigator.userAgent.toLowerCase(); // Get client info
9var is_gecko  = ((clientPC.indexOf('gecko')!=-1) && (clientPC.indexOf('spoofer')==-1) &&
10                (clientPC.indexOf('khtml') == -1) && (clientPC.indexOf('netscape/7.0')==-1));
11var is_safari = ((clientPC.indexOf('AppleWebKit')!=-1) && (clientPC.indexOf('spoofer')==-1));
12var is_khtml  = (navigator.vendor == 'KDE' || ( document.childNodes && !document.all && !navigator.taintEnabled ));
13if (clientPC.indexOf('opera')!=-1) {
14    var is_opera = true;
15    var is_opera_preseven = (window.opera && !document.childNodes);
16    var is_opera_seven = (window.opera && document.childNodes);
17}
18
19/**
20 * Get the X offset of the top left corner of the given object
21 *
22 * @link http://www.quirksmode.org/index.html?/js/findpos.html
23 */
24function findPosX(object){
25  var curleft = 0;
26  var obj;
27  if(typeof(object) == 'object'){
28    obj = object;
29  }else{
30    obj = document.getElementById(object);
31  }
32  if (obj.offsetParent){
33    while (obj.offsetParent){
34      curleft += obj.offsetLeft;
35      obj = obj.offsetParent;
36    }
37  }
38  else if (obj.x){
39    curleft += obj.x;
40  }
41  return curleft;
42} //end findPosX function
43
44/**
45 * Get the Y offset of the top left corner of the given object
46 *
47 * @link http://www.quirksmode.org/index.html?/js/findpos.html
48 */
49function findPosY(object){
50  var curtop = 0;
51  var obj;
52  if(typeof(object) == 'object'){
53    obj = object;
54  }else{
55    obj = document.getElementById(object);
56  }
57  if (obj.offsetParent){
58    while (obj.offsetParent){
59      curtop += obj.offsetTop;
60      obj = obj.offsetParent;
61    }
62  }
63  else if (obj.y){
64    curtop += obj.y;
65  }
66  return curtop;
67} //end findPosY function
68
69/**
70 * Escape special chars in JavaScript
71 *
72 * @author Andreas Gohr <andi@splitbrain.org>
73 */
74function jsEscape(text){
75    var re=new RegExp("\\\\","g");
76    text=text.replace(re,"\\\\");
77    re=new RegExp("'","g");
78    text=text.replace(re,"\\'");
79    re=new RegExp('"',"g");
80    text=text.replace(re,'&quot;');
81    re=new RegExp("\\\\\\\\n","g");
82    text=text.replace(re,"\\n");
83    return text;
84}
85
86/**
87 * This function escapes some special chars
88 * @deprecated by above function
89 */
90function escapeQuotes(text) {
91  var re=new RegExp("'","g");
92  text=text.replace(re,"\\'");
93  re=new RegExp('"',"g");
94  text=text.replace(re,'&quot;');
95  re=new RegExp("\\n","g");
96  text=text.replace(re,"\\n");
97  return text;
98}
99
100/**
101 * Adds a node as the first childenode to the given parent
102 *
103 * @see appendChild()
104 */
105function prependChild(parent,element) {
106	if(!parent.firstChild){
107		parent.appendChild(element);
108	}else{
109		parent.insertBefore(element,parent.firstChild);
110	}
111}
112
113/**
114 * Prints a animated gif to show the search is performed
115 *
116 * @author Andreas Gohr <andi@splitbrain.org>
117 */
118function showLoadBar(){
119  if(document.getElementById){
120    document.write('<img src="'+DOKU_BASE+'lib/images/loading.gif" '+
121                   'width="150" height="12" id="loading" />');
122  }
123}
124
125/**
126 * Disables the animated gif to show the search is done
127 *
128 * @author Andreas Gohr <andi@splitbrain.org>
129 */
130function hideLoadBar(){
131  if(document.getElementById){
132    document.getElementById('loading').style.display="none";
133  }
134}
135
136/*
137 * Insert the selected filename and close the window
138 *
139 * @see http://www.alexking.org/index.php?content=software/javascript/content.php
140 */
141function mediaSelect(file){
142	opener.insertAtCarret('wikitext','{{'+file+'}}');
143  window.close();
144}
145
146/**
147 * For the upload Dialog. Prefills the wikiname.
148 */
149function suggestWikiname(){
150  var file = document.upload.upload.value;
151
152  file = file.substr(file.lastIndexOf('/')+1);
153  file = file.substr(file.lastIndexOf('\\')+1);
154
155  document.upload.id.value = file;
156}
157
158/**
159 * Adds the toggle switch to the TOC
160 */
161function addTocToggle() {
162	if(!document.getElementById) return;
163	var header = document.getElementById('toc__header');
164  if(!header) return;
165
166  var showimg     = document.createElement('img');
167	showimg.id      = 'toc__show';
168  showimg.src     = DOKU_BASE+'lib/images/arrow_down.gif';
169  showimg.alt     = '+';
170	showimg.onclick = toggleToc;
171  showimg.style.display = 'none';
172
173	var hideimg     = document.createElement('img');
174	hideimg.id      = 'toc__hide';
175  hideimg.src     = DOKU_BASE+'lib/images/arrow_up.gif';
176  hideimg.alt     = '-';
177	hideimg.onclick = toggleToc;
178
179  prependChild(header,showimg);
180  prependChild(header,hideimg);
181}
182
183/**
184 * This toggles the visibility of the Table of Contents
185 */
186function toggleToc() {
187  var toc = document.getElementById('toc__inside');
188  var showimg = document.getElementById('toc__show');
189  var hideimg = document.getElementById('toc__hide');
190  if(toc.style.display == 'none') {
191    toc.style.display      = '';
192    hideimg.style.display = '';
193    showimg.style.display = 'none';
194  } else {
195    toc.style.display      = 'none';
196    hideimg.style.display = 'none';
197    showimg.style.display = '';
198  }
199}
200
201/*
202 * This sets a cookie by JavaScript
203 *
204 * @see http://www.webreference.com/js/column8/functions.html
205 */
206function setCookie(name, value, expires, path, domain, secure) {
207  var curCookie = name + "=" + escape(value) +
208      ((expires) ? "; expires=" + expires.toGMTString() : "") +
209      ((path) ? "; path=" + path : "") +
210      ((domain) ? "; domain=" + domain : "") +
211      ((secure) ? "; secure" : "");
212  document.cookie = curCookie;
213}
214
215/*
216 * This reads a cookie by JavaScript
217 *
218 * @see http://www.webreference.com/js/column8/functions.html
219 */
220function getCookie(name) {
221  var dc = document.cookie;
222  var prefix = name + "=";
223  var begin = dc.indexOf("; " + prefix);
224  if (begin == -1) {
225    begin = dc.indexOf(prefix);
226    if (begin !== 0){ return null; }
227  } else {
228    begin += 2;
229  }
230  var end = document.cookie.indexOf(";", begin);
231  if (end == -1){
232    end = dc.length;
233  }
234  return unescape(dc.substring(begin + prefix.length, end));
235}
236
237/*
238 * This is needed for the cookie functions
239 *
240 * @see http://www.webreference.com/js/column8/functions.html
241 */
242function fixDate(date) {
243  var base = new Date(0);
244  var skew = base.getTime();
245  if (skew > 0){
246    date.setTime(date.getTime() - skew);
247  }
248}
249
250/*
251 * This enables/disables checkboxes for acl-administration
252 *
253 * @author Frank Schubert <frank@schokilade.de>
254 */
255function checkAclLevel(){
256  if(document.getElementById) {
257    var scope = document.getElementById('acl_scope').value;
258
259    //check for namespace
260    if( (scope.indexOf(":*") > 0) || (scope == "*") ){
261      document.getElementsByName('acl_checkbox[4]')[0].disabled=false;
262      document.getElementsByName('acl_checkbox[8]')[0].disabled=false;
263    }else{
264      document.getElementsByName('acl_checkbox[4]')[0].checked=false;
265      document.getElementsByName('acl_checkbox[8]')[0].checked=false;
266
267      document.getElementsByName('acl_checkbox[4]')[0].disabled=true;
268      document.getElementsByName('acl_checkbox[8]')[0].disabled=true;
269    }
270  }
271}
272
273/* insitu footnote addition
274 * provide a wrapper for domTT javascript library
275 * this function is placed in the onmouseover event of footnote references in the main page
276 *
277 * @author Chris Smith <chris [at] jalakai [dot] co [dot] uk>
278 */
279var currentFootnote = 0;
280function fnt(id, e, evt) {
281
282    if (currentFootnote && id != currentFootnote) {
283        domTT_close(document.getElementById('insitu-fn'+currentFootnote));
284    }
285
286    // does the footnote tooltip already exist?
287    var fnote = document.getElementById('insitu-fn'+id);
288    var footnote;
289    if (!fnote) {
290        // if not create it...
291
292        // locate the footnote anchor element
293        var a = document.getElementById( "fn"+id );
294        if (!a){ return; }
295
296        // anchor parent is the footnote container, get its innerHTML
297        footnote = new String (a.parentNode.innerHTML);
298
299        // strip the leading footnote anchors and their comma separators
300        footnote = footnote.replace(/<a\s.*?href=\".*\#fnt\d+\".*?<\/a>/gi, '');
301        footnote = footnote.replace(/^\s+(,\s+)+/,'');
302
303        // prefix ids on any elements with "insitu-" to ensure they remain unique
304        footnote = footnote.replace(/\bid=\"(.*?)\"/gi,'id="insitu-$1');
305   	} else {
306        footnote = new String(fnt.innerHTML);
307    }
308
309    // activate the tooltip
310    domTT_activate(e, evt, 'content', footnote, 'type', 'velcro', 'id', 'insitu-fn'+id, 'styleClass', 'insitu-footnote JSpopup', 'maxWidth', document.body.offsetWidth*0.4);
311    currentFootnote = id;
312}
313
314
315/**
316 * Add the edit window size controls
317 */
318function initSizeCtl(ctlid,edid){
319		if(!document.getElementById){ return; }
320
321    var ctl      = document.getElementById(ctlid);
322    var textarea = document.getElementById(edid);
323
324    var hgt = getCookie('DokuWikisizeCtl');
325    if(hgt === null || hgt === ''){
326      textarea.style.height = '300px';
327    }else{
328      textarea.style.height = hgt;
329    }
330
331    var l = document.createElement('img');
332    var s = document.createElement('img');
333    l.src = DOKU_BASE+'lib/images/larger.gif';
334    s.src = DOKU_BASE+'lib/images/smaller.gif';
335		addEvent(l,'click',function(){sizeCtl(edid,100);});
336		addEvent(s,'click',function(){sizeCtl(edid,-100);});
337    ctl.appendChild(l);
338    ctl.appendChild(s);
339}
340
341/**
342 * This sets the vertical size of the editbox
343 */
344function sizeCtl(edid,val){
345  var textarea = document.getElementById(edid);
346  var height = parseInt(textarea.style.height.substr(0,textarea.style.height.length-2));
347  height += val;
348  textarea.style.height = height+'px';
349
350  var now = new Date();
351  fixDate(now);
352  now.setTime(now.getTime() + 365 * 24 * 60 * 60 * 1000); //expire in a year
353  setCookie('DokuWikisizeCtl',textarea.style.height,now);
354}
355
356/**
357 * Handler to close all open Popups
358 */
359function closePopups(){
360  if(!document.getElementById){ return; }
361
362  var divs = document.getElementsByTagName('div');
363  for(var i=0; i < divs.length; i++){
364    if(divs[i].className.indexOf('JSpopup') != -1){
365			divs[i].style.display = 'none';
366    }
367  }
368}
369