1// using version of bind from prototype for scoping purposes 2Function.prototype.mybicBind = function(object) { 3 var __method = this; 4 return function() { 5 return __method.apply(object, arguments); 6 } 7}; 8 9/** 10* Constructor for MyBIC's ajax object 11* This only needs to be instantiated once in your script and you'll be able to re-use the same object for all your requests 12*@constructor 13*@author Jim Plush [email protected] 14*@param {string} server_url The URL of the page you're going to connect to on the server, by default mybic_server.php 15*@param {string} readyStateFunction (OPTIONAL)The function that will be called when ajax responses come back from the server, by default mybic handles this for you 16*/ 17function XMLHTTP(server_url, readyStateFunction) 18{ 19 /** 20 * the SERVER page URL to connect to IE ajax_server.php 21 *@type String 22 */ 23 this.server_url = server_url; 24 25 /** 26 * whether we're in syncronous mode or async (default), syncronous means the UI will lock up until the response is received - you rarely would want this. 27 *@type String 28 */ 29 this.async = true; 30 31 /** 32 * debug turned off by default, to see your request/response do ajaxObj.debug=1, useful for seeing what's going on with your ajax requests 33 *@type int 34 */ 35 this.debug=0; 36 37 /** 38 * this enables throttling by default so all your requests are in the proper order 39 *@type int 40 */ 41 this.throttle=1; 42 43 /** 44 * by default all requests are sent via POST to override just use ajaxObj.method="GET"; before your call 45 *@type String 46 */ 47 this.method = "POST"; 48 49 /** 50 * by default JSON encoding is the expected format, to override: ajaxObj.format = "XML"; or ajaxObj.format="TEXT"; 51 * if you're planning to just load HTML snippets for innerHTML use, just set this to TEXT 52 *@type String 53 */ 54 this.format = "JSON"; 55 56 /** 57 * array of optional headers you may pass in 58 *@type Array 59 */ 60 this.headers = new Array(); 61 62 /** 63 * the number of seconds to wait before calling network down function, set to -1 disable feature, defaults to 5 seconds 64 *@type int 65 */ 66 this.abort_timeout = 30000; 67 68 /** 69 * the number of failed requests before mybic is disabled -> prevents repeated error notifications, no more ajax requests will fire after this amount of failures 70 *@type int 71 */ 72 this.failed_threshold = 3; 73 74 /** 75 * set this to 1 if you have a polling object and you don't want to see debug msgs every second or activity indicators, nice to keep out of firebug 76 *@type 77 */ 78 this.ignoreCall = 0; 79 80 /** 81 * set this to one in your client code if you want to make sure your callback functions completes before making another ajax call in the queue 82 *@type int 83 */ 84 this.stopRequest = 0; 85 86 /** 87 * ERROR HANDLERS YOU CAN SET, TO OVERRIDE OR COMPLIMENT EXISTING FUNCTIONALITY 88 */ 89 90 /** 91 * Set this to a function in your website that will handle pop up errors in your call back function more gracefully DO FOR LIVE SITES! 92 * this is used when your callback function experiences a fatal error, mybic can execute a nicer function for you and pass you the error object 93 * note: do not assign with parens, do this ajaxObj.jsErrorHandler = myFunction; 94 *@type function 95 */ 96 this.jsErrorHandler = ''; 97 98 /** 99 * set this to a function in your website that will handle pop up errors in your call back function more gracefully 100 */ 101 this.notAuthorizedHandler = ''; 102 103 /** 104 * the function that will be called if mybic cannot make a request to the server (server down) 105 * if 'disabled' is passed to your function, then no more ajax calls can be made, you might want to reload the whole page at this point 106 */ 107 this.net_down_func = this.down; 108 109 110 /*-- SYSTEM PROPERTIES - no need to change the properites below --*/ 111 /** 112 *@private 113 */ 114 this.version = '1.0.1'; 115 116 /** 117 * the xmlhttprequest variable, starts off as null 118 *@private 119 */ 120 this.req = null; 121 122 /** 123 * used for showing expandable visual debug data 124 *@private 125 */ 126 this.debugID = 0; 127 128 /** 129 * array of errors generated 130 *@private 131 */ 132 this.errors = new Array(); 133 134 /** 135 * the queue that will handle the throttling requests to keep your stuff in sync 136 *@private 137 */ 138 this.queue = new Array(); 139 140 /** 141 * the current index for the throttling array 142 *@private 143 */ 144 this.queue_in_process = 0; 145 146 /** 147 * system uses this to see what calls to ignore from the queue 148 *@private 149 */ 150 this.currentCallIgnore=0; 151 152 /** 153 * the timer used to check the readystate of the xmlhttprequest to prevent memory leaks 154 *@private 155 */ 156 this.readySateTimer = ''; 157 158 /**
159 * the callback function, when the ajax request is sent, this is the function that will be called 160 *@private 161 */ 162 this.callBack = ''; 163 164 /** 165 * cache which version of msxml to use on IE to avoid using the loop every time 166 *@private 167 */ 168 this.IEObjCache = 0; 169 170 /** 171 * number of failed requests in a row 172 *@private 173 */ 174 this.failed_requests=0 175 176 /** 177 * holds the callback function for ajax calls 178 *@private 179 */ 180 this.readyStateFunction = (readyStateFunction) ? readyStateFunction : this.responseHandler; 181 182 /** 183 * holds the current queue of msgs to try to match up request/responses 184 *@private 185 */ 186 this._msgQueueInfo = new Array(); 187 188 /** 189 * the timer used to check the readystate of the xmlhttprequest to prevent memory leaks 190 *@private 191 */ 192 this.readyStateTimer = ''; 193 194 /** 195 * the time interval used to check the readystate of the xmlhttprequest to prevent memory leaks 196 *@private 197 */ 198 this.poolTimerInterval = 50; 199 200} 201 202/** 203* Method to create an XMLHTTP object 204*@access private 205*/ 206XMLHTTP.prototype = { 207 getXMLHTTP:function() { 208 209 // moz-IE7 XMLHTTPRequest object 210 if (window.XMLHttpRequest) { this.req = new XMLHttpRequest(); } 211 else if (this.IEObjCache != 0) { alert(this.IEObjCache);try {this.req = new ActiveXObject(this.IEObjCache);}catch(e){} } 212 else if (window.ActiveXObject){ 213 // 6.0 is recommended for all vista + users, 3.0 is recommended over all 4 & 5 versions 214 var progIDs = [ 'MSXML2.XMLHTTP.6.0','MSXML2.XMLHTTP.3.0','Microsoft.XMLHTTP']; 215 for (var i = 0; i < progIDs.length; i++) { 216 try { 217 this.req = new ActiveXObject(progIDs[i]); 218 this.IEObjCache = progIDs[i]; 219 break; 220 } 221 catch (ex) {} 222 } 223 } else { 224 if(this.debug == 1) { this.showDebug("<BR>FATAL ERROR: Could not create XMLHTTPRequest Object!<BR>"); } 225 } 226 return this.req; 227 }, 228 /** 229 * Main API method to use for AJAX requests 230 * example: ajaxObj.call("action=loadComments&id=1", myCallBackFunction); 231 *@access public 232 *@param string A url encoded string of data to send to the server 233 *@param string A callback function that the server will launch when the response is generated 234 *@param string Used by the response handler function to send back throttled requests, you won't need to worry about this param 235 */ 236 call:function(queryVars, userCallback, queue_request) { 237 238 // test for too many failed requests 239 if(this.failed_requests >= this.failed_threshold) { 240 // call network down method with instruction to notify of mybic being disabled 241 this.net_down_func('disable'); 242 return false; 243 } else { 244 var currentVars; 245 var callback; 246 this.fullUrl = ''; 247 248 if(this.throttle == 1 && queue_request != 'queue' || this.stopRequest == 1) { // throttling keeps your requests in sync, so things aren't out of order 249 this.add2Queue(queryVars, userCallback); 250 } 251 252 if(this.queue_in_process == 0) { 253 if(!this.getXMLHTTP()) { 254 return false; 255 } 256 257 if(this.throttle == 1) { 258 this.queue_in_process = 1; 259 var currentCall = this.queue.shift(); // get the current call to make 260 currentVars = currentCall.queryVars; 261 callback = currentCall.userCallback; 262 this.format = currentCall.format; 263 this.method = currentCall.method; 264 this.abort_timeout = currentCall.abortTimeout; 265 this.currentCallIgnore = currentCall.ignoreCall; 266 this.async = currentCall.async; 267 } else { 268 currentVars = queryVars; 269 callback = userCallback; 270 var ignoreCall=0; 271 272 } 273 this.callBack = callback; 274 275 // check for JSON encoding 276 if(this.format != 'JSON') { 277 currentVars = currentVars+'&json=false'; 278 } 279 280 // if get is used, append the query variables to the url string 281 this.full_url = (this.method == "POST") ? this.server_url : this.server_url + '?'+ currentVars; 282 283 if(this.debug == 1 && this.currentCallIgnore != 1) { 284 try { 285 var matches = currentVars.match(/action=(\w+)&?/); 286 this.showDebug('new', 'MYBIC - CALLING: '+matches[1]); 287 this.showDebug("Server Page: "+this.server_url+"<BR>HTTP Method: "+this.method+"<BR>Encoding Format: "+this.format+"<BR>Query String: "+currentVars+"<BR>"); 288 }catch(e){} 289 } 290 291 // open connection 292 this.req.open(this.method, this.full_url, this.async); 293 294 // set any optional headers 295 if(this.headers){ 296 for(var i in this.headers) { 297 if(i != '' && (this.headers[i] instanceof String)) { 298 try { 299 this.req.setRequestHeader( i, this.headers[i]); 300 if(this.debug == 1) { this.showDebug('Setting Custom Header: '+this.headers[i]+'<br>');} 301 } catch(e) {} 302 } 303 } 304 } 305 // START TIMER TO ABORT REQUEST 306 if(this.abort_timeout != -1) { 307 this.end_timer = setInterval(this.endCall.mybicBind(this), this.abort_timeout); 308 } 309 // send request 310 if(this.method == 'POST') { 311 this.req.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); 312 this.request = currentVars; 313 this.req.send(currentVars); 314 } else { 315 this.req.send(null); 316 } 317 318 // START POLLING FOR READYSTATECHANGE 319 if (this.readyStateFunction) { 320 this.readyStateTimer = window.setInterval( 321 this.readyPoolFunc.mybicBind(this), 322 this.poolTimerInterval // poll every 50 milliseconds for ready state 323 ); 324 } 325 326 } 327 } 328 329 }, 330 331 /** 332 * 333 *@private 334 */ 335 readyPoolFunc:function() { 336 if(this.req && this.req.readyState == 4) { 337 window.clearInterval(this.readyStateTimer); 338 this.readyStateTimer = null; 339 // call the current response handlet - responseHandler by default 340 this.readyStateFunction(); 341 } 342 }, 343 344/** 345* Default method for parsing the response from the server. It will try to eval the obj.method_to_call property and pass the native JS object 346*private 347*/ 348 responseHandler:function() { 349 if(this.req) { 350 try { 351 // only if req shows "complete" 352 if (this.req.readyState == 4) { 353 // only if "OK" 354 if (this.req.status && this.req.status == 200) { 355 if(this.req.responseText.indexOf('ajax_msg_failed') != -1) { 356 this.showDebug("Fatal Error: mybic_server sent back ajax_msg_failed! - MSG: "+this.req.responseText+"<br/>"); 357 if(this.req.responseText.indexOf('notauth') != -1) { 358 if(this.abort_timeout != -1) { clearInterval(this.end_timer); } 359 if(this.notAuthorizedHandler == '') { 360 this.callBack('notauthorized'); 361 } else { 362 try { 363 this.notAuthorizedHandler(); 364 }catch(e) { 365 366 } 367 } 368 369 } else { 370 this.callBack(false); 371 } 372 } else { 373 // clear out network down timer 374 if(this.abort_timeout != -1) { 375 clearInterval(this.end_timer); 376 } 377 if(this.throttle == 1) { 378 var req = this._msgQueueInfo.shift(); 379 var format = req.format; 380 } else { 381 var format = this.format; 382 } 383 384 if(format == "JSON") { 385 try { 386 var myObject = JSON.parse(this.req.responseText); 387 // callback function we passed to the server to process the results 388 389 if(document.getElementById(this.callBack)) { 390 document.getElementById(this.callBack).innerHTML = myObject; 391 } else { 392 this.callBack(myObject); 393 } 394 395 } catch(e) { 396 397 if(this.jsErrorHandler == '') { 398 alert('An error occurred in your response function, NOT mybic related. Error Name: ' + e.name + ' Message:' + e.message); 399 } else { 400 // try to call the users javascript error handling function, have to show a popup
400if that sucker has en error in it too 401 try { this.jsErrorHandler(e); } catch(err) { alert('Error: your errorhandling function has an error - name: '+err.name + ' message: '+err.message)} 402 } 403 404 } 405 } else if(this.format == "XML") { 406 // send the raw xml data to the callback function 407 this.callBack(this.req.responseXML); 408 } else { 409 try { 410 if(document.getElementById(this.callBack)) { 411 document.getElementById(this.callBack).innerHTML = this.req.responseText; 412 } else { 413 this.callBack(this.req.responseText); 414 } 415 } catch(e) { 416 if(this.jsErrorHandler == '') { 417 alert('An error occurred in your response function, NOT mybic related. Error Name: ' + e.name + ' Message:' + e.message); 418 } else { 419 // try to call the users javascript error handling function, have to show a popup if that sucker has en error in it too 420 try { this.jsErrorHandler(e); } catch(err) { alert('Error: your errorhandling function has an error - name: '+err.name + ' message: '+err.message)} 421 } 422 } 423 424 } 425 426 } 427 428 this.failed_requests = 0; // reset failed requests back to 0 429 } else { 430 // server is came back with a bad status 431 try{ 432 this.showDebug("Fatal Error: MSG: "+this.req.responseText+" StatusText: "+this.req.statusText+"<br/>"); 433 } catch(e){} 434 this.endCall(); 435 } 436 try { 437 if(this.debug == 1 && this.currentCallIgnore != 1) { 438 // STRIP HTML 439 var str = this.req.responseText.replace(/(\<)/gi, '<'); 440 var str = str.replace(/(\>)/gi, '>'); 441 this.showDebug("HTTP Server Response:<br/> "+str+"<br>"); 442 } 443 } catch(e) { } 444 445 // reset the method, format, etc back to class defaults 446 this.restoreDefaults(); 447 448 // reset our queue and call 449 this.queue_in_process = 0; 450 this.req = null; 451 if(this.queue.length > 0) { 452 453 this.call('','','queue'); 454 } 455 } 456 } catch(e) { 457 /*network is down*/} 458 } 459 460 }, 461 462 463 /** 464 * This method will allow you to lazy load javascript source files for on-demand javascript processing 465 * Just pass in the url of the javascript file you wish to pull in and you're all set, its not ajaxified so you 466 * can pull in scripts from any URL you want! You can also use this function to remove scripts from the DOM as well 467 * Just pass in 'remove' as the 2nd parameter with the 1st parameter being the file you want to remove 468 * Removal is good for memory heavy desktop type apps you might be creating 469 *@param string The URL of the script you wish to load 470 *@param string OPTIONAL If you wish to remove a javascript file from the DOM then just pass in 'remove' as the 2nd parameter 471 */ 472 loadScript:function(url, remove) { 473 try{ 474 // lets check to see if the script is already loaded, if so lets remove it and add a new one 475 var scripts = document.getElementsByTagName('script'); 476 s_len = scripts.length; 477 for(var i=0;i<s_len;i++){ 478 var reg = new RegExp(url+"$"); 479 if (reg.test(scripts[i].src)) { 480 var p2 = scripts[i]; 481 p2.parentNode.removeChild(p2); 482 break; 483 } 484 } 485 if(remove != 'remove') { 486 newScript = document.createElement("script"); 487 newScript.setAttribute("type", "text/javascript"); 488 newScript.setAttribute("src", url); 489 document.getElementsByTagName('head')[0].appendChild(newScript); 490 } 491 } catch(e) { 492 this.showDebug("MyBIC - loadScript failed URL: "+url+" ErrName: "+e.name+" Msg: "+e.message); 493 } 494 495 }, 496 497 /** 498 * This method will allow you to create a "command queue" so ajax requests are sent in order they were fired. 499 * You will be able to keep your request/responses in order they were sent 500 *@private 501 */ 502 add2Queue:function(queryVars, userCallback) { 503 var addAjax = new Array(); 504 addAjax['queryVars'] = queryVars; 505 addAjax['userCallback'] = userCallback; 506 addAjax['ignoreCall'] = this.ignoreCall; 507 addAjax['abortTimeout'] = this.abort_timeout; 508 addAjax['format'] = this.format; 509 addAjax['method'] = this.method; 510 addAjax['async'] = this.async; 511 var opts = new Object(); 512 opts.format = this.format; 513 this._msgQueueInfo.push(opts); 514 this.ignoreCall=0; // reset back to original state 515 this.queue.push(addAjax); 516 }, 517 518 519 /** 520 * Method called after callback function is called to return the class to a default state 521 *@private 522 */ 523 restoreDefaults:function() 524 { 525 this.method = "POST"; 526 this.format = "JSON"; 527 this.callback = ""; 528 this.abort_timeout = 30000; 529 this.failed_threshold = 3; 530 this.async = true; 531 532 }, 533 534 /** 535 * This method will allow you to get all your form fields in ONE magical step! 536 * right before your ajaxObj.call statement all you have to do is: var form_vars = ajaxObj.getForm('formid'); 537 * that will loop through the form id you pass, and put all the form variables into your query string!
538 *@param string The ID of the form you wish to submit 539 *@return string An encoded query string, ready to send to the server 540 */ 541 542 getForm:function(formid) { 543 var formobj = document.getElementById(formid); 544 var fields = new Array(); 545 var form_len = formobj.elements.length; 546 for (var x = 0; x < form_len; x++) { 547 548 // rf, 10.07.2017, disabled elements may not be transfered 549 if (formobj.elements[x].disabled == true) continue; 550 551 switch(formobj.elements[x].type) { 552 case 'select-one': 553 554 fields.push(encodeURIComponent(formobj.elements[x].name)+'='+encodeURIComponent(formobj.elements[x].options[formobj.elements[x].selectedIndex].value)); 555 break; 556 case 'select-multiple': 557 var obj = formobj.elements[x]; 558 for(var y=0; y < formobj.elements[x].options.length; y++) { 559 if(formobj.elements[x].options[y].selected) { 560 if(formobj.elements[x].options[y].value == ''){ 561 fields.push(encodeURIComponent(formobj.elements[x].name)+'='+encodeURIComponent(formobj.elements[x].options[y].text)); 562 } else { 563 fields.push(encodeURIComponent(formobj.elements[x].name)+'='+encodeURIComponent(formobj.elements[x].options[y].value)); 564 } 565 } 566 } 567 break; 568 case 'radio': 569 if(formobj.elements[x].checked) { 570 fields.push(encodeURIComponent(formobj.elements[x].name)+'='+encodeURIComponent(formobj.elements[x].value)); 571 } 572 break; 573 case 'checkbox': 574 if(formobj.elements[x].checked) { 575 fields.push(encodeURIComponent(formobj.elements[x].name)+'='+encodeURIComponent(formobj.elements[x].value)); 576 } 577 break; 578 default: 579 // text, password, textarea, etc 580 fields.push(encodeURIComponent(formobj.elements[x].name)+'='+encodeURIComponent(formobj.elements[x].value)); 581 break; 582 } 583 } 584 var new_qstring = '&' + fields.join('&'); 585 return new_qstring; 586 }, 587 588 /** 589 * This method will check the request call after x number of seconds to see if the network call is still hanging 590 * You will want to use this when your server might be down and after 5 seconds you'll want to call a function that lets the 591 * user know you're having server issues 592 *@private 593 */ 594 endCall:function() { 595 try{ 596 this.net_down_func(); 597 this.req.abort(); 598 this.req = null; 599 clearInterval(this.end_timer); 600 clearInterval(this.readyStateTimer); 601 // increase failed requests variable 602 this.failed_requests++; 603 // reset our queue and call 604 this.queue_in_process = 0; 605 if(this.queue.length > 0) { 606 607 this.call('','','queue'); 608 } 609 610 if(this.debug == 1) { this.showDebug("Request Failed - Network Down! Current Failed Attempts: "+this.failed_requests+"<br>");} 611 } catch(e) { 612 // server is completely down, call netdown function 613 clearInterval(this.end_timer); 614 this.net_down_func('disable'); 615 } 616 this.req = null; 617 }, 618 619 /** 620 * Default method that will be called when mybic experiences a network down situation, or is disabled 621 * This method will pop up a div alerting the user of a general network error 622 * You should define your own method to properly fit in with your page layout 623 *@private 624 */ 625 down:function(status) { 626 var notif_div = '<div id="mybic_notification" style="text-align:center;padding:20px;position:absolute;top:100px;left:100px;width:300px;border:thin solid black;background-color:#F8F021;">'; 627 notif_div += '<span id="mybic_notif_msg"> MSGHERE </span> <br><br><input type="button" value="OK" onclick="document.getElementById(\'mybic_notification\').style.display=\'none\';"></div>'; 628 if(status == 'disable') { 629 var notif = 'A network issue has disabled network connections for this page. Please reload this page or contact the site administrator'; 630 } else { 631 var notif = 'A network issue has occurred which canceled your last request'; 632 } 633 // lets try and find an existing error message or use the current one in the DOM 634 try{ 635 if(document.getElementById('mybic_notification')) { 636 document.getElementById('mybic_notification').style.display='block'; 637 } else { 638 var new_div = document.createElement('div'); 639 new_div.innerHTML = notif_div; 640 document.body.appendChild(new_div); 641 } 642 document.getElementById('mybic_notif_msg').innerHTML = notif; 643 } catch(e) { 644 alert('Network Unavailable: Please re-load page or contact the site administrator'); 645 } 646 }, 647 648 /** 649 * This method will allow you to lazy load stylesheet source files for on-demand css 650 * Just pass in the url of the css file you wish to pull in and you're all set, its not ajaxified so you 651 * can pull in scripts from any URL you want. 652 *@param string The URL of the css file you wish to load /lib/css/myfile.css 653 */ 654 loadCSS:function(url) 655 { 656 try{ 657 // lets check to see if the script is already loaded, if so lets remove it and add a new one 658 var scripts = document.getElementsByTagName('link'); 659 s_len = scripts.length; 660 if(s_len > 0) { 661 for(var i=0;i<s_len;i++){ 662 var reg = new RegExp(url+"$"); 663 if (reg.test(scripts[i].href)) { 664 var p2 = scripts[i]; 665 p2.parentNode.removeChild(p2); 666 break; 667 } 668 } 669 } 670 newScript = document.createElement("link"); 671 newScript.setAttribute("type", "text/css"); 672 newScript.setAttribute("rel", "stylesheet"); 673 newScript.setAttribute("href", url); 674 document.getElementsByTagName('head')[0].appendChild(newScript); 675 676 } catch(e) { 677 if(this.debug==1) {this.showDebug("MyBIC - loadCSS failed URL: "+url+" ErrName: "+e.name+" Msg: "+e.message)}; 678 } 679 680 }, 681 682 /** 683 * This method will let developers view debug information on the screen from not only the system calls but also let them tap into it as well 684 *@access public 685 *@param string The Message you wish to push to debugging or pass in 'break' and the UI will break a new expandable column for you 686 *@param string OPTIONAL: If you pass in break, also send in a string that will show what the break label should be 687 *@param int OPTIONAL: If you pass in break, if you pass in a 1 to the function it will allow you have your section autoexpanded 688 */ 689 showDebug:function(msg, label, expand) { 690 if(this.debug == 1) 691 { 692 if(!document.getElementById('mybic_debug')) { 693 var errs = document.createElement('div'); 694 errs.id = 'mybic_errs'; 695 var deb = document.createElement('div'); 696 deb.id = 'mybic_debug'; 697 deb.style.border = "thick solid black"; 698 deb.style.backgroundColor = "#eeeeee"; 699 deb.style.padding = "10px"; 700 deb.style.margin = '75px 10px 10px 10px'; 701 deb.style.width = '90%'; 702 deb.style.position = 'absolute'; 703 deb.style.zIndex = '999'; 704 deb.innerHTML += 'MyBic Debugger: <a href="#" onclick="document.getElementById(\'mybic_errs\').style.display = (document.getElementById(\'mybic_errs\').style.display==\'none\') ? \'\':\'none\'; return false;" >hide/show me!</a>'; 705 deb.innerHTML += ' <a href="#" onclick="document.getElementById(\'mybic_errs\').innerHTML = \'\'; return false;">Clear</a>'; 706 deb.innerHTML += ' <a href="#" onclick="XMLHTTP.prototype.debug_expand(\'block\');return false;">Expand All</a>'; //TODO: 707 deb.innerHTML += ' <a href="#" onclick="XMLHTTP.prototype.debug_expand(\'none\'); return false;">Contract All</a><br><br>';//TODO: 708 deb.appendChild(errs); 709 if(document.body) { 710 document.body.appendChild(deb); 711 } else { 712 document.lastChild.appendChild(deb); 713 } 714 } 715 var deb = document.getElementById('mybic_errs'); 716 if(msg == 'new') { 717 this.debugID++; 718 var dimg = '<a style="color:white;font-size:1.1em;text-decoration:none" href="#" onclick="XMLHTTP.prototype.debug_expand(this);return false;">+</a>'; 719 deb.innerHTML += '<div id="mybiclabel_'+this.debugID+'" style="display:block;border:thin solid #999999;padding:2px;background-color:#cccccc;">'+dimg+' label'+this.debugID+': '+label+'</div>'; 720 } else { 721 deb.innerHTML +='<div class="mybic_debug'+this.debugID+'" style="padding:5px;display:none; border:thin solid white;">'+msg+'</div>'; 722 } 723 } 724 }, 725 726 727 /** 728 * This method is used by MyBic to visually show the debug data you've passed in 729 *@private 730 *@param object The image element that triggers the show/hide functionality 731 */ 732 debug_expand:function(el) { 733 var deb = document.getElementById('mybic_errs'); 734 var deb_len = deb.childNodes.length; 735 if(el == 'none' || el == 'block') { 736 var label = "mybic_debug"; 737 var links = deb.getElementsByTagName('a'); 738 var links_len = links.length; 739 for(var q=0;q<links_len;q++) { 740 links[q].innerHTML = (el == 'none') ? '+' : '>'; 741 } 742 } else { 743 var label = el.parentNode.id; 744 label = label.split('_'); 745 label = "mybic_debug"+label[1]; 746 } 747 for(var i=0; i<deb_len; i++) { 748 // loop through and show the elements with the right classname 749 try { 750 if(deb.childNodes[i].className.match(new RegExp("(^"+ label + ".*$)"))) { 751 if(el == 'none' || el == 'block') { 752 deb.childNodes[i].style.display = el; 753 } else { 754 if(deb.childNodes[i].style.display == 'block') { 755 el.innerHTML = '+'; 756 deb.childNodes[i].style.display = 'none'; 757 } else { 758 el.innerHTML = '>'; 759 deb.childNodes[i].style.display = 'block'; 760 } 761 } 762 } 763 } catch(e) {} 764 } 765 }, 766 767 /** 768 * This method is a wrapper for when you have a callback funciton that has to finish executing before any other ajax calls are made 769 * You may be in this situation when ajax calls rely on each other IE don't update this data until I finish processing the other data 770 */ 771 restart:function() { 772 this.stopRequest=0; 773 this.call('','','queue'); 774 } 775 776}; 777 778 779/****************************************************/ 780// INCLUDE JSON.ORG's JSON CLIENT SIDE SERIALIZER 781/* 782Copyright (c) 2005 JSON.org 783*/ 784 785/** 786* The global object JSON contains two methods. 787* 788* JSON.stringify(value) takes a JavaScript value and produces a JSON text. 789* The value must not be cyclical. 790*
791* JSON.parse(text) takes a JSON text and produces a JavaScript value. It will 792* return false if there is an error. 793*/ 794var JSON = function () { 795 var m = { 796 '\b': '\\b', 797 '\t': '\\t', 798 '\n': '\\n', 799 '\f': '\\f', 800 '\r': '\\r', 801 '"' : '\\"', 802 '\\': '\\\\' 803 }, 804 s = { 805 'boolean': function (x) { 806 return String(x); 807 }, 808 number: function (x) { 809 return isFinite(x) ? String(x) : 'null'; 810 }, 811 string: function (x) { 812 if (/["\\\x00-\x1f]/.test(x)) { 813 x = x.replace(/([\x00-\x1f\\"])/g, function(a, b) { 814 var c = m[b]; 815 if (c) { 816 return c; 817 } 818 c = b.charCodeAt(); 819 return '\\u00' + 820 Math.floor(c / 16).toString(16) + 821 (c % 16).toString(16); 822 }); 823 } 824 return '"' + x + '"'; 825 }, 826 object: function (x) { 827 if (x) { 828 var a = [], b, f, i, l, v; 829 if (x instanceof Array) { 830 a[0] = '['; 831 l = x.length; 832 for (i = 0; i < l; i += 1) { 833 v = x[i]; 834 f = s[typeof v]; 835 if (f) { 836 v = f(v); 837 if (typeof v == 'string') { 838 if (b) { 839 a[a.length] = ','; 840 } 841 a[a.length] = v; 842 b = true; 843 } 844 } 845 } 846 a[a.length] = ']'; 847 } else if (x instanceof Object) { 848 a[0] = '{'; 849 for (i in x) { 850 v = x[i]; 851 f = s[typeof v]; 852 if (f) { 853 v = f(v); 854 if (typeof v == 'string') { 855 if (b) { 856 a[a.length] = ','; 857 } 858 a.push(s.string(i), ':', v); 859 b = true; 860 } 861 } 862 } 863 a[a.length] = '}'; 864 } else { 865 return; 866 } 867 return a.join(''); 868 } 869 return 'null'; 870 } 871 }; 872 return { 873 copyright: '(c)2005 JSON.org', 874 license: 'http://www.JSON.org/license.html', 875/** 876* Stringify a JavaScript value, producing a JSON text. 877*/ 878 stringify: function (v) { 879 var f = s[typeof v]; 880 if (f) { 881 v = f(v); 882 if (typeof v == 'string') { 883 return v; 884 } 885 } 886 return null; 887 }, 888/* 889 Parse a JSON text, producing a JavaScript value. 890 It returns false if there is a syntax error. 891*/ 892 parse: function (text) { 893 try { 894 return !(/[^,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]/.test( 895 text.replace(/"(\\.|[^"\\])*"/g, ''))) && 896 eval('(' + text + ')'); 897 } catch (e) { 898 return false; 899 } 900 } 901 }; 902}();
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.