Attachment 'common.js'
Download 1 //
2 // MoinMoin commonly used JavaScript functions
3 //
4
5 // We keep here the state of the search box
6 searchIsDisabled = false;
7
8 function searchChange(e) {
9 // Update search buttons status according to search box content.
10 // Ignore empty or whitespace search term.
11 var value = e.value.replace(/\s+/, '');
12 if (value == '' || searchIsDisabled) {
13 searchSetDisabled(true);
14 } else {
15 searchSetDisabled(false);
16 }
17 }
18
19 function searchSetDisabled(flag) {
20 // Enable or disable search
21 document.getElementById('fullsearch').disabled = flag;
22 document.getElementById('titlesearch').disabled = flag;
23 }
24
25 function searchFocus(e) {
26 // Update search input content on focus
27 if (e.value == search_hint) {
28 e.value = '';
29 e.className = '';
30 searchIsDisabled = false;
31 }
32 }
33
34 function searchBlur(e) {
35 // Update search input content on blur
36 if (e.value == '') {
37 e.value = search_hint;
38 e.className = 'disabled';
39 searchIsDisabled = true;
40 }
41 }
42
43 function actionsMenuInit(title) {
44 // Initialize action menu
45 for (i = 0; i < document.forms.length; i++) {
46 var form = document.forms[i];
47 if (form.className == 'actionsmenu') {
48 // Check if this form needs update
49 var div = form.getElementsByTagName('div')[0];
50 var label = div.getElementsByTagName('label')[0];
51 if (label) {
52 // This is the first time: remove label and do buton.
53 div.removeChild(label);
54 var dobutton = div.getElementsByTagName('input')[0];
55 div.removeChild(dobutton);
56 // and add menu title
57 var select = div.getElementsByTagName('select')[0];
58 var item = document.createElement('option');
59 item.appendChild(document.createTextNode(title));
60 item.value = 'show';
61 select.insertBefore(item, select.options[0]);
62 select.selectedIndex = 0;
63 }
64 }
65 }
66 }
67
68 // use this instead of assigning to window.onload directly:
69 function addLoadEvent(func) {
70 // alert("addLoadEvent " + func)
71 var oldonload = window.onload;
72 if (typeof window.onload != 'function') {
73 window.onload = func;
74 } else {
75 window.onload = function() {
76 oldonload();
77 func();
78 }
79 }
80 }
81
82 // copy from fckeditor browser check code (fckeditor.js:298, function : FCKeditor_IsCompatibleBrowser)
83 function can_use_gui_editor() {
84 var sAgent = navigator.userAgent.toLowerCase() ;
85
86 // Internet Explorer 5.5+
87 if ( /*@cc_on!@*/false && sAgent.indexOf("mac") == -1 )
88 {
89 var sBrowserVersion = navigator.appVersion.match(/MSIE (.\..)/)[1] ;
90 return ( sBrowserVersion >= 5.5 ) ;
91 }
92
93 // Gecko (Opera 9 tries to behave like Gecko at this point).
94 if ( navigator.product == "Gecko" && navigator.productSub >= 20030210 && !( typeof(opera) == 'object' && opera.postError ) )
95 return true ;
96
97 // Opera 9.50+
98 if ( window.opera && window.opera.version && parseFloat( window.opera.version() ) >= 9.5 )
99 return true ;
100
101 /*
102 // disable safari : until fck devteam fix http://dev.fckeditor.net/ticket/2333
103
104 // Adobe AIR
105 // Checked before Safari because AIR have the WebKit rich text editor
106 // features from Safari 3.0.4, but the version reported is 420.
107 if ( sAgent.indexOf( ' adobeair/' ) != -1 )
108 return ( sAgent.match( / adobeair\/(\d+)/ )[1] >= 1 ) ; // Build must be at least v1
109
110 // Safari 3+
111 if ( sAgent.indexOf( ' applewebkit/' ) != -1 )
112 return ( sAgent.match( / applewebkit\/(\d+)/ )[1] >= 522 ) ; // Build must be at least 522 (v3)
113 */
114 return false ;
115
116 }
117
118
119 function update_edit_links() {
120 // Update editlink according if if the browser is compatible
121 if (can_use_gui_editor() == false){
122 //alert("update_edit_links: can't use gui editor");
123 return;
124 }
125 var editlinks = document.getElementsByName("editlink");
126 for (i = 0; i < editlinks.length; i++) {
127 var link = editlinks[i];
128 href = link.href.replace('editor=textonly','editor=guipossible');
129 link.href = href;
130 //alert("update_edit_links: modified to guipossible");
131 }
132 }
133
134
135 function add_gui_editor_links() {
136 // Add gui editor link after the text editor link
137
138 // If the variable is not set or browser is not compatible, exit
139 try {gui_editor_link_href}
140 catch (e) {
141 //alert("add_gui_editor_links: gui_editor_link_href not here");
142 return
143 }
144 if (can_use_gui_editor() == false){
145 //alert("add_gui_editor_links: can't use gui_editor");
146 return;
147 }
148 var all = document.getElementsByName('texteditlink');
149 for (i = 0; i < all.length; i++) {
150 var textEditorLink = all[i];
151 // Create a list item with a link
152 var guiEditorLink = document.createElement('a');
153 guiEditorLink.href = gui_editor_link_href;
154 var text = document.createTextNode(gui_editor_link_text);
155 guiEditorLink.appendChild(text);
156 var listItem = document.createElement('li')
157 listItem.appendChild(guiEditorLink);
158 // Insert in the editbar
159 var editbar = textEditorLink.parentNode.parentNode
160 var nextListItem = textEditorLink.parentNode.nextSibling;
161 editbar.insertBefore(listItem, nextListItem);
162 //alert("add_gui_editor_links: added gui editor link");
163 }
164 }
165
166
167 function show_switch2gui() {
168 // Show switch to gui editor link if the browser is compatible
169 if (can_use_gui_editor() == false) return;
170
171 var switch2gui = document.getElementById('switch2gui')
172 if (switch2gui) {
173 switch2gui.style.display = 'inline';
174 }
175 }
176
177 // for long documents with many comments this is expensive to calculate,
178 // thus we keep it here:
179 comments = null;
180
181 function toggleComments() {
182 // Toggle visibility of every tag with class "comment"
183 for (i = 0; i < comments.length; i++){
184 el = comments[i];
185 if ( el.style.display != 'none' ) {
186 el.style.display = 'none';
187 } else {
188 el.style.display = '';
189 }
190 }
191 }
192
193 function show_toggleComments() {
194 // Show edit bar item for toggling inline comments on/off only if inline comments exist on the page
195 comments = getElementsByClassName('comment', null, document);
196 if (comments.length > 0) {
197 var buttons = getElementsByClassName('toggleCommentsButton', null, document);
198 for (i = 0; i < buttons.length; i++){
199 el = buttons[i];
200 el.style.display = '';
201 }
202 }
203 }
204
205
206 function load() {
207 // Do not name this "onload", it does not work with IE :-)
208 // TODO: create separate onload for each type of view and set the
209 // correct function name in the html.
210 // e.g <body onlod='editor_onload()'>
211
212 // login focus
213 if (document.forms['loginform']) {
214 document.forms['loginform'].elements['name'].focus();
215 }
216
217 // Page view stuff
218 update_edit_links();
219 add_gui_editor_links();
220
221 // Editor stuff
222 show_switch2gui();
223
224 // Enable menu item "ToggleComments" if inline comments exist
225 show_toggleComments();
226
227 // data browser widget
228 dbw_hide_buttons();
229 }
230
231
232 function before_unload(evt) {
233 // TODO: Better to set this in the editor html, as it does not make
234 // sense elsehwere.
235 // confirmleaving is available when editing
236 try {return confirmleaving();}
237 catch (e) {}
238 }
239
240 // Initialize after loading the page
241 addLoadEvent(load)
242
243 // Catch before unloading the page
244 window.onbeforeunload = before_unload
245
246 function dbw_update_search(dbw_id)
247 {
248 var table = document.getElementById(dbw_id+'table');
249 var cell;
250 var shown;
251 var i
252 var cols = table.rows[0].cells.length;
253 var filter = new Array();
254 var dofilter = new Array();
255 var form = document.forms[dbw_id+'form'];
256
257 for (i = 0; i < cols; i++) {
258 dofilter[i] = false;
259 if (form[dbw_id+'filter'+i]) {
260 dofilter[i] = true;
261 filter[i] = form[dbw_id+'filter'+i].value;
262 if (filter[i] == '[all]')
263 dofilter[i] = false;
264 if (filter[i] == '[empty]')
265 filter[i] = '';
266 }
267 }
268
269 for (i = 1; i < table.rows.length; i++) {
270 var show = true;
271 for (col = 0; col < cols; col++) {
272 if (!dofilter[col])
273 continue;
274
275 cell = table.rows[i].cells[col];
276
277 if (filter[col] == '[notempty]') {
278 if (cell.abbr == '') {
279 show = false;
280 break;
281 }
282 } else if (filter[col] != cell.abbr) {
283 show = false;
284 break;
285 }
286 }
287 if (show)
288 table.rows[i].style.display = '';
289 else
290 table.rows[i].style.display = 'none';
291 }
292 }
293
294 function dbw_hide_buttons() {
295 var form;
296 var elem;
297 var name;
298
299 for (var fidx = 0; fidx < document.forms.length; fidx++) {
300 form = document.forms[fidx];
301 for (var eidx = 0; eidx < form.elements.length; eidx++) {
302 elem = form.elements[eidx];
303 name = elem.name;
304 if (name) {
305 if (name.indexOf('dbw.') >= 0 && name.substr(-7) == '.submit')
306 elem.style.display = 'none';
307 }
308 }
309 }
310 }
311
312 /* getElementsByClassName
313 Developed by Robert Nyman, http://www.robertnyman.com
314 Code/licensing: http://code.google.com/p/getelementsbyclassname/ (MIT license)
315 Version: 1.0.1
316 */
317 var getElementsByClassName = function (className, tag, elm){
318 if (document.getElementsByClassName) {
319 getElementsByClassName = function (className, tag, elm) {
320 elm = elm || document;
321 var elements = elm.getElementsByClassName(className),
322 nodeName = (tag)? new RegExp("\\b" + tag + "\\b", "i") : null,
323 returnElements = [],
324 current;
325 for(var i=0, il=elements.length; i<il; i+=1){
326 current = elements[i];
327 if(!nodeName || nodeName.test(current.nodeName)) {
328 returnElements.push(current);
329 }
330 }
331 return returnElements;
332 };
333 }
334 else if (document.evaluate) {
335 getElementsByClassName = function (className, tag, elm) {
336 tag = tag || "*";
337 elm = elm || document;
338 var classes = className.split(" "),
339 classesToCheck = "",
340 xhtmlNamespace = "http://www.w3.org/1999/xhtml",
341 namespaceResolver = (document.documentElement.namespaceURI === xhtmlNamespace)? xhtmlNamespace : null,
342 returnElements = [],
343 elements,
344 node;
345 for(var j=0, jl=classes.length; j<jl; j+=1){
346 classesToCheck += "[contains(concat(' ', @class, ' '), ' " + classes[j] + " ')]";
347 }
348 try {
349 elements = document.evaluate(".//" + tag + classesToCheck, elm, namespaceResolver, 0, null);
350 }
351 catch (e) {
352 elements = document.evaluate(".//" + tag + classesToCheck, elm, null, 0, null);
353 }
354 while ((node = elements.iterateNext())) {
355 returnElements.push(node);
356 }
357 return returnElements;
358 };
359 }
360 else {
361 getElementsByClassName = function (className, tag, elm) {
362 tag = tag || "*";
363 elm = elm || document;
364 var classes = className.split(" "),
365 classesToCheck = [],
366 elements = (tag === "*" && elm.all)? elm.all : elm.getElementsByTagName(tag),
367 current,
368 returnElements = [],
369 match;
370 for(var k=0, kl=classes.length; k<kl; k+=1){
371 classesToCheck.push(new RegExp("(^|\\s)" + classes[k] + "(\\s|$)"));
372 }
373 for(var l=0, ll=elements.length; l<ll; l+=1){
374 current = elements[l];
375 match = false;
376 for(var m=0, ml=classesToCheck.length; m<ml; m+=1){
377 match = classesToCheck[m].test(current.className);
378 if (!match) {
379 break;
380 }
381 }
382 if (match) {
383 returnElements.push(current);
384 }
385 }
386 return returnElements;
387 };
388 }
389 return getElementsByClassName(className, tag, elm);
390 };
391
392
393 // ===========================================================================
394 // The following functions are part of scroll edit textarea on double-click
395 //
396 // This code is public domain (or primarily public domain).
397 // Do whatever you want with it. In particular, you may release it under
398 // GPL 2.0 or incorporate it into projects that use GPL 2.0.
399 // -- Radomir Dopieralski and Roger D. Haase
400
401 // Debugging helpers
402 // save debugging state in cookie - presence of a cookie means debugging mode is on
403 cookiePath = '/';
404 function autoScrollSetCookie (){
405 document.cookie = 'autoscrolldebug=on; path=' + cookiePath + '; ';
406 }
407 function autoScrollDeleteCookie (){
408 var cookie_date = new Date ( ); // current date & time
409 cookie_date.setTime ( cookie_date.getTime() - 1 );
410 document.cookie = 'autoscrolldebug=; expires=' + cookie_date.toGMTString() + '; path=' + cookiePath + '; ';
411 }
412 function autoScrollGetCookie (){
413 var results = document.cookie.match ( '(^|;) ?' + "autoscrolldebug" + '=([^;]*)(;|$)' );
414 if ( results ) {
415 return ( unescape ( results[2] ) );
416 } else {
417 return null;
418 }
419 }
420 // turn on debugging mode by previewing, saving or reading a page with "auto scroll debug on" within an h1 header
421 // = My Page auto scroll debug on =
422 // once set on,debug mode says on for current session or until turned off with
423 // = My Page auto scroll debug off =
424 autoScrollDebugOn = 0;
425 // this function executed on page load
426 function turnDebugOnOrOff () {
427 // set global variable for use by cookie functions
428 cookiePath = document.getElementsByName('edit_on_doubleclick')[0].content;
429 var hOnes = document.getElementsByTagName('H1');
430 for (var i = 0; i < hOnes.length; ++i) {
431 var header = hOnes[i].textContent || hOnes[i].innerText;
432 if (header.match ('auto scroll debug on')) {
433 autoScrollSetCookie ();
434 }
435 if (header.match ('auto scroll debug off')) {
436 autoScrollDeleteCookie ();
437 }
438 }
439 if (autoScrollGetCookie ()) {
440 autoScrollDebugOn = 1;
441 } else {
442 autoScrollDebugOn = 0;
443 }
444 }
445
446 // functions used for testing - mouseover tooltip with tagName and scroll line number
447 function doMouseOver(e) {
448 var targ = getNode(e);
449 targ.title = 'tagName='+targ.tagName+' line='+targ.scrollLine;
450 }
451 function doMouseOut(e) {
452 var targ = getNode(e);
453 targ.removeAttribute('title');
454 }
455 // add leading zeros to hours, minutes, seconds, milliseconds
456 function leadingZeros (nbr,count) {
457 var strNbr = nbr + '';
458 while (strNbr.length < count) {
459 strNbr = "0" + strNbr;
460 }
461 return strNbr;
462 }
463 // format hours, minutes, seconds, and ms
464 function formatTime (t) {
465 var sHours = leadingZeros (t.getHours(), 2);
466 var sMinutes = leadingZeros (t.getMinutes (), 2);
467 var sSeconds = leadingZeros (t.getSeconds (), 2);
468 var sMilliseconds = leadingZeros (t.getMilliseconds (), 3);
469 return sHours + ':' + sMinutes + ':' + sSeconds + ':' + sMilliseconds;
470 }
471
472 // this variable is available as easy way to display trace info
473 autoDebugTrace = '';
474 function showStartStopTimes (startTime) {
475 // display a message with start and end times at top of page
476 var endTime = new Date();
477 var tStart ='auto scroll debug on -- Initialization start H:M:S:ms=' + formatTime (startTime);
478 var tEnd = ' end H:M:S:ms=' + formatTime (endTime);
479 var timingMsg = document.createElement ('P');
480 timingMsg.innerHTML = tStart + tEnd;
481 timingMsg.style. color = "red";
482 var contentDiv;
483 if (document.getElementById ('preview')) {
484 contentDiv = document.getElementById ('preview');
485 } else {
486 contentDiv = document.getElementById ('content');
487 }
488 contentDiv.insertBefore (timingMsg, contentDiv.firstChild);
489 // display trace info is there is any
490 if (autoDebugTrace) {
491 alert(autoDebugTrace);
492 }
493 }
494 // end of debugging helpers
495
496 // this scrolls the textarea after a doubleclick - jumpLine is scroll-to line
497 function scrollTextarea(jumpLine) {
498 var txtBox = document.getElementById('editor-textarea');
499 scroll(0,0);
500 if (txtBox) {
501 // Calculate the cursor position - IE supports innerText, not textContent
502 var textLines = txtBox.textContent || txtBox.innerText;
503 textLines = textLines.match(/(.*(\r\n|\r|\n))/g);
504 var scrolledText = '';
505 for (var i = 0; i < textLines.length && i < jumpLine; ++i) {
506 scrolledText += textLines[i];
507 }
508 txtBox.focus();
509 if (txtBox.setSelectionRange) {
510 // Standard-compliant browsers
511 // Move the cursor
512 txtBox.setSelectionRange(scrolledText.length, scrolledText.length);
513 // Calculate how far to scroll, by putting the text that is to be
514 // above the fold in a DIV, and checking the DIV's height.
515 var scrollPre = document.createElement('pre');
516 txtBox.parentNode.appendChild(scrollPre);
517 var style = window.getComputedStyle(txtBox, '');
518 scrollPre.style.lineHeight = style.lineHeight;
519 scrollPre.style.fontFamily = style.fontFamily;
520 scrollPre.style.fontSize = style.fontSize;
521 scrollPre.style.padding = 0;
522 scrollPre.style.letterSpacing = style.letterSpacing;
523 // Different browsers call this value differently:
524 try { scrollPre.style.whiteSpace = "-moz-pre-wrap"; } catch(e) {}
525 try { scrollPre.style.whiteSpace = "-o-pre-wrap"; } catch(e) {}
526 try { scrollPre.style.whiteSpace = "-pre-wrap"; } catch(e) {}
527 try { scrollPre.style.whiteSpace = "pre-wrap"; } catch(e) {}
528 scrollPre.textContent = scrolledText;
529 txtBox.scrollTop = scrollPre.scrollHeight-100;
530 scrollPre.parentNode.removeChild(scrollPre);
531 } else if (txtBox.createTextRange) {
532 // Microsoft Internet Explorer
533 // We don't need to scroll, it will do it automatically, just move
534 // the cursor.
535 var range = txtBox.createTextRange();
536 range.collapse(true);
537 range.moveEnd('character', scrolledText.length);
538 range.moveStart('character', scrolledText.length);
539 range.select();
540 txtBox.__column = 1;
541 }
542 }
543 }
544
545 // stop event bubbling
546 function stopBubbling(e) {
547 if (e.stopPropagation) {
548 e.stopPropagation();
549 }
550 e.cancelBubble = true;
551 }
552
553 // stop bubbling and return event node
554 function getNode(e) {
555 // window.event and e.srcElement are IE
556 var e = e || window.event;
557 var targ = e.target || e.srcElement;
558 if (targ.nodeType == 3) {
559 // workaround safari
560 targ = targ.parentNode;
561 }
562 stopBubbling(e);
563 return targ;
564 }
565
566 // add action=edit and scrollLine to document.location
567 function doActionEdit(e) {
568 var targ = getNode(e);
569 // MoinMoin counts starting with 1, scrollTextarea starts with 0
570 document.location.search = '?action=edit&line='+(targ.scrollLine-1);
571 }
572
573 // scroll textarea on this page
574 function doTextareaScroll(e) {
575 var targ = getNode(e);
576 scrollTextarea(targ.scrollLine-1);
577 }
578
579 // This is the function that registers double clicks.
580 // isPreview is true if the current page is an edit draft preview
581 function setCallback(node, line, isPreview) {
582 if (node.scrollLine) {
583 // this node already processed
584 return;
585 } else {
586 node.scrollLine = line;
587 if(window.addEventListener){
588 if (isPreview) {
589 node.addEventListener('dblclick',doTextareaScroll,false);
590 } else {
591 node.addEventListener('dblclick',doActionEdit,false);
592 }
593 if (autoScrollDebugOn) {
594 node.addEventListener('mouseover', doMouseOver,false);
595 node.addEventListener('mouseout',doMouseOut,false);
596 }
597 } else {
598 // IE
599 if (isPreview) {
600 node.attachEvent('ondblclick',doTextareaScroll);
601 } else {
602 node.attachEvent('ondblclick',doActionEdit);
603 }
604 if (autoScrollDebugOn) {
605 node.attachEvent('onmouseover', doMouseOver,false);
606 node.attachEvent('onmouseout',doMouseOut,false);
607 }
608 }
609 }
610 }
611
612 // walk part of DOM and add doubleclick function to all nodes with tagNames
613 function walkDom (someNode, lineNbr, isPreview, nextId, topId) {
614
615 //~ // handle special cases of paragraph on line after <<TOC>> and ---- (horizontal rule)
616 //~ // But this effects paragraphs on multiple lines: doubleclick goes to paragraph bottom rather than top.
617 //~ // Seems best to live with TOC and HR problem and wait for Moin2.
618 //~ var next1, next2, next3;
619 //~ var nextNbr = 'line-' + (lineNbr-0+1);
620 //~ if (someNode.parentNode.tagName == 'P' && someNode.parentNode.scrollLine) {
621 //~ next1 = someNode.nextSibling;
622 //~ if (next1 && next1.tagName != 'SPAN') {
623 //~ next2 = next1.nextSibling;
624 //~ }
625 //~ if (next2 && next2.id == nextNbr) {
626 //~ alert('Correcting scrollLine='+lineNbr);
627 //~ someNode.parentNode.scrollLine = lineNbr;
628 //~ return;
629 //~ }
630 //~ }
631
632 var ie8LoopCounter = 0;
633 var doChild = true;
634 while (!(someNode.id == nextId) && !(someNode.id == topId)) {
635 // workaround IE8 bug: http://moinmo.in/MoinMoinBugs/FormInsideTableCausesIE8ScriptLoop
636 ie8LoopCounter += 1;
637 if (ie8LoopCounter > 10000) {
638 return;
639 }
640
641 // add children, add siblings, add parent
642 if (doChild && someNode.firstChild) {
643 someNode = someNode.firstChild;
644 } else {
645 doChild = true;
646 if (someNode.nextSibling) {
647 someNode = someNode.nextSibling;
648 } else {
649 if (someNode.parentNode.nextSibling) {
650 someNode = someNode.parentNode.nextSibling;
651 } else {
652 doChild = false;
653 someNode = someNode.parentNode.parentNode;
654 }
655 }
656 }
657 if (doChild && someNode.tagName && !(someNode.id == nextId) && !(someNode.id == topId)) {
658 setCallback(someNode, lineNbr, isPreview);
659 }
660 }
661 }
662
663 // run during page load when user may edit current page OR is viewing draft preview
664 function setSpanTags(isPreview) {
665 var startTime = new Date();
666 // find all the SPAN tags with an ID beginning with "line-"
667 var spanTags = document.getElementsByTagName('span');
668 var marks = [];
669 for (var i = 0; i < spanTags.length; ++i) {
670 if (spanTags[i].id && spanTags[i].id.substring(0, 5) == 'line-') {
671 marks.push(spanTags[i]);
672 }
673 }
674 var top = document.getElementById('content');
675 var bottom = document.getElementById('bottom');
676 // add expected stopping point to end of array for convenience
677 if (bottom) {
678 marks.push(bottom);
679 } else {
680 if (autoScrollDebugOn) {
681 alert("auto scroll debug 1: document.getElementById('bottom') failed");
682 }
683 }
684 var skipTo = -1;
685 // loop through span tags and apply double-click events to appropriate node(s)
686 for (i = 0; i < marks.length-1; ++i) {
687 var mark = marks[i];
688 // skip span tags generated by embedded parsers
689 if (i > skipTo) {
690 // split the ID into parts: looks like "line-22" or "line-22-1"
691 var lineParts = mark.id.split('-');
692 var line = lineParts[1];
693 if (lineParts.length == 3) {
694 // have found output from embedded parser
695 // find next span id that looks like "line-n" and the "line-n-n" just before it
696 var j = i - 0;
697 while (lineParts.length == 3) {
698 j++;
699 lineParts = marks[j].id.split('-');
700 }
701 // determine how many lines, starting line number, and add double-click events
702 var nbrParsedLines = j - i;
703 var parsedLineNbr = lineParts[1] - nbrParsedLines - 1;
704 for (var k = 0; k < nbrParsedLines; ++k) {
705 if (marks[i+k] && marks[i+k+1] && marks[i+k+1].id) {
706 walkDom (marks[i+k], parsedLineNbr+k, isPreview, marks[i+k+1].id, top.id);
707 } else {
708 if (autoScrollDebugOn) {
709 alert('auto scroll debug 2: skipping walkDom, i=' + i + ' k=' + k + ' marks[i].id=' + marks[i].id);
710 }
711 }
712 }
713 // done with embedded parser lines, tell main loop to skip these
714 skipTo = j - 1;
715 } else {
716 // walk part of DOM and apply doubleclick function to every node with a tagname
717 if (marks[i+1] && marks[i+1].id) {
718 walkDom (mark, line, isPreview, marks[i+1].id, top.id);
719 } else {
720 if (autoScrollDebugOn) {
721 alert('auto scroll debug 3: skipping walkDom, i=' + i + ' marks[i].id=' + marks[i].id);
722 }
723 }
724 }
725 }
726 }
727 if (autoScrollDebugOn && document.getElementById('content')) {
728 for (i = 0; i < marks.length-1; ++i) {
729 marks[i].innerHTML = ' ' + marks[i].id + ' ';
730 marks[i].style. color = "red";
731 }
732 showStartStopTimes(startTime);
733 }
734 }
735
736 // test to see if this user has selected or defaulted to edit_on_doubleclick AND
737 // whether we are viewing a page, editing a page, or previewing an edit draft
738 function scrollTextareaInit() {
739 // look for meta tag -- is edit_on_doubleclick present?
740 if (!document.getElementsByName('edit_on_doubleclick').length) {
741 return;
742 }
743 turnDebugOnOrOff ();
744 // are we viewing a page - both gui and text editors will have button named button_save
745 if (!document.getElementsByName('button_save').length) {
746 setSpanTags(0);
747 return;
748 }
749 // we are in editor -- is there a line number specified in URL?
750 var lineMatch = document.location.search.match(/line=(\d*)/);
751 if (lineMatch) {
752 scrollTextarea(lineMatch[1]);
753 return;
754 }
755 if (document.getElementById('preview')) {
756 // is an editor preview
757 setSpanTags(1);
758 }
759 }
760
761 // The DOM ready check for Internet Explorer
762 function ieScrollCheck() {
763 try {
764 // If IE is used, use the trick by Diego Perini
765 document.documentElement.doScroll("left");
766 } catch( error ) {
767 setTimeout( ieScrollCheck, 1 );
768 return;
769 }
770 scrollTextareaInit();
771 }
772
773 // run auto scroll init As Soon As Possible -- prior to onload for modern browsers
774 function runASAP() {
775 if (document.addEventListener) {
776 // Firefox 3.6, Chrome 4.0.249.89, Safari for Windows 4.04, Opera 10.5beta, and maybe older versions
777 // schedule func to be run when DOM complete, usually before last image loaded
778 document.addEventListener("DOMContentLoaded", scrollTextareaInit, false);
779 } else {
780 if (document.documentElement.doScroll && window == window.top) {
781 // IE 5-8 and not using frames
782 ieScrollCheck();
783 } else {
784 addLoadEvent(scrollTextareaInit);
785 }
786 }
787 }
788 // auto scroll initialization starts here
789 runASAP();
Attached Files
To refer to attachments on a page, use attachment:filename, as shown below in the list of files. Do NOT use the URL of the [get] link, since this is subject to change and can break easily.You are not allowed to attach a file to this page.