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.