PageSourceSearch

https://kernelnewbies.org/moin_static1911/common/js/common.js

js kernelnewbies.org collected 2026-09-24 08:30:44 UTC 27,963 bytes, 787 lines download raw bytes

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

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.