1var _____WB$wombat$assign$function_____ = function(name) {return (self._wb_wombat && self._wb_wombat.local_init && self._wb_wombat.local_init(name)) || self[name]; }; 2if (!self.__WB_pmw) { self.__WB_pmw = function(obj) { this.__WB_source = obj; return this; } } 3{ 4 let window = _____WB$wombat$assign$function_____("window"); 5 let self = _____WB$wombat$assign$function_____("self"); 6 let document = _____WB$wombat$assign$function_____("document"); 7 let location = _____WB$wombat$assign$function_____("location"); 8 let top = _____WB$wombat$assign$function_____("top"); 9 let parent = _____WB$wombat$assign$function_____("parent"); 10 let frames = _____WB$wombat$assign$function_____("frames"); 11 let opener = _____WB$wombat$assign$function_____("opener"); 12 13/*!======================================================================*\ 14|| #################################################################### || 15|| # vBulletin 3.8.1 16|| # ---------------------------------------------------------------- # || 17|| # Copyright ©2000-2009 Jelsoft Enterprises Ltd. All Rights Reserved. || 18|| # This file may not be redistributed in whole or significant part. # || 19|| # ---------------- VBULLETIN IS NOT FREE SOFTWARE ---------------- # || 20|| # http://www.vbulletin.com | http://www.vbulletin.com/license.html # || 21|| #################################################################### || 22\*======================================================================*/ 23 24/** 25* Handle Firebug calls when Firebug is not available (getfirebug.com) 26*/ 27if (!window.console || !console.firebug) 28{ 29 window.console = {}; 30 var names = ["log", "debug", "info", "warn", "error", "assert", "dir", "dirxml", "group", "groupEnd", "time", "timeEnd", "count", "trace", "profile", "profileEnd"]; 31 for (var i = 0; i < names.length; ++i) window.console[names[i]] = function() {}; 32} 33 34/** 35* Setup Variables 36* 37* @var string SESSIONURL - stores the session URL 38* @var string SECURITYTOKEN - token that should be passed with POST requests 39* @var array vbphrase - stores text phrases 40* @var array vB_Editor - array of vB_Text_Editor objects 41* @var boolean ignorequotechars - ignore characters inside [quote] tags for message length check 42* @var integer pagenavcounter - counts the number of pagenav instances encountered so far 43* @var boolean is_regexp - does window.regExp exist? - Catch errors with less capable browsers 44* @var boolean AJAX_Compatible - does the current browser support AJAX? 45* @var string pointer_cursor - help out old versions of IE that don't understand style.cursor = pointer 46* @var array Viewport info array 47* @var integer Length of standard AJAX timeout (ms) 48*/ 49var SESSIONURL = (typeof(SESSIONURL) == "undefined" ? "" : SESSIONURL); 50var SECURITYTOKEN = (typeof(SECURITYTOKEN) == "undefined" ? "" : SECURITYTOKEN); 51var vbphrase = (typeof(vbphrase) == "undefined" ? new Array() : vbphrase); 52var vB_Editor = new Array(); 53var ignorequotechars = false; 54var pagenavcounter = 0; 55var is_regexp = (window.RegExp) ? true : false; 56var AJAX_Compatible = false; 57var viewport_info = null; 58var vB_Default_Timeout = 15000; 59 60/** 61* Define the browser loading the page 62* 63* @var string userAgent Useragent string 64* @var boolean is_opera Opera 65* @var boolean is_saf Safari 66* @var boolean is_webtv WebTV 67* @var boolean is_ie Internet Explorer 68* @var boolean is_ie4 Internet Explorer 4 69* @var boolean is_ie7 Internet Explorer 7 70* @var boolean is_ps3 Playstation 3 71* @var boolean is_moz Mozilla / Firefox / Camino 72* @var boolean is_kon Konqueror 73* @var boolean is_ns Netscape 74* @var boolean is_ns4 Netscape 4 75* @var boolean is_mac Client is running MacOS 76*/ 77var userAgent = navigator.userAgent.toLowerCase(); 78var is_opera = ((userAgent.indexOf('opera') != -1) || (typeof(window.opera) != 'undefined')); 79var is_saf = ((userAgent.indexOf('applewebkit') != -1) || (navigator.vendor == 'Apple Computer, Inc.')); 80var is_webtv = (userAgent.indexOf('webtv') != -1); 81var is_ie = ((userAgent.indexOf('msie') != -1) && (!is_opera) && (!is_saf) && (!is_webtv)); 82var is_ie4 = ((is_ie) && (userAgent.indexOf('msie 4.') != -1)); 83var is_ie7 = ((is_ie) && (userAgent.indexOf('msie 7.') != -1)); 84var is_ps3 = (userAgent.indexOf('playstation 3') != -1); 85var is_moz = ((navigator.product == 'Gecko') && (!is_saf)); 86var is_kon = (userAgent.indexOf('konqueror') != -1); 87var is_ns = ((userAgent.indexOf('compatible') == -1) && (userAgent.indexOf('mozilla') != -1) && (!is_opera) && (!is_webtv) && (!is_saf)); 88var is_ns4 = ((is_ns) && (parseInt(navigator.appVersion) == 4)); 89var is_mac = (userAgent.indexOf('mac') != -1); 90 91/** 92* @var string pointer_cursor - help out old versions of IE that don't understand style.cursor = pointer 93*/ 94var pointer_cursor = (is_ie ? 'hand' : 'pointer'); 95 96/** 97* Workaround for heinous IE bug - add special vBlength property to all strings
98* This method is applied to ALL string objects automatically 99* 100* @return integer 101*/ 102String.prototype.vBlength = function() 103{ 104 return (is_ie && this.indexOf("\n") != -1) ? this.replace(/\r?\n/g, "_").length : this.length; 105} 106 107/** 108* Overrides IE's original String.prototype.substr to accept negative values 109* 110* @param integer Substring start position 111* @param integer Substring length 112* 113* @return string 114*/ 115if ("1234".substr(-2, 2) == "12") // (which would be incorrect) 116{ 117 String.prototype.substr_orig = String.prototype.substr; 118 119 String.prototype.substr = function(start, length) 120 { 121 if (typeof(length) == "undefined") 122 { 123 return this.substr_orig((start < 0 ? this.length + start : start)); 124 } 125 else 126 { 127 return this.substr_orig((start < 0 ? this.length + start : start), length); 128 } 129 }; 130} 131 132/** 133* Define Array.shift() for browsers that don't have it 134*/ 135if (typeof Array.prototype.shift === 'undefined') 136{ 137 Array.prototype.shift = function() 138 { 139 for(var i = 0, b = this[0], l = this.length-1; i < l; i++) 140 { 141 this[i] = this[i + 1]; 142 } 143 this.length--; 144 return b; 145 }; 146} 147 148/** 149* Function to emulate document.getElementById 150* 151* @param string Object ID 152* 153* @return mixed null if not found, object if found 154*/ 155function fetch_object(idname) 156{ 157 if (document.getElementById) 158 { 159 return document.getElementById(idname); 160 } 161 else if (document.all) 162 { 163 return document.all[idname]; 164 } 165 else if (document.layers) 166 { 167 return document.layers[idname]; 168 } 169 else 170 { 171 return null; 172 } 173} 174 175/** 176* Function to emulate document.getElementsByTagName 177* 178* @param object Parent object (eg: document) 179* @param string Tag type (eg: 'td') 180* 181* @return array 182*/ 183function fetch_tags(parentobj, tag) 184{ 185 if (parentobj == null) 186 { 187 return new Array(); 188 } 189 else if (typeof parentobj.getElementsByTagName != 'undefined') 190 { 191 return parentobj.getElementsByTagName(tag); 192 } 193 else if (parentobj.all && parentobj.all.tags) 194 { 195 return parentobj.all.tags(tag); 196 } 197 else 198 { 199 return new Array(); 200 } 201} 202 203/** 204* Function to count the number of tags in an object 205* 206* @param object Parent object (eg: document) 207* @param string Tag type (eg: 'td') 208* 209* @return integer 210*/ 211function fetch_tag_count(parentobj, tag) 212{ 213 return fetch_tags(parentobj, tag).length; 214} 215 216// ############################################################################# 217// Event handlers 218 219/** 220* Handles the different event models of different browsers and prevents event bubbling 221* 222* @param event Event object 223* 224* @return event 225*/ 226function do_an_e(eventobj) 227{ 228 if (!eventobj || is_ie) 229 { 230 window.event.returnValue = false; 231 window.event.cancelBubble = true; 232 return window.event; 233 } 234 else 235 { 236 eventobj.stopPropagation(); 237 eventobj.preventDefault(); 238 return eventobj; 239 } 240} 241 242/** 243* Handles the different event models of different browsers and prevents event bubbling in a lesser way than do_an_e() 244* 245* @param event Event object 246* 247* @return event 248*/ 249function e_by_gum(eventobj) 250{ 251 if (!eventobj || is_ie) 252 { 253 window.event.cancelBubble = true; 254 return window.event; 255 } 256 else 257 { 258 if (eventobj.target.type == 'submit') 259 { 260 // naughty safari 261 eventobj.target.form.submit(); 262 } 263 eventobj.stopPropagation(); 264 return eventobj; 265 } 266} 267 268// ############################################################################# 269// Message manipulation and validation 270 271/** 272* Checks that a message is valid for submission to PHP 273* 274* @param string Message text 275* @param mixed Either subject text (if you want to make sure it exists) or 0 if you don't care 276* @param integer Minimum acceptable character limit for the message 277* 278* @return boolean 279*/ 280function validatemessage(messagetext, subjecttext, minchars) 281{ 282 if (is_kon || is_saf || is_webtv) 283 { 284 // ignore less-than-capable browsers 285 return true; 286 } 287 else if (subjecttext.length < 1) 288 { 289 // subject not specified 290 alert(vbphrase['must_enter_subject']); 291 return false; 292 } 293 else 294 { 295 var stripped = PHP.trim(stripcode(messagetext, false, ignorequotechars)); 296 297 if (stripped.length < minchars) 298 { 299 // minimum message length not met 300 alert(construct_phrase(vbphrase['message_too_short'], minchars)); 301 return false;
302 } 303 else if (typeof(document.forms.vbform) != 'undefined' && typeof(document.forms.vbform.imagestamp) != 'undefined') 304 { 305 // This form has image verification enabled 306 document.forms.vbform.imagestamp.failed = false; 307 308 if (document.forms.vbform.imagestamp.value.length != 6) 309 { 310 alert(vbphrase['complete_image_verification']); 311 document.forms.vbform.imagestamp.failed = true; 312 document.forms.vbform.imagestamp.focus(); 313 return false; 314 } 315 else 316 { 317 return true; 318 } 319 } 320 else 321 { 322 // everything seems ok 323 return true; 324 } 325 } 326} 327 328 329/** 330* Strips quotes and bbcode tags from text 331* 332* @param string Text to manipulate 333* @param boolean If true, strip <x> otherwise strip [x] 334* @param boolean If true, strip all [quote]...contents...[/quote] 335* 336* @return string 337*/ 338function stripcode(str, ishtml, stripquotes) 339{ 340 if (!is_regexp) 341 { 342 return str; 343 } 344 345 if (stripquotes) 346 { 347 var start_time = new Date().getTime(); 348 349 while ((startindex = PHP.stripos(str, '[quote')) !== false) 350 { 351 if (new Date().getTime() - start_time > 2000) 352 { 353 // while loop has been running for over 2 seconds and has probably gone infinite 354 break; 355 } 356 357 if ((stopindex = PHP.stripos(str, '[/quote]')) !== false) 358 { 359 fragment = str.substr(startindex, stopindex - startindex + 8); 360 str = str.replace(fragment, ''); 361 } 362 else 363 { 364 break; 365 } 366 str = PHP.trim(str); 367 } 368 } 369 370 if (ishtml) 371 { 372 // exempt image tags -- they need to count as characters in the string 373 // as the do as BB codes 374 str = str.replace(/<img[^>]+src="([^"]+)"[^>]*>/gi, '$1'); 375 376 var html1 = new RegExp("<(\\w+)[^>]*>", 'gi'); 377 var html2 = new RegExp("<\\/\\w+>", 'gi'); 378 379 str = str.replace(html1, ''); 380 str = str.replace(html2, ''); 381 382 var html3 = new RegExp('( )', 'gi'); 383 str = str.replace(html3, ' '); 384 } 385 else 386 { 387 var bbcode1 = new RegExp("\\[(\\w+)(=[^\\]]*)?\\]", 'gi'); 388 var bbcode2 = new RegExp("\\[\\/(\\w+)\\]", 'gi'); 389 390 str = str.replace(bbcode1, ''); 391 str = str.replace(bbcode2, ''); 392 } 393 394 return str; 395} 396 397// ############################################################################# 398// vB_PHP_Emulator class 399// ############################################################################# 400 401/** 402* PHP Function Emulator Class 403*/ 404function vB_PHP_Emulator() 405{ 406} 407 408// ============================================================================= 409// vB_PHP_Emulator Methods 410 411/** 412* Find a string within a string (case insensitive) 413* 414* @param string Haystack 415* @param string Needle 416* @param integer Offset 417* 418* @return mixed Not found: false / Found: integer position 419*/ 420vB_PHP_Emulator.prototype.stripos = function(haystack, needle, offset) 421{ 422 if (typeof offset == 'undefined') 423 { 424 offset = 0; 425 } 426 427 index = haystack.toLowerCase().indexOf(needle.toLowerCase(), offset); 428 429 return (index == -1 ? false : index); 430} 431 432/** 433* Trims leading whitespace 434* 435* @param string String to trim 436* 437* @return string 438*/ 439vB_PHP_Emulator.prototype.ltrim = function(str) 440{ 441 return str.replace(/^\s+/g, ''); 442} 443 444/** 445* Trims trailing whitespace 446* 447* @param string String to trim 448* 449* @return string 450*/ 451vB_PHP_Emulator.prototype.rtrim = function(str) 452{ 453 return str.replace(/(\s+)$/g, ''); 454} 455 456/** 457* Trims leading and trailing whitespace 458* 459* @param string String to trim 460* 461* @return string 462*/ 463vB_PHP_Emulator.prototype.trim = function(str) 464{ 465 return this.ltrim(this.rtrim(str)); 466} 467 468/** 469* Emulation of PHP's preg_quote() 470* 471* @param string String to process 472* 473* @return string 474*/ 475vB_PHP_Emulator.prototype.preg_quote = function(str) 476{ 477 // replace + { } ( ) [ ] | / ? ^ $ \ . = ! < > : * with backslash+character 478 return str.replace(/(\+|\{|\}|\(|\)|\[|\]|\||\/|\?|\^|\$|\\|\.|\=|\!|\<|\>|\:|\*)/g, "\\$1"); 479} 480 481/** 482* Emulates PHP's preg_match_all()... sort of 483* 484* @param string Haystack 485* @param string Regular expression - to be inserted into RegExp(x) 486* 487* @return mixed Array on match, false on no match 488*/ 489vB_PHP_Emulator.prototype.match_all = function(string, regex) 490{ 491 var gmatch = string.match(RegExp(regex, "gim")); 492 if (gmatch) 493 { 494 var matches = new Array(); 495 496 var iregex = new RegExp(regex, "im"); 497 for (var i = 0; i < gmatch.length; i++) 498 { 499 matches[matches.length] = gmatch[i].match(iregex); 500 } 501 502 return matches; 503 } 504 else 505 { 506 return false;
507 } 508} 509 510/** 511* Emulates unhtmlspecialchars in vBulletin 512* 513* @param string String to process 514* 515* @return string 516*/ 517vB_PHP_Emulator.prototype.unhtmlspecialchars = function(str) 518{ 519 var f = new Array(/</g, />/g, /"/g, /&/g); 520 var r = new Array('<', '>', '"', '&'); 521 522 for (var i in f) 523 { 524 if (YAHOO.lang.hasOwnProperty(f, i)) 525 { 526 str = str.replace(f[i], r[i]); 527 } 528 } 529 530 return str; 531} 532 533/** 534* Unescape CDATA from vB_AJAX_XML_Builder PHP class 535* 536* @param string Escaped CDATA 537* 538* @return string 539*/ 540vB_PHP_Emulator.prototype.unescape_cdata = function(str) 541{ 542 var r1 = /<\=\!\=\[\=C\=D\=A\=T\=A\=\[/g; 543 var r2 = /\]\=\]\=>/g; 544 545 return str.replace(r1, '<![CDATA[').replace(r2, ']]>'); 546} 547 548/** 549* Emulates PHP's htmlspecialchars() 550* 551* @param string String to process 552* 553* @return string 554*/ 555vB_PHP_Emulator.prototype.htmlspecialchars = function(str) 556{ 557 //var f = new Array(/&(?!#[0-9]+;)/g, /</g, />/g, /"/g); 558 var f = new Array( 559 (is_mac && is_ie ? new RegExp('&', 'g') : new RegExp('&(?!#[0-9]+;)', 'g')), 560 new RegExp('<', 'g'), 561 new RegExp('>', 'g'), 562 new RegExp('"', 'g') 563 ); 564 var r = new Array( 565 '&', 566 '<', 567 '>', 568 '"' 569 ); 570 571 for (var i = 0; i < f.length; i++) 572 { 573 str = str.replace(f[i], r[i]); 574 } 575 576 return str; 577} 578 579/** 580* Searches an array for a value 581* 582* @param string Needle 583* @param array Haystack 584* @param boolean Case insensitive 585* 586* @return integer Not found: -1 / Found: integer index 587*/ 588vB_PHP_Emulator.prototype.in_array = function(ineedle, haystack, caseinsensitive) 589{ 590 var needle = new String(ineedle); 591 var i; 592 593 if (caseinsensitive) 594 { 595 needle = needle.toLowerCase(); 596 for (i in haystack) 597 { 598 if (YAHOO.lang.hasOwnProperty(haystack, i)) 599 { 600 if (haystack[i].toLowerCase() == needle) 601 { 602 return i; 603 } 604 } 605 } 606 } 607 else 608 { 609 for (i in haystack) 610 { 611 if (YAHOO.lang.hasOwnProperty(haystack, i)) 612 { 613 if (haystack[i] == needle) 614 { 615 return i; 616 } 617 } 618 } 619 } 620 return -1; 621} 622 623/** 624* Emulates PHP's strpad() 625* 626* @param string Text to pad 627* @param integer Length to pad 628* @param string String with which to pad 629* 630* @return string 631*/ 632vB_PHP_Emulator.prototype.str_pad = function(text, length, padstring) 633{ 634 text = new String(text); 635 padstring = new String(padstring); 636 637 if (text.length < length) 638 { 639 padtext = new String(padstring); 640 641 while (padtext.length < (length - text.length)) 642 { 643 padtext += padstring; 644 } 645 646 text = padtext.substr(0, (length - text.length)) + text; 647 } 648 649 return text; 650} 651 652/** 653* A sort of emulation of PHP's urlencode - not 100% the same, but accomplishes the same thing 654* 655* @param string String to encode 656* 657* @return string 658*/ 659vB_PHP_Emulator.prototype.urlencode = function(text) 660{ 661 text = escape(text.toString()).replace(/\+/g, "%2B"); 662 663 // this escapes 128 - 255, as JS uses the unicode code points for them. 664 // This causes problems with submitting text via AJAX with the UTF-8 charset. 665 var matches = text.match(/(%([0-9A-F]{2}))/gi); 666 if (matches) 667 { 668 for (var matchid = 0; matchid < matches.length; matchid++) 669 { 670 var code = matches[matchid].substring(1,3); 671 if (parseInt(code, 16) >= 128) 672 { 673 text = text.replace(matches[matchid], '%u00' + code); 674 } 675 } 676 } 677 678 // %25 gets translated to % by PHP, so if you have %25u1234, 679 // we see it as %u1234 and it gets translated. So make it %u0025u1234, 680 // which will print as %u1234! 681 text = text.replace('%25', '%u0025'); 682 683 return text; 684} 685 686/** 687* Works a bit like ucfirst, but with some extra options 688* 689* @param string String with which to work 690* @param string Cut off string before first occurence of this string 691* 692* @return string 693*/ 694vB_PHP_Emulator.prototype.ucfirst = function(str, cutoff) 695{ 696 if (typeof cutoff != 'undefined') 697 { 698 var cutpos = str.indexOf(cutoff); 699 if (cutpos > 0) 700 { 701 str = str.substr(0, cutpos); 702 } 703 } 704 705 str = str.split(' '); 706 for (var i = 0; i < str.length; i++) 707 { 708 str[i] = str[i].substr(0, 1).toUpperCase() + str[i].substr(1); 709 } 710 return str.join(' '); 711} 712 713// ############################################################################# 714// vB_AJAX_Handler 715// ############################################################################# 716 717/** 718* XML Sender Class - deprecated. Here for BC only. Use YAHOO.util.Connect.asyncRequest instead. 719* 720* @param boolean Should connections be asyncronous? (Now redundant) 721*/ 722function vB_AJAX_Handler(async) { this.async = async ? true : false; this.conn = null; }; 723vB_AJAX_Handler.prototype.init = function() { return AJAX_Compatible; }; 724vB_AJAX_Handler.is_compatible = function() { return AJAX_Compatible; }; 725vB_AJAX_Handler.prototype.onreadystatechange = function(callback) { this.callback = callback; }; 726vB_AJAX_Handler.prototype.fetch_data = function(xml_node) { 727 console.warn("vB_AJAX_Handler.prototype.fetch_data() is deprecated.\nUse responseXML.getElementsByTagName(\"x\")[i].firstChild.nodeValue instead."); 728 if (xml_node && xml_node.firstChild && xml_node.firstChild.nodeValue) { return PHP.unescape_cdata(xml_node.firstChild.nodeValue); } else { return ''; } 729}; 730vB_AJAX_Handler.prototype.send = function(desturl, datastream) { 731 this.conn = YAHOO.util.Connect.asyncRequest("POST", desturl, { success: this.callback }, datastream + "&securitytoken=" + SECURITYTOKEN + "&s=" + fetch_sessionhash());
732 this.handler = this.conn.conn; 733}; 734 735/** 736* Checks to see if this Javascript-aware browser is also capable of handling AJAX requests 737* 738* @return boolean 739*/ 740function is_ajax_compatible() 741{ 742 if (typeof vb_disable_ajax != "undefined" && vb_disable_ajax == 2) 743 { 744 return false; 745 } 746 else if (is_ie && !is_ie4) 747 { 748 return true; 749 } 750 else if (window.XMLHttpRequest) 751 { 752 try 753 { 754 var ajax_test = new XMLHttpRequest(); 755 return ajax_test.setRequestHeader ? true : false; 756 } 757 catch(e) 758 { 759 return false; 760 } 761 } 762 else 763 { 764 return false; 765 } 766} 767 768// we can check this variable to see if browser is AJAX compatible 769AJAX_Compatible = is_ajax_compatible(); 770console.info("This browser is%s AJAX compatible", AJAX_Compatible ? "" : " NOT"); 771 772// ############################################################################# 773// YUI AJAX Stuff 774// ############################################################################# 775 776/** 777* Handles AJAX request timeouts returned from YUI connection manager 778* 779* @param object YUI AJAX 780*/ 781function vBulletin_AJAX_Error_Handler(ajax) 782{ 783 /** 784 * Available properties of ajax object 785 * 786 * .tId 787 * .status 788 * .statusText 789 * .getResponseHeader[ ] 790 * .getAllResponseHeaders 791 * .responseText 792 * .responseXML 793 * .argument 794 */ 795 console.warn("AJAX Error: Status = %s: %s", ajax.status, ajax.statusText); 796} 797 798// ############################################################################# 799// vB_Hidden_Form 800// ############################################################################# 801 802/** 803* Form Generator Class 804* 805* Builds a form filled with hidden fields for invisible submit via POST 806* 807* @param string Script (my_target_script.php) 808*/ 809function vB_Hidden_Form(script) 810{ 811 this.action = script; 812 this.variables = new Array(); 813} 814 815// ============================================================================= 816// vB_Hidden_Form methods 817 818/** 819* Adds a hidden input field to the form object 820* 821* @param string Name attribute 822* @param string Value attribute 823*/ 824vB_Hidden_Form.prototype.add_variable = function(name, value) 825{ 826 this.variables[this.variables.length] = new Array(name, value); 827 console.log("vB_Hidden_Form :: add_variable(%s)", name); 828}; 829 830/** 831* Fetches all form elements inside an HTML element and performs 'add_input()' on them 832* 833* @param object HTML element to search 834*/ 835vB_Hidden_Form.prototype.add_variables_from_object = function(obj) 836{ 837 if (!obj) 838 { 839 return; 840 } 841 console.info("vB_Hidden_Form :: add_variables_from_object(%s)", obj.id); 842 var inputs = fetch_tags(obj, 'input'); 843 var i; 844 845 for (i = 0; i < inputs.length; i++) 846 { 847 switch (inputs[i].type) 848 { 849 case 'checkbox': 850 case 'radio': 851 if (inputs[i].checked) 852 { 853 this.add_variable(inputs[i].name, inputs[i].value); 854 } 855 break; 856 case 'text': 857 case 'hidden': 858 case 'password': 859 this.add_variable(inputs[i].name, inputs[i].value); 860 break; 861 default: 862 continue; 863 } 864 } 865 866 var textareas = fetch_tags(obj, 'textarea'); 867 for (i = 0; i < textareas.length; i++) 868 { 869 this.add_variable(textareas[i].name, textareas[i].value); 870 } 871 872 var selects = fetch_tags(obj, 'select'); 873 for (i = 0; i < selects.length; i++) 874 { 875 if (selects[i].multiple) 876 { 877 for (var j = 0; j < selects[i].options.length; j++) 878 { 879 if (selects[i].options[j].selected) 880 { 881 this.add_variable(selects[i].name, selects[i].options[j].value); 882 } 883 } 884 } 885 else 886 { 887 this.add_variable(selects[i].name, selects[i].options[selects[i].selectedIndex].value); 888 } 889 } 890}; 891 892/** 893* Fetches a variable value 894* 895* @param string Variable name 896* 897* @return mixed Variable value 898*/ 899vB_Hidden_Form.prototype.fetch_variable = function(varname) 900{ 901 for (var i = 0; i < this.variables.length; i++) 902 { 903 if (this.variables[i][0] == varname) 904 { 905 return this.variables[i][1]; 906 } 907 } 908 909 return null; 910}; 911 912/** 913* Submits the hidden form object 914*/ 915vB_Hidden_Form.prototype.submit_form = function() 916{ 917 this.form = document.createElement('form'); 918 this.form.method = 'post'; 919 this.form.action = this.action; 920 921 for (var i = 0; i < this.variables.length; i++) 922 { 923 var inputobj = document.createElement('input'); 924 925 inputobj.type = 'hidden'; 926 inputobj.name = this.variables[i][0]; 927 inputobj.value = this.variables[i][1]; 928 929 this.form.appendChild(inputobj); 930 } 931 932 console.info("vB_Hidden_Form :: submit_form() -> %s", this.action); 933 document.body.appendChild(this.form).submit(); 934}; 935 936/** 937* Builds a URI query string from the given variables 938*/ 939vB_Hidden_Form.prototype.build_query_string = function() 940{ 941 var query_string = ''; 942 943 for (var i = 0; i < this.variables.length; i++) 944 { 945 query_string += this.variables[i][0] + '=' + PHP.urlencode(this.variables[i][1]) + '&'; 946 } 947 948 console.info("vB_Hidden_Form :: Query String = %s", query_string); 949 return query_string; 950} 951 952/** 953* Legacy functions for backward compatability 954*/ 955vB_Hidden_Form.prototype.add_input = vB_Hidden_Form.prototype.add_variable;
956vB_Hidden_Form.prototype.add_inputs_from_object = vB_Hidden_Form.prototype.add_variables_from_object; 957 958 959// ############################################################################# 960// vB_Select_Overlay_Handler 961// ############################################################################# 962 963/** 964* Handler for <select> tags that are overlayed with another element 965* Fixes a problem in IE versions older than IE7. 966* 967* @param mixed Object or ID string that is the overlayed object 968*/ 969function vB_Select_Overlay_Handler(overlay) 970{ 971 this.browser_affected = (is_ie && !is_ie7); 972 973 if (this.browser_affected) 974 { 975 this.overlay = YAHOO.util.Dom.get(overlay); 976 this.hidden_selects = new Array(); 977 console.log("Initializing <select> overlay handler for '%s'.", this.overlay.id); 978 } 979} 980 981// ============================================================================= 982// vB_Hidden_Form methods 983 984/** 985* Hides any selects that intersect the overlayed object 986*/ 987vB_Select_Overlay_Handler.prototype.hide = function() 988{ 989 if (this.browser_affected) 990 { 991 var overlay_region = YAHOO.util.Dom.getRegion(this.overlay); 992 993 var selects = document.getElementsByTagName("select"); 994 for (var i = 0; i < selects.length; i++) 995 { 996 if (region_intersects(selects[i], overlay_region)) 997 { 998 if (YAHOO.util.Dom.isAncestor(this.overlay, selects[i])) 999 { 1000 continue; 1001 } 1002 else 1003 { 1004 YAHOO.util.Dom.setStyle(selects[i], "visibility", "hidden"); 1005 this.hidden_selects.push(YAHOO.util.Dom.generateId(selects[i])); 1006 } 1007 } 1008 } 1009 } 1010}; 1011 1012/** 1013* Un-hides any hidden selects 1014*/ 1015vB_Select_Overlay_Handler.prototype.show = function() 1016{ 1017 if (this.browser_affected) 1018 { 1019 var selectid; 1020 while (selectid = this.hidden_selects.pop()) 1021 { 1022 YAHOO.util.Dom.setStyle(selectid, "visibility", "visible"); 1023 } 1024 } 1025}; 1026 1027// ############################################################################# 1028// Window openers and instant messenger wrappers 1029 1030/** 1031* Opens a generic browser window 1032* 1033* @param string URL 1034* @param integer Width 1035* @param integer Height 1036* @param string Optional Window ID 1037*/ 1038function openWindow(url, width, height, windowid) 1039{ 1040 return window.open( 1041 url, 1042 (typeof windowid == 'undefined' ? 'vBPopup' : windowid), 1043 'statusbar=no,menubar=no,toolbar=no,scrollbars=yes,resizable=yes' 1044 + (typeof width != 'undefined' ? (',width=' + width) : '') + (typeof height != 'undefined' ? (',height=' + height) : '') 1045 ); 1046} 1047 1048/** 1049* Opens control panel help window 1050* 1051* @param string Script name 1052* @param string Action type 1053* @param string Option value 1054* 1055* @return window 1056*/ 1057function js_open_help(scriptname, actiontype, optionval) 1058{ 1059 return openWindow( 1060 'help.php?s=' + SESSIONHASH + '&do=answer&page=' + scriptname + '&pageaction=' + actiontype + '&option=' + optionval, 1061 600, 450, 'helpwindow' 1062 ); 1063} 1064 1065/** 1066* Opens a window to show a list of attachments in a thread (misc.php?do=showattachments) 1067* 1068* @param integer Thread ID 1069* 1070* @return window 1071*/ 1072function attachments(threadid) 1073{ 1074 return openWindow( 1075 'misc.php?' + SESSIONURL + 'do=showattachments&t=' + threadid, 1076 480, 300 1077 ); 1078} 1079 1080/** 1081* Opens a window to show a list of posters in a thread (misc.php?do=whoposted) 1082* 1083* @param integer Thread ID 1084* 1085* @return window 1086*/ 1087function who(threadid) 1088{ 1089 return openWindow( 1090 'misc.php?' + SESSIONURL + 'do=whoposted&t=' + threadid, 1091 230, 300 1092 ); 1093} 1094 1095/** 1096* Opens an IM Window 1097* 1098* @param string IM type 1099* @param integer User ID 1100* @param integer Width of window 1101* @param integer Height of window 1102* 1103* @return window 1104*/ 1105function imwindow(imtype, userid, width, height) 1106{ 1107 return openWindow( 1108 'sendmessage.php?' + SESSIONURL + 'do=im&type=' + imtype + '&u=' + userid, 1109 width, height 1110 ); 1111} 1112 1113/** 1114* Sends an MSN message 1115* 1116* @param string Target MSN handle 1117* 1118* @return boolean false 1119*/ 1120function SendMSNMessage(name) 1121{ 1122 if (!is_ie) 1123 { 1124 alert(vbphrase['msn_functions_only_work_in_ie']); 1125 } 1126 else 1127 { 1128 try 1129 { 1130 MsgrObj.InstantMessage(name); 1131 } 1132 catch(e) 1133 { 1134 alert(vbphrase['msn_functions_only_work_in_ie']); 1135 } 1136 } 1137 1138 return false; 1139} 1140 1141/** 1142* Adds an MSN Contact (requires MSN) 1143* 1144* @param string MSN handle 1145* 1146* @return boolean false 1147*/ 1148function AddMSNContact(name) 1149{ 1150 if (!is_ie) 1151 { 1152 alert(vbphrase['msn_functions_only_work_in_ie']); 1153 } 1154 else 1155 { 1156 try 1157 { 1158 MsgrObj.AddContact(0, name); 1159 } 1160 catch(e) 1161 { 1162 alert(vbphrase['msn_functions_only_work_in_ie']); 1163 } 1164 } 1165 1166 return false;
1167} 1168 1169/** 1170* Detects Caps-Lock when a key is pressed 1171* 1172* @param event 1173* 1174* @return boolean True if Caps-Lock is on 1175*/ 1176function detect_caps_lock(e) 1177{ 1178 e = (e ? e : window.event); 1179 1180 var keycode = (e.which ? e.which : (e.keyCode ? e.keyCode : (e.charCode ? e.charCode : 0))); 1181 var shifted = (e.shiftKey || (e.modifiers && (e.modifiers & 4))); 1182 var ctrled = (e.ctrlKey || (e.modifiers && (e.modifiers & 2))); 1183 1184 // if characters are uppercase without shift, or lowercase with shift, caps-lock is on. 1185 return (keycode >= 65 && keycode <= 90 && !shifted && !ctrled) || (keycode >= 97 && keycode <= 122 && shifted); 1186} 1187 1188/** 1189* Confirms log-out request 1190* 1191* @param string Log-out confirmation message 1192* 1193* @return boolean 1194*/ 1195function log_out(confirmation_message) 1196{ 1197 var ht = document.getElementsByTagName("html")[0]; 1198 ht.style.filter = "progid:DXImageTransform.Microsoft.BasicImage(grayscale=1)"; 1199 if (confirm(confirmation_message)) 1200 { 1201 return true; 1202 } 1203 else 1204 { 1205 ht.style.filter = ""; 1206 return false; 1207 } 1208} 1209 1210// ############################################################################# 1211// Cookie handlers 1212 1213/** 1214* Sets a cookie 1215* 1216* @param string Cookie name 1217* @param string Cookie value 1218* @param date Cookie expiry date 1219*/ 1220function set_cookie(name, value, expires) 1221{ 1222 console.log("Set Cookie :: %s = '%s'", name, value); 1223 document.cookie = name + '=' + escape(value) + '; path=/' + (typeof expires != 'undefined' ? '; expires=' + expires.toGMTString() : ''); 1224} 1225 1226/** 1227* Deletes a cookie 1228* 1229* @param string Cookie name 1230*/ 1231function delete_cookie(name) 1232{ 1233 console.log("Delete Cookie :: %s", name); 1234 document.cookie = name + '=' + '; expires=Thu, 01-Jan-70 00:00:01 GMT' + '; path=/'; 1235} 1236 1237/** 1238* Fetches the value of a cookie 1239* 1240* @param string Cookie name 1241* 1242* @return string 1243*/ 1244function fetch_cookie(name) 1245{ 1246 cookie_name = name + '='; 1247 cookie_length = document.cookie.length; 1248 cookie_begin = 0; 1249 while (cookie_begin < cookie_length) 1250 { 1251 value_begin = cookie_begin + cookie_name.length; 1252 if (document.cookie.substring(cookie_begin, value_begin) == cookie_name) 1253 { 1254 var value_end = document.cookie.indexOf (';', value_begin); 1255 if (value_end == -1) 1256 { 1257 value_end = cookie_length; 1258 } 1259 var cookie_value = unescape(document.cookie.substring(value_begin, value_end)); 1260 console.log("Fetch Cookie :: %s = '%s'", name, cookie_value); 1261 return cookie_value; 1262 } 1263 cookie_begin = document.cookie.indexOf(' ', cookie_begin) + 1; 1264 if (cookie_begin == 0) 1265 { 1266 break; 1267 } 1268 } 1269 console.log("Fetch Cookie :: %s (null)", name); 1270 return null; 1271} 1272 1273// ############################################################################# 1274// Form element managers (used for 'check all' type systems) 1275 1276/** 1277* Sets all checkboxes, radio buttons or selects in a given form to a given state, with exceptions 1278* 1279* @param object Form object 1280* @param string Target element type (one of 'radio', 'select-one', 'checkbox') 1281* @param string Selected option in case of 'radio' 1282* @param array Array of element names to be excluded 1283* @param mixed Value to give to found elements 1284*/ 1285function js_toggle_all(formobj, formtype, option, exclude, setto) 1286{ 1287 for (var i =0; i < formobj.elements.length; i++) 1288 { 1289 var elm = formobj.elements[i]; 1290 if (elm.type == formtype && PHP.in_array(elm.name, exclude, false) == -1) 1291 { 1292 switch (formtype) 1293 { 1294 case 'radio': 1295 if (elm.value == option) // option == '' evaluates true when option = 0 1296 { 1297 elm.checked = setto; 1298 } 1299 break; 1300 case 'select-one': 1301 elm.selectedIndex = setto; 1302 break; 1303 default: 1304 elm.checked = setto; 1305 break; 1306 } 1307 } 1308 } 1309} 1310 1311/** 1312* Sets all <select> elements to the selectedIndex specified by the 'selectall' element 1313* 1314* @param object Form object 1315*/ 1316function js_select_all(formobj) 1317{ 1318 exclude = new Array(); 1319 exclude[0] = 'selectall'; 1320 js_toggle_all(formobj, 'select-one', '', exclude, formobj.selectall.selectedIndex); 1321} 1322 1323/** 1324* Sets all <input type="checkbox" /> elements to have the same checked status as 'allbox' 1325* 1326* @param object Form object 1327*/ 1328function js_check_all(formobj) 1329{ 1330 exclude = new Array(); 1331 exclude[0] = 'keepattachments'; 1332 exclude[1] = 'allbox'; 1333 exclude[2] = 'removeall'; 1334 js_toggle_all(formobj, 'checkbox', '', exclude, formobj.allbox.checked); 1335} 1336 1337/** 1338* Sets all <input type="radio" /> groups to have a particular option checked 1339* 1340* @param object Form object 1341* @param mixed Selected option 1342*/ 1343function js_check_all_option(formobj, option) 1344{ 1345 exclude = new Array(); 1346 exclude[0] = 'useusergroup'; 1347 js_toggle_all(formobj, 'radio', option, exclude, true); 1348} 1349 1350/** 1351* Alias to js_check_all 1352*/ 1353function checkall(formobj) 1354{ 1355 js_check_all(formobj); 1356} 1357 1358/** 1359* Alias to js_check_all_option 1360*/ 1361function checkall_option(formobj, option) 1362{ 1363 js_check_all_option(formobj, option); 1364} 1365 1366/** 1367* Resize function for CP textareas 1368* 1369* @param integer If positive, size up, otherwise size down 1370* @param string ID of the textarea 1371*
1372* @return boolean false 1373*/ 1374function resize_textarea(to, id) 1375{ 1376 var textarea = fetch_object(id); 1377 1378 textarea.style.width = parseInt(textarea.offsetWidth) + (to < 0 ? -100 : 100) + "px"; 1379 textarea.style.height = parseInt(textarea.offsetHeight) + (to < 0 ? -100 : 100) + "px"; 1380 1381 return false; 1382} 1383 1384/** 1385* Determines if two HTML objects intersect 1386* 1387* @param object 1st HTML object 1388* @param object 2nd HTML object 1389* 1390* @return boolean True if intersection is found 1391*/ 1392function region_intersects(obj1, obj2) 1393{ 1394 obj1 = typeof(obj1.left) == "undefined" ? YAHOO.util.Dom.getRegion(obj1) : obj1; 1395 obj2 = typeof(obj2.left) == "undefined" ? YAHOO.util.Dom.getRegion(obj2) : obj2; 1396 1397 return (obj1.left > obj2.right || obj1.right < obj2.left || obj1.top > obj2.bottom || obj1.bottom < obj2.top) ? false : true; 1398} 1399 1400/** 1401* Fetch information about the current browser viewport 1402* 1403* @return array Contains x, y, w, h elements 1404*/ 1405function fetch_viewport_info() 1406{ 1407 if (viewport_info == null) 1408 { 1409 viewport_info = { 1410 x : YAHOO.util.Dom.getDocumentScrollLeft(), 1411 y : YAHOO.util.Dom.getDocumentScrollTop(), 1412 w : YAHOO.util.Dom.getViewportWidth(), 1413 h : YAHOO.util.Dom.getViewportHeight() 1414 }; 1415 1416 console.info("Viewport Info: Size = %dx%d, Position = %d,%d", viewport_info['w'], viewport_info['h'], viewport_info['x'], viewport_info['y']); 1417 } 1418 1419 return viewport_info; 1420} 1421 1422/** 1423* Clear cached viewport info 1424*/ 1425function clear_viewport_info() 1426{ 1427 viewport_info = null; 1428} 1429 1430/** 1431* Position an element in the middle of the browser window 1432* Note that this will only work if it is called AFTER an element is part of the DOM tree and has its full size 1433* 1434* @param object HTML element to be positioned 1435*/ 1436function center_element(el) 1437{ 1438 viewport_info = fetch_viewport_info(); 1439 1440 YAHOO.util.Dom.setXY(el, [ 1441 viewport_info['w'] / 2 + viewport_info['x'] - el.clientWidth / 2, 1442 viewport_info['h'] / 2 + viewport_info['y'] - el.clientHeight / 2 1443 ]); 1444} 1445 1446/* Parses a stylesheet to find all rules within, including those fetched with @import 1447* 1448* @param object Usually document.styleSheets 1449* 1450* @return array 1451*/ 1452function fetch_all_stylesheets(sheets) 1453{ 1454 var all_sheets = new Array(), 1455 i = 0, 1456 current_sheet = null, 1457 current_rule = 0, 1458 current_import = 0; 1459 1460 for (i = 0; i < document.styleSheets.length; i++) 1461 { 1462 current_sheet = document.styleSheets[i]; 1463 1464 all_sheets.push(current_sheet); 1465 1466 try 1467 { 1468 if (current_sheet.cssRules) // not IE 1469 { 1470 for (current_rule = 0; current_rule < current_sheet.cssRules.length; current_rule++) 1471 { 1472 if (current_sheet.cssRules[current_rule].styleSheet) 1473 { 1474 all_sheets.push(current_sheet.cssRules[current_rule].styleSheet); 1475 } 1476 } 1477 } 1478 else // IE 1479 { 1480 if (current_sheet.imports) 1481 { 1482 for (current_import = 0; current_import < current_sheet.imports.length; current_import++) 1483 { 1484 all_sheets.push(current_sheet.imports[current_import]); 1485 } 1486 } 1487 } 1488 } 1489 catch(e) 1490 { 1491 // trying to access a stylesheet outside the allowed domain 1492 all_sheets.pop(); 1493 continue; 1494 } 1495 } 1496 1497 return all_sheets; 1498} 1499 1500/** 1501* Highlights the login box to make it obvious where to login. 1502*/ 1503function highlight_login_box() 1504{ 1505 var obj = fetch_object('navbar_username'); 1506 var addclass = 'inlinemod'; 1507 var i, timeout = 1600, flash_speed = 200; 1508 1509 if (obj) 1510 { 1511 obj.focus(); 1512 obj.select(); 1513 1514 for (i = 0; i < timeout; i += 2 * flash_speed) 1515 { 1516 window.setTimeout(function() { YAHOO.util.Dom.addClass(obj, addclass) }, i); 1517 window.setTimeout(function() { YAHOO.util.Dom.removeClass(obj, addclass) }, i + flash_speed); 1518 } 1519 } 1520 1521 return false; 1522} 1523 1524// ############################################################################# 1525// Collapsible element handlers 1526 1527/** 1528* Toggles the collapse state of an object, and saves state to 'vbulletin_collapse' cookie 1529* 1530* @param string Unique ID for the collapse group 1531* 1532* @return boolean false 1533*/ 1534function toggle_collapse(objid, forcestate) 1535{ 1536 if (!is_regexp) 1537 { 1538 return false; 1539 } 1540 1541 var obj = fetch_object('collapseobj_' + objid); 1542 var img = fetch_object('collapseimg_' + objid); 1543 var cel = fetch_object('collapsecel_' + objid); 1544 1545 if (!obj) 1546 { 1547 // nothing to collapse! 1548 if (img) 1549 { 1550 // hide the clicky image if there is one 1551 img.style.display = 'none'; 1552 } 1553 return false;
1554 } 1555 1556 if (obj.style.display == 'none' || 'open' == forcestate) 1557 { 1558 obj.style.display = ''; 1559 1560 if (!forcestate) 1561 { 1562 save_collapsed(objid, false); 1563 } 1564 1565 if (img) 1566 { 1567 img_re = new RegExp("_collapsed\\.gif$"); 1568 img.src = img.src.replace(img_re, '.gif'); 1569 } 1570 if (cel) 1571 { 1572 cel_re = new RegExp("^(thead|tcat)(_collapsed)$"); 1573 cel.className = cel.className.replace(cel_re, '$1'); 1574 } 1575 } 1576 else if (obj.style.display != 'none' || 'closed' == forcestate) 1577 { 1578 obj.style.display = 'none'; 1579 1580 if (!forcestate) 1581 { 1582 save_collapsed(objid, true); 1583 } 1584 1585 if (img) 1586 { 1587 img_re = new RegExp("\\.gif$"); 1588 img.src = img.src.replace(img_re, '_collapsed.gif'); 1589 } 1590 if (cel) 1591 { 1592 cel_re = new RegExp("^(thead|tcat)$"); 1593 cel.className = cel.className.replace(cel_re, '$1_collapsed'); 1594 } 1595 } 1596 return false; 1597} 1598 1599/** 1600* Updates vbulletin_collapse cookie with collapse preferences 1601* 1602* @param string Unique ID for the collapse group 1603* @param boolean Add a cookie 1604*/ 1605function save_collapsed(objid, addcollapsed) 1606{ 1607 var collapsed = fetch_cookie('vbulletin_collapse'); 1608 var tmp = new Array(); 1609 1610 if (collapsed != null) 1611 { 1612 collapsed = collapsed.split('\n'); 1613 1614 for (var i in collapsed) 1615 { 1616 if (YAHOO.lang.hasOwnProperty(collapsed, i) && collapsed[i] != objid && collapsed[i] != '') 1617 { 1618 tmp[tmp.length] = collapsed[i]; 1619 } 1620 } 1621 } 1622 1623 if (addcollapsed) 1624 { 1625 tmp[tmp.length] = objid; 1626 } 1627 1628 expires = new Date(); 1629 expires.setTime(expires.getTime() + (1000 * 86400 * 365)); 1630 set_cookie('vbulletin_collapse', tmp.join('\n'), expires); 1631} 1632 1633// ############################################################################# 1634// Event Handlers for PageNav menus 1635 1636/** 1637* Class to handle pagenav events 1638*/ 1639function vBpagenav() 1640{ 1641} 1642 1643/** 1644* Handles clicks on pagenav menu control objects 1645*/ 1646vBpagenav.prototype.controlobj_onclick = function(e) 1647{ 1648 this._onclick(e); 1649 var inputs = fetch_tags(this.menu.menuobj, 'input'); 1650 for (var i = 0; i < inputs.length; i++) 1651 { 1652 if (inputs[i].type == 'text') 1653 { 1654 inputs[i].focus(); 1655 break; 1656 } 1657 } 1658}; 1659 1660/** 1661* Submits the pagenav form... sort of 1662*/ 1663vBpagenav.prototype.form_gotopage = function(e) 1664{ 1665 if ((pagenum = parseInt(fetch_object('pagenav_itxt').value, 10)) > 0) 1666 { 1667 window.location = vBmenu.menus[vBmenu.activemenu].addr + '&page=' + pagenum; 1668 } 1669 return false; 1670}; 1671 1672/** 1673* Handles clicks on the 'Go' button in pagenav popups 1674*/ 1675vBpagenav.prototype.ibtn_onclick = function(e) 1676{ 1677 return this.form.gotopage(); 1678}; 1679 1680/** 1681* Handles keypresses in the text input of pagenav popups 1682*/ 1683vBpagenav.prototype.itxt_onkeypress = function(e) 1684{ 1685 return ((e ? e : window.event).keyCode == 13 ? this.form.gotopage() : true); 1686}; 1687 1688// ############################################################################# 1689// DHTML Popup Menu Handling (complements vbulletin_menu.js) 1690 1691/** 1692* Wrapper for vBmenu.register 1693* 1694* @param string Control ID 1695* @param boolean No image (true) 1696* @param boolean Does nothing any more 1697*/ 1698function vbmenu_register(controlid, noimage, datefield) 1699{ 1700 if (typeof(vBmenu) == "object") 1701 { 1702 return vBmenu.register(controlid, noimage); 1703 } 1704 else 1705 { 1706 return false; 1707 } 1708} 1709 1710// ############################################################################# 1711// Stuff that really doesn't fit anywhere else 1712 1713/** 1714* Converts an HTML string into a DOM node for use elsewhere 1715* 1716* Note: Only works reliably if the string is enclosed in an HTML element. 1717* eg: "<span>Hello, <strong>username</strong></span>" not "Hello, <strong>username</strong>" 1718* 1719* @param string HTML String to convert 1720*/ 1721function string_to_node(html_string) 1722{ 1723 var node_container = document.createElement("div"); 1724 node_container.innerHTML = html_string; 1725 1726 var node = node_container.firstChild; 1727 while (node && node.nodeType != 1) 1728 { 1729 node = node.nextSibling; 1730 } 1731 1732 if (!node) 1733 { 1734 return node_container.firstChild.cloneNode(true); 1735 } 1736 else 1737 { 1738 return node.cloneNode(true); 1739 } 1740} 1741 1742/** 1743* Sets an element and all its children to be 'unselectable' 1744* 1745* @param mixed Object/Object ID to be made unselectable 1746*/
1747function set_unselectable(obj) 1748{ 1749 obj = YAHOO.util.Dom.get(obj); 1750 1751 if (!is_ie4 && typeof obj.tagName != 'undefined') 1752 { 1753 if (obj.hasChildNodes()) 1754 { 1755 for (var i = 0; i < obj.childNodes.length; i++) 1756 { 1757 set_unselectable(obj.childNodes[i]); 1758 } 1759 } 1760 obj.unselectable = 'on'; 1761 } 1762} 1763 1764/** 1765* Fetches the sessionhash from the SESSIONURL variable 1766* 1767* @return string 1768*/ 1769function fetch_sessionhash() 1770{ 1771 return (SESSIONURL == '' ? '' : SESSIONURL.substr(2, 32)); 1772} 1773 1774/** 1775* Emulates the PHP version of vBulletin's construct_phrase() sprintf wrapper 1776* 1777* @param string String containing %1$s type replacement markers 1778* @param string First replacement 1779* @param string Nth replacement 1780* 1781* @return string 1782*/ 1783function construct_phrase() 1784{ 1785 if (!arguments || arguments.length < 1 || !is_regexp) 1786 { 1787 return false; 1788 } 1789 1790 var args = arguments; 1791 var str = args[0]; 1792 var re; 1793 1794 for (var i = 1; i < args.length; i++) 1795 { 1796 re = new RegExp("%" + i + "\\$s", 'gi'); 1797 str = str.replace(re, args[i]); 1798 } 1799 return str; 1800} 1801 1802/** 1803* Handles the quick style/language options in the footer 1804* 1805* @param object Select object 1806* @param string Type (style or language) 1807*/ 1808function switch_id(selectobj, type) 1809{ 1810 var id = selectobj.options[selectobj.selectedIndex].value; 1811 1812 if (id == '') 1813 { 1814 return; 1815 } 1816 1817 var url = new String(window.location); 1818 var fragment = new String(''); 1819 1820 // get rid of fragment 1821 url = url.split('#'); 1822 1823 // deal with the fragment first 1824 if (url[1]) 1825 { 1826 fragment = '#' + url[1]; 1827 } 1828 1829 // deal with the main url 1830 url = url[0]; 1831 1832 // remove id=x& from main bit 1833 if (url.indexOf(type + 'id=') != -1 && is_regexp) 1834 { 1835 var re = new RegExp(type + "id=\\d+&?"); 1836 url = url.replace(re, ''); 1837 } 1838 1839 // add the ? to the url if needed 1840 if (url.indexOf('?') == -1) 1841 { 1842 url += '?'; 1843 } 1844 else 1845 { 1846 // make sure that we have a valid character to join our id bit 1847 lastchar = url.substr(url.length - 1); 1848 if (lastchar != '&' && lastchar != '?') 1849 { 1850 url += '&'; 1851 } 1852 } 1853 1854 window.location = url + type + 'id=' + id + fragment; 1855} 1856 1857/** 1858* Finds all images within the specified element and sets their alt attribute as title 1859* 1860* @param object Containing element 1861*/ 1862function child_img_alt_2_title(object) 1863{ 1864 var imgs = object.getElementsByTagName("img"); 1865 for (var i = 0; i < imgs.length; i++) 1866 { 1867 img_alt_2_title(imgs[i]); 1868 } 1869} 1870 1871/** 1872* Takes the 'alt' attribute for an image and attaches it to the 'title' attribute 1873* 1874* @param object Image object 1875*/ 1876function img_alt_2_title(img) 1877{ 1878 if (!img.title && img.alt != '') 1879 { 1880 img.title = img.alt; 1881 } 1882} 1883 1884 1885function do_securitytoken_replacement(newtoken) 1886{ 1887 if (newtoken == '') 1888 { 1889 return; 1890 } 1891 1892 for (var formid = 0; formid < document.forms.length; formid++) 1893 { 1894 if (document.forms[formid].elements['securitytoken'] && document.forms[formid].elements['securitytoken'].value == SECURITYTOKEN) 1895 { 1896 document.forms[formid].elements['securitytoken'].value = newtoken; 1897 } 1898 } 1899 SECURITYTOKEN = newtoken; 1900 console.log("Securitytoken updated"); 1901} 1902 1903function handle_securitytoken_response(ajax) 1904{ 1905 console.log("Processing securitytoken update"); 1906 if (ajax.responseXML && ajax.responseXML.getElementsByTagName("securitytoken").length) 1907 { 1908 var newtoken = ajax.responseXML.getElementsByTagName("securitytoken")[0].firstChild.nodeValue; 1909 do_securitytoken_replacement(newtoken); 1910 securitytoken_errors = 0; 1911 } 1912 else 1913 { 1914 handle_securitytoken_error(ajax); 1915 } 1916} 1917 1918function handle_securitytoken_error(ajax) 1919{ 1920 console.log("Securitytoken Error"); 1921 if (++securitytoken_errors == 3) 1922 { 1923 do_securitytoken_replacement('guest'); 1924 } 1925} 1926 1927// 1 hour = 3,600,000ms 1928var securitytoken_timeout = window.setTimeout('replace_securitytoken()', 3600000); 1929var securitytoken_errors = 0; 1930 1931function replace_securitytoken() 1932{ 1933 window.clearTimeout(securitytoken_timeout); 1934 if (AJAX_Compatible && SECURITYTOKEN != '' && SECURITYTOKEN != 'guest') 1935 { 1936 securitytoken_timeout = window.setTimeout('replace_securitytoken()', 3600000); 1937 YAHOO.util.Connect.asyncRequest("POST", "ajax.php", { 1938 success: handle_securitytoken_response, 1939 failure: handle_securitytoken_error, 1940 timeout: vB_Default_Timeout 1941 }, SESSIONURL + "securitytoken=" + SECURITYTOKEN + "&do=securitytoken"); 1942 } 1943} 1944 1945// ############################################################################# 1946// Initialize a Comment 1947 1948/** 1949* This function runs all the necessary Javascript code on a Comment 1950* after it has been loaded via AJAX. Don't use this method before a 1951* complete page load or you'll have problems. 1952* 1953* @param object Object containing postbits 1954*/ 1955function Comment_Init(obj) 1956{ 1957 if (typeof obj.id == "undefined") 1958 { 1959 return; 1960 } 1961 1962 var objectid = obj.id; 1963 if (isNaN(objectid)) 1964 { 1965 var match = null; 1966 if (match = objectid.match(/(\d+)/)) 1967 { 1968 objectid = match[0]; 1969 } 1970 } 1971 1972 if (typeof inlineMod_comment != "undefined") 1973 { 1974 im_init(obj, inlineMod_comment); 1975 } 1976 1977 if (typeof vB_QuickEditor_Factory != "undefined") 1978 { 1979 if (typeof vB_QuickEditor_Factory.controls[objectid] == "undefined") 1980 { 1981 vB_QuickEditor_Factory.controls[objectid] = new vB_QuickEditor(objectid, vB_QuickEditor_Factory); 1982 } 1983 else 1984 { 1985 vB_QuickEditor_Factory.controls[objectid].init(); 1986 } 1987 } 1988 1989 if (typeof vB_QuickLoader_Factory != "undefined") 1990 { 1991 vB_QuickLoader_Factory.controls[objectid] = new vB_QuickLoader(objectid, vB_QuickLoader_Factory); 1992 } 1993 1994 child_img_alt_2_title(obj); 1995} 1996 1997// ############################################################################# 1998// Initialize a PostBit 1999 2000/** 2001* This function runs all the necessary Javascript code on a PostBit 2002* after it has been loaded via AJAX. Don't use this method before a 2003* complete page load or you'll have problems. 2004* 2005* @param object Object containing postbits 2006*/ 2007function PostBit_Init(obj, postid) 2008{ 2009 console.log("PostBit Init: %d", postid); 2010 2011 if (typeof vBmenu != 'undefined') 2012 { 2013 // init profile menu(s) 2014 var divs = fetch_tags(obj, 'div'); 2015 for (var i = 0; i < divs.length; i++) 2016 { 2017 if (divs[i].id && divs[i].id.substr(0, 9) == 'postmenu_') 2018 { 2019 vBmenu.register(divs[i].id, true); 2020 } 2021 } 2022 } 2023 2024 if (typeof vB_QuickEditor != 'undefined') 2025 { 2026 // init quick edit controls 2027 vB_AJAX_QuickEdit_Init(obj); 2028 } 2029 2030 if (typeof vB_QuickReply != 'undefined') 2031 { 2032 // init quick reply button 2033 qr_init_buttons(obj); 2034 } 2035 2036 if (typeof mq_init != 'undefined') 2037 { 2038 // init quick reply button 2039 mq_init(obj); 2040 } 2041 2042 if (typeof vBrep != 'undefined') 2043 { 2044 if (typeof postid != 'undefined' && typeof postid != 'null') 2045 { 2046 vbrep_register(postid); 2047 } 2048 } 2049 2050 if (typeof inlineMod != 'undefined') 2051 { 2052 im_init(obj); 2053 } 2054 2055 if (typeof vB_Lightbox != 'undefined') 2056 { 2057 init_postbit_lightbox(obj, false, true); 2058 } 2059 2060 child_img_alt_2_title(obj); 2061} 2062 2063// ############################################################################# 2064// Main vBulletin Javascript Initialization 2065 2066/** 2067* This function runs (almost) at the end of script loading on most vBulletin pages 2068* 2069* It sets up things like image alt->title tags, turns on the popup menu system etc. 2070* 2071* @return boolean 2072*/
2073function vBulletin_init() 2074{ 2075 // don't bother doing any exciting stuff for WebTV 2076 if (is_webtv) 2077 { 2078 return false; 2079 } 2080 2081 // set 'title' tags for image elements 2082 child_img_alt_2_title(document); 2083 2084 // finalize popup menus 2085 if (typeof vBmenu == 'object') 2086 { 2087 // close all menus on document click or resize 2088 if (typeof(YAHOO) != "undefined") 2089 { 2090 YAHOO.util.Event.on(document, "click", vbmenu_hide); 2091 YAHOO.util.Event.on(window, "resize", vbmenu_hide); 2092 } 2093 else if (window.attachEvent && !is_saf) 2094 { 2095 document.attachEvent('onclick', vbmenu_hide); 2096 window.attachEvent('onresize', vbmenu_hide); 2097 } 2098 else if (document.addEventListener && !is_saf) 2099 { 2100 document.addEventListener('click', vbmenu_hide, false); 2101 window.addEventListener('resize', vbmenu_hide, false); 2102 } 2103 else 2104 { 2105 window.onclick = vbmenu_hide; 2106 window.onresize = vbmenu_hide; 2107 } 2108 2109 // add popups to pagenav elements 2110 var pagenavs = fetch_tags(document, 'td'); 2111 for (var n = 0; n < pagenavs.length; n++) 2112 { 2113 if (pagenavs[n].hasChildNodes() && pagenavs[n].firstChild.name && pagenavs[n].firstChild.name.indexOf('PageNav') != -1) 2114 { 2115 var addr = pagenavs[n].title; 2116 pagenavs[n].title = ''; 2117 pagenavs[n].innerHTML = ''; 2118 pagenavs[n].id = 'pagenav.' + n; 2119 var pn = vBmenu.register(pagenavs[n].id); 2120 pn.addr = addr; 2121 2122 if (is_saf) 2123 { 2124 pn.controlobj._onclick = pn.controlobj.onclick; 2125 pn.controlobj.onclick = vBpagenav.prototype.controlobj_onclick; 2126 } 2127 } 2128 } 2129 2130 // process the pagenavs popup form 2131 if (typeof addr != 'undefined') 2132 { 2133 fetch_object('pagenav_form').gotopage = vBpagenav.prototype.form_gotopage; 2134 fetch_object('pagenav_ibtn').onclick = vBpagenav.prototype.ibtn_onclick; 2135 fetch_object('pagenav_itxt').onkeypress = vBpagenav.prototype.itxt_onkeypress; 2136 } 2137 2138 // activate the menu system 2139 vBmenu.activate(true); 2140 } 2141 2142 // the new init system 2143 vBulletin.init(); 2144 2145 return true; 2146} 2147 2148// ############################################################################# 2149// vBulletin Javascript Framework 2150 2151/** 2152* General class for handling custom events and custom controls 2153*/ 2154function vBulletin_Framework() 2155{ 2156 /** 2157 * @var array Array of elements to be passed to control init functions 2158 * @var array Array of AJAX load/save URLs 2159 * @var array Array of YUI custom events 2160 * @var date Current time 2161 */ 2162 this.elements = new Array(); 2163 this.ajaxurls = new Array(); 2164 this.events = new Array(); 2165 this.time = new Date(); 2166 2167 // custom event to fire during class init 2168 this.add_event("systemInit"); 2169} 2170 2171/** 2172* Initializes the object - usually called at end of footer template 2173*/ 2174vBulletin_Framework.prototype.init = function() 2175{ 2176 console.info("Firing System Init"); 2177 this.events.systemInit.fire(); 2178} 2179 2180/** 2181* Emulates OOP class extension 2182* 2183* @param object Extended class 2184* @param object Base class 2185*/ 2186vBulletin_Framework.prototype.extend = function(subClass, baseClass) 2187{ 2188 function inheritance() {} 2189 inheritance.prototype = baseClass.prototype; 2190 2191 subClass.prototype = new inheritance(); 2192 subClass.prototype.constructor = subClass; 2193 subClass.baseConstructor = baseClass; 2194 subClass.superClass = baseClass.prototype; 2195} 2196 2197/** 2198* Registers a custom control for later initialization 2199* Arguments 1-n are stored for later use 2200* 2201* @param string Control type (vB_DatePicker etc.) 2202* @param string HTML element ID 2203*/ 2204vBulletin_Framework.prototype.register_control = function(controltype, element) 2205{ 2206 var args = new Array(); 2207 for (var i = 1; i < arguments.length; i++) 2208 { 2209 args.push(arguments[i]); 2210 } 2211 if (!this.elements[controltype]) 2212 { 2213 console.info("Creating array vBulletin.elements[\"%s\"]", controltype); 2214 this.elements[controltype] = new Array(); 2215 } 2216 var x = this.elements[controltype].push(args); 2217 console.log("vBulletin.elements[\"%s\"][%d] = %s", controltype, x-1, args.join(", ")); 2218} 2219 2220/** 2221* Registers AJAX load/save urls for a control 2222* 2223* @param Fetch URL 2224* @param Save URL 2225* @param List of elements to which these URLs apply 2226*/ 2227vBulletin_Framework.prototype.register_ajax_urls = function(fetch, save, elements) 2228{ 2229 fetch = fetch.split("?"); fetch[1] = SESSIONURL + "securitytoken=" + SECURITYTOKEN + "&ajax=1&" + fetch[1].replace(/\{(\d+)(:\w+)?\}/gi, '%$1$s'); 2230 save = save.split("?"); save[1] = SESSIONURL + "securitytoken=" + SECURITYTOKEN + "&ajax=1&" + save[1].replace(/\{(\d+)(:\w+)?\}/gi, '%$1$s'); 2231 2232 console.log("Register AJAX URLs for %s", elements); 2233 2234 for (var i = 0; i < elements.length; i++) 2235 { 2236 this.ajaxurls[elements[i]] = new Array(fetch, save); 2237 } 2238} 2239 2240/** 2241* Register a custom event 2242* 2243* @param string Event name 2244*/ 2245vBulletin_Framework.prototype.add_event = function(eventname) 2246{ 2247 this.events[eventname] = new YAHOO.util.CustomEvent(eventname); 2248} 2249 2250/** 2251* BC: Pass console calls to Firebug if it's available 2252*/ 2253//vBulletin_Framework.prototype.console = console.log; 2254vBulletin_Framework.prototype.console = function() 2255{ 2256 if (window.console || console.firebug) 2257 { 2258 var args = new Array(); 2259 for (var i = 0; i < arguments.length; i++) 2260 { 2261 args[args.length] = arguments[i]; 2262 } 2263 2264 try 2265 { 2266 eval("console.log('" + args.join("','") + "');"); 2267 } 2268 catch(e) {} 2269 } 2270} 2271 2272// ############################################################################# 2273 2274// initialize the PHP function emulator 2275var PHP = new vB_PHP_Emulator(); 2276 2277// Create an instance of the vBulletin Framework object 2278var vBulletin = new vBulletin_Framework(); 2279 2280vBulletin.events.systemInit.subscribe(function() 2281{ 2282 YAHOO.util.Event.on(window, "resize", clear_viewport_info); 2283 YAHOO.util.Event.on(window, "scroll", clear_viewport_info) 2284}); 2285 2286// #############################################################################
2287// Functions for dismissing dismissible notices 2288function handle_dismiss_notice_error(ajax) 2289{ 2290 if (ajax.argument) 2291 { 2292 var nodeDismissID = YAHOO.util.Dom.get("dismiss_notice_hidden"); 2293 nodeDismissID.value = ajax.argument; 2294 var nodeForm = YAHOO.util.Dom.get("notices"); 2295 nodeForm.submit(); 2296 } 2297} 2298 2299function handle_dismiss_notice_ajax(ajax) 2300{ 2301 if (ajax.responseXML && ajax.responseXML.getElementsByTagName("dismissed").length) 2302 { 2303 var dismissed = ajax.responseXML.getElementsByTagName("dismissed")[0].firstChild.nodeValue; 2304 var nodeNotice = YAHOO.util.Dom.get("navbar_notice_" + dismissed); 2305 if (nodeNotice != null) 2306 { 2307 nodeNotice.style.display = "none"; 2308 var nodeNotices = YAHOO.util.Dom.getElementsByClassName("navbar_notice", "", YAHOO.util.Dom.get("notices")); 2309 var showing = 0; 2310 for (i = 0; i < nodeNotices.length; i++) 2311 { 2312 if (nodeNotices[i].style.display != "none") 2313 { 2314 showing++; 2315 } 2316 } 2317 if (showing == 0) 2318 { 2319 var nodeNoticeTable = YAHOO.util.Dom.get("notices"); 2320 if (nodeNoticeTable != null) 2321 { 2322 // hide the table if no more notices left 2323 nodeNoticeTable.style.display = "none"; 2324 } 2325 } 2326 } 2327 } 2328 else 2329 { 2330 handle_dismiss_notice_error(ajax); 2331 } 2332} 2333 2334/** 2335* @param int integer value of noticeid 2336* 2337* returns false, to disable link for js compatible browsers, when AJAX enabled or browser support it 2338* returns true, to actually submit the form, when AJAX disabled or browser does not support it 2339*/ 2340function dismiss_notice(noticeid) 2341{ 2342 if (AJAX_Compatible) 2343 { 2344 var ajax_req = YAHOO.util.Connect.asyncRequest("POST", "ajax.php?do=dismissnotice", { 2345 success: handle_dismiss_notice_ajax, 2346 failure: handle_dismiss_notice_error, 2347 timeout: vB_Default_Timeout, 2348 argument: noticeid 2349 }, SESSIONURL + "securitytoken=" + SECURITYTOKEN + "&do=dismissnotice¬iceid=" + PHP.urlencode(noticeid)); 2350 return false; 2351 } 2352 return true; 2353} 2354 2355/*======================================================================*\ 2356|| #################################################################### 2357|| # NulleD - FintMax 2358|| # CVS: $RCSfile$ - $Revision: 29350 $ 2359|| #################################################################### 2360\*======================================================================*/ 2361 2362} 2363
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.