1var cur_topic_id, cur_msg_id, buff_subject, cur_subject_div, in_edit_mode = 0; 2var hide_prefixes = Array(); 3 4function modify_topic(topic_id, first_msg_id) 5{ 6 if (!('XMLHttpRequest' in window)) 7 return; 8 9 if ('opera' in window) 10 { 11 var oTest = new XMLHttpRequest(); 12 if (!('setRequestHeader' in oTest)) 13 return; 14 } 15 16 // Add backwards compatibility with old themes. 17 if (typeof(cur_session_var) == 'undefined') 18 cur_session_var = 'sesc'; 19 20 if (in_edit_mode == 1) 21 { 22 if (cur_topic_id == topic_id) 23 return; 24 else 25 modify_topic_cancel(); 26 } 27 28 in_edit_mode = 1; 29 mouse_on_div = 1; 30 cur_topic_id = topic_id; 31 32 if (typeof window.ajax_indicator == "function") 33 ajax_indicator(true); 34 getXMLDocument(smf_prepareScriptUrl(smf_scripturl) + "action=quotefast;quote=" + first_msg_id + ";modify;xml", onDocReceived_modify_topic); 35} 36 37function onDocReceived_modify_topic(XMLDoc) 38{ 39 cur_msg_id = XMLDoc.getElementsByTagName("message")[0].getAttribute("id"); 40 41 cur_subject_div = document.getElementById('msg_' + cur_msg_id.substr(4)); 42 buff_subject = getInnerHTML(cur_subject_div); 43 44 // Here we hide any other things they want hiding on edit. 45 set_hidden_topic_areas('none'); 46 47 modify_topic_show_edit(XMLDoc.getElementsByTagName("subject")[0].childNodes[0].nodeValue); 48 if (typeof window.ajax_indicator == "function") 49 ajax_indicator(false); 50} 51 52function modify_topic_cancel() 53{ 54 setInnerHTML(cur_subject_div, buff_subject); 55 set_hidden_topic_areas(''); 56 57 in_edit_mode = 0; 58 return false; 59} 60 61function modify_topic_save(cur_session_id, cur_session_var) 62{ 63 if (!in_edit_mode) 64 return true; 65 66 // Add backwards compatibility with old themes. 67 if (typeof(cur_session_var) == 'undefined') 68 cur_session_var = 'sesc'; 69 70 var i, x = new Array(); 71 x[x.length] = 'subject=' + document.forms.quickModForm['subject'].value.replace(/&#/g, "&#").php_to8bit().php_urlencode(); 72 x[x.length] = 'topic=' + parseInt(document.forms.quickModForm.elements['topic'].value); 73 x[x.length] = 'msg=' + parseInt(document.forms.quickModForm.elements['msg'].value); 74 75 if (typeof window.ajax_indicator == "function") 76 ajax_indicator(true); 77 sendXMLDocument(smf_prepareScriptUrl(smf_scripturl) + "action=jsmodify;topic=" + parseInt(document.forms.quickModForm.elements['topic'].value) + ";" + cur_session_var + "=" + cur_session_id + ";xml", x.join("&"), modify_topic_done); 78 79 return false; 80} 81 82function modify_topic_done(XMLDoc) 83{ 84 if (!XMLDoc) 85 { 86 modify_topic_cancel(); 87 return true; 88 } 89 90 var message = XMLDoc.getElementsByTagName("smf")[0].getElementsByTagName("message")[0]; 91 var subject = message.getElementsByTagName("subject")[0]; 92 var error = message.getElementsByTagName("error")[0]; 93 94 if (typeof window.ajax_indicator == "function") 95 ajax_indicator(false); 96 97 if (!subject || error) 98 return false; 99 100 subjectText = subject.childNodes[0].nodeValue; 101 102 modify_topic_hide_edit(subjectText); 103 104 set_hidden_topic_areas(''); 105 106 in_edit_mode = 0; 107 108 return false; 109} 110 111// Simply restore any hidden bits during topic editing. 112function set_hidden_topic_areas(set_style) 113{ 114 for (var i = 0; i < hide_prefixes.length; i++) 115 { 116 if (document.getElementById(hide_prefixes[i] + cur_msg_id.substr(4)) != null) 117 document.getElementById(hide_prefixes[i] + cur_msg_id.substr(4)).style.display = set_style; 118 } 119} 120 121// *** QuickReply object. 122function QuickReply(oOptions) 123{ 124 this.opt = oOptions; 125 this.bCollapsed = this.opt.bDefaultCollapsed; 126} 127 128// When a user presses quote, put it in the quick reply box (if expanded). 129QuickReply.prototype.quote = function (iMessageId, xDeprecated) 130{ 131 // Compatibility with older templates. 132 if (typeof(xDeprecated) != 'undefined') 133 return true; 134 135 if (this.bCollapsed) 136 { 137 window.location.href = smf_prepareScriptUrl(this.opt.sScriptUrl) + 'action=post;quote=' + iMessageId + ';topic=' + this.opt.iTopicId + '.' + this.opt.iStart; 138 return false; 139 } 140 else 141 { 142 // Doing it the XMLhttp way? 143 if (window.XMLHttpRequest) 144 { 145 ajax_indicator(true); 146 getXMLDocument(smf_prepareScriptUrl(this.opt.sScriptUrl) + 'action=quotefast;quote=' + iMessageId + ';xml', this.onQuoteReceived); 147 } 148 // Or with a smart popup! 149 else 150 reqWin(smf_prepareScriptUrl(this.opt.sScriptUrl) + 'action=quotefast;quote=' + iMessageId, 240, 90); 151 152 // Move the view to the quick reply box. 153 if (navigator.appName == 'Microsoft Internet Explorer') 154 window.location.hash = this.opt.sJumpAnchor; 155 else 156 window.location.hash = '#' + this.opt.sJumpAnchor; 157 158 return false;
159 } 160} 161 162// This is the callback function used after the XMLhttp request. 163QuickReply.prototype.onQuoteReceived = function (oXMLDoc) 164{ 165 var sQuoteText = ''; 166 167 for (var i = 0; i < oXMLDoc.getElementsByTagName('quote')[0].childNodes.length; i++) 168 sQuoteText += oXMLDoc.getElementsByTagName('quote')[0].childNodes[i].nodeValue; 169 170 replaceText(sQuoteText, document.forms.postmodify.message); 171 172 ajax_indicator(false); 173} 174 175// The function handling the swapping of the quick reply. 176QuickReply.prototype.swap = function () 177{ 178 document.getElementById(this.opt.sImageId).src = this.opt.sImagesUrl + "/" + (this.bCollapsed ? this.opt.sImageCollapsed : this.opt.sImageExpanded); 179 document.getElementById(this.opt.sContainerId).style.display = this.bCollapsed ? '' : 'none'; 180 181 this.bCollapsed = !this.bCollapsed; 182} 183 184// *** QuickModify object. 185function QuickModify(oOptions) 186{ 187 this.opt = oOptions; 188 this.bInEditMode = false; 189 this.sCurMessageId = ''; 190 this.oCurMessageDiv = null; 191 this.oCurSubjectDiv = null; 192 this.sMessageBuffer = ''; 193 this.sSubjectBuffer = ''; 194 this.bXmlHttpCapable = this.isXmlHttpCapable(); 195 196 // Show the edit buttons 197 if (this.bXmlHttpCapable) 198 { 199 for (var i = document.images.length - 1; i >= 0; i--) 200 if (document.images[i].id.substr(0, 14) == 'modify_button_') 201 document.images[i].style.display = ''; 202 } 203} 204 205// Determine whether the quick modify can actually be used. 206QuickModify.prototype.isXmlHttpCapable = function () 207{ 208 if (typeof(window.XMLHttpRequest) == 'undefined') 209 return false; 210 211 // Opera didn't always support POST requests. So test it first. 212 if ('opera' in window) 213 { 214 var oTest = new XMLHttpRequest(); 215 if (!('setRequestHeader' in oTest)) 216 return false; 217 } 218 219 return true; 220} 221 222// Function called when a user presses the edit button. 223QuickModify.prototype.modifyMsg = function (iMessageId) 224{ 225 if (!this.bXmlHttpCapable) 226 return; 227 228 // Add backwards compatibility with old themes. 229 if (typeof(sSessionVar) == 'undefined') 230 sSessionVar = 'sesc'; 231 232 // First cancel if there's another message still being edited. 233 if (this.bInEditMode) 234 this.modifyCancel(); 235 236 // At least NOW we're in edit mode 237 this.bInEditMode = true; 238 239 // Send out the XMLhttp request to get more info 240 ajax_indicator(true); 241 242 // For IE 5.0 support, 'call' is not yet used. 243 this.tmpMethod = getXMLDocument; 244 this.tmpMethod(smf_prepareScriptUrl(this.opt.sScriptUrl) + 'action=quotefast;quote=' + iMessageId + ';modify;xml', this.onMessageReceived); 245 delete this.tmpMethod; 246} 247 248// The callback function used for the XMLhttp request retrieving the message. 249QuickModify.prototype.onMessageReceived = function (XMLDoc) 250{ 251 var sBodyText = '', sSubjectText = ''; 252 253 // No longer show the 'loading...' sign. 254 ajax_indicator(false); 255 256 // Grab the message ID. 257 this.sCurMessageId = XMLDoc.getElementsByTagName('message')[0].getAttribute('id'); 258 259 // If this is not valid then simply give up. 260 if (!document.getElementById(this.sCurMessageId)) 261 return this.modifyCancel(); 262 263 // Replace the body part. 264 for (var i = 0; i < XMLDoc.getElementsByTagName("message")[0].childNodes.length; i++) 265 sBodyText += XMLDoc.getElementsByTagName("message")[0].childNodes[i].nodeValue; 266 this.oCurMessageDiv = document.getElementById(this.sCurMessageId); 267 this.sMessageBuffer = getInnerHTML(this.oCurMessageDiv); 268 269 // We have to force the body to lose its dollar signs thanks to IE. 270 sBodyText = sBodyText.replace(/\$/g, '{&dollarfix;$}'); 271 272 // Actually create the content, with a bodge for disappearing dollar signs. 273 setInnerHTML(this.oCurMessageDiv, this.opt.sTemplateBodyEdit.replace(/%msg_id%/g, this.sCurMessageId.substr(4)).replace(/%body%/, sBodyText).replace(/\{&dollarfix;\$\}/g, '$')); 274 275 // Replace the subject part. 276 this.oCurSubjectDiv = document.getElementById('subject_' + this.sCurMessageId.substr(4)); 277 this.sSubjectBuffer = getInnerHTML(this.oCurSubjectDiv); 278 279 sSubjectText = XMLDoc.getElementsByTagName('subject')[0].childNodes[0].nodeValue.replace(/\$/g, '{&dollarfix;$}'); 280 setInnerHTML(this.oCurSubjectDiv, this.opt.sTemplateSubjectEdit.replace(/%subject%/, sSubjectText).replace(/\{&dollarfix;\$\}/g, '$')); 281 282 return true; 283} 284 285// Function in case the user presses cancel (or other circumstances cause it). 286QuickModify.prototype.modifyCancel = function () 287{ 288 // Roll back the HTML to its original state. 289 if (this.oCurMessageDiv) 290 { 291 setInnerHTML(this.oCurMessageDiv, this.sMessageBuffer); 292 setInnerHTML(this.oCurSubjectDiv, this.sSubjectBuffer); 293 } 294 295 // No longer in edit mode, that's right. 296 this.bInEditMode = false;
297 298 return false; 299} 300 301// The function called after a user wants to save his precious message. 302QuickModify.prototype.modifySave = function (sSessionId, sSessionVar) 303{ 304 // We cannot save if we weren't in edit mode. 305 if (!this.bInEditMode) 306 return true; 307 308 // Add backwards compatibility with old themes. 309 if (typeof(sSessionVar) == 'undefined') 310 sSessionVar = 'sesc'; 311 312 var i, x = new Array(); 313 x[x.length] = 'subject=' + escape(document.forms.quickModForm['subject'].value.replace(/&#/g, "&#").php_to8bit()).replace(/\+/g, "%2B"); 314 x[x.length] = 'message=' + escape(document.forms.quickModForm['message'].value.replace(/&#/g, "&#").php_to8bit()).replace(/\+/g, "%2B"); 315 x[x.length] = 'topic=' + parseInt(document.forms.quickModForm.elements['topic'].value); 316 x[x.length] = 'msg=' + parseInt(document.forms.quickModForm.elements['msg'].value); 317 318 // Send in the XMLhttp request and let's hope for the best. 319 ajax_indicator(true); 320 sendXMLDocument.call(this, smf_prepareScriptUrl(this.opt.sScriptUrl) + "action=jsmodify;topic=" + this.opt.iTopicId + ";" + sSessionVar + "=" + sSessionId + ";xml", x.join("&"), this.onModifyDone); 321 322 return false; 323} 324 325// Callback function of the XMLhttp request sending the modified message. 326QuickModify.prototype.onModifyDone = function (XMLDoc) 327{ 328 // We've finished the loading stuff. 329 ajax_indicator(false); 330 331 // If we didn't get a valid document, just cancel. 332 if (!XMLDoc || !XMLDoc.getElementsByTagName('smf')[0]) 333 { 334 // Mozilla will nicely tell us what's wrong. 335 if (XMLDoc.childNodes.length > 0 && XMLDoc.firstChild.nodeName == 'parsererror') 336 setInnerHTML(document.getElementById('error_box'), XMLDoc.firstChild.textContent); 337 else 338 this.modifyCancel(); 339 return; 340 } 341 342 var message = XMLDoc.getElementsByTagName('smf')[0].getElementsByTagName('message')[0]; 343 var body = message.getElementsByTagName('body')[0]; 344 var error = message.getElementsByTagName('error')[0]; 345 346 if (body) 347 { 348 // Show new body. 349 var bodyText = ''; 350 for (var i = 0; i < body.childNodes.length; i++) 351 bodyText += body.childNodes[i].nodeValue; 352 353 this.sMessageBuffer = this.opt.sTemplateBodyNormal.replace(/%body%/, bodyText.replace(/\$/g, '{&dollarfix;$}')).replace(/\{&dollarfix;\$\}/g,'$'); 354 setInnerHTML(this.oCurMessageDiv, this.sMessageBuffer); 355 356 // Show new subject. 357 var oSubject = message.getElementsByTagName('subject')[0]; 358 var sSubjectText = oSubject.childNodes[0].nodeValue.replace(/\$/g, '{&dollarfix;$}'); 359 this.sSubjectBuffer = this.opt.sTemplateSubjectNormal.replace(/%msg_id%/g, this.sCurMessageId.substr(4)).replace(/%subject%/, sSubjectText).replace(/\{&dollarfix;\$\}/g,'$'); 360 setInnerHTML(this.oCurSubjectDiv, this.sSubjectBuffer); 361 362 // If this is the first message, also update the topic subject. 363 if (oSubject.getAttribute('is_first') == '1') 364 setInnerHTML(document.getElementById('top_subject'), this.opt.sTemplateTopSubject.replace(/%subject%/, sSubjectText).replace(/\{&dollarfix;\$\}/g, '$')); 365 366 // Show this message as 'modified on x by y'. 367 if (this.opt.bShowModify) 368 setInnerHTML(document.getElementById('modified_' + this.sCurMessageId.substr(4)), message.getElementsByTagName('modified')[0].childNodes[0].nodeValue); 369 } 370 else if (error) 371 { 372 setInnerHTML(document.getElementById('error_box'), error.childNodes[0].nodeValue); 373 document.forms.quickModForm.message.style.border = error.getAttribute('in_body') == '1' ? this.opt.sErrorBorderStyle : ''; 374 document.forms.quickModForm.subject.style.border = error.getAttribute('in_subject') == '1' ? this.opt.sErrorBorderStyle : ''; 375 } 376} 377 378function InTopicModeration(oOptions) 379{ 380 this.opt = oOptions; 381 this.bButtonsShown = false; 382 this.iNumSelected = 0; 383 384 // Add backwards compatibility with old themes. 385 if (typeof(this.opt.sSessionVar) == 'undefined') 386 this.opt.sSessionVar = 'sesc'; 387 388 this.init(); 389} 390 391InTopicModeration.prototype.init = function() 392{ 393 // Add checkboxes to all the messages. 394 for (var i = 0, n = this.opt.aMessageIds.length; i < n; i++) 395 { 396 // Create the checkbox. 397 var oCheckbox = document.createElement('input'); 398 oCheckbox.type = 'checkbox'; 399 oCheckbox.className = 'input_check'; 400 oCheckbox.name = 'msgs[]'; 401 oCheckbox.value = this.opt.aMessageIds[i]; 402 oCheckbox.instanceRef = this; 403 oCheckbox.onclick = function () { 404 this.instanceRef.handleClick(this); 405 } 406 407 // Append it to the container 408 var oCheckboxContainer = document.getElementById(this.opt.sCheckboxContainerMask + this.opt.aMessageIds[i]); 409 oCheckboxContainer.appendChild(oCheckbox); 410 oCheckboxContainer.style.display = ''; 411 } 412} 413 414InTopicModeration.prototype.handleClick = function(oCheckbox) 415{ 416 if (!this.bButtonsShown && this.opt.sButtonStripDisplay) 417 { 418 var oButtonStrip = document.getElementById(this.opt.sButtonStrip); 419 var oButtonStripDisplay = document.getElementById(this.opt.sButtonStripDisplay); 420
421 // Make sure it can go somewhere. 422 if (typeof(oButtonStripDisplay) == 'object' && oButtonStripDisplay != null) 423 oButtonStripDisplay.style.display = ""; 424 else 425 { 426 var oNewDiv = document.createElement('div'); 427 var oNewList = document.createElement('ul'); 428 429 oNewDiv.id = this.opt.sButtonStripDisplay; 430 oNewDiv.className = this.opt.sButtonStripClass ? this.opt.sButtonStripClass : 'buttonlist floatbottom'; 431 432 oNewDiv.appendChild(oNewList); 433 oButtonStrip.appendChild(oNewDiv); 434 } 435 436 // Add the 'remove selected items' button. 437 if (this.opt.bCanRemove) 438 smf_addButton(this.opt.sButtonStrip, this.opt.bUseImageButton, { 439 sId: this.opt.sSelf + '_remove_button', 440 sText: this.opt.sRemoveButtonLabel, 441 sImage: this.opt.sRemoveButtonImage, 442 sUrl: '#', 443 sCustom: ' onclick="return ' + this.opt.sSelf + '.handleSubmit(\'remove\')"' 444 }); 445 446 // Add the 'restore selected items' button. 447 if (this.opt.bCanRestore) 448 smf_addButton(this.opt.sButtonStrip, this.opt.bUseImageButton, { 449 sId: this.opt.sSelf + '_restore_button', 450 sText: this.opt.sRestoreButtonLabel, 451 sImage: this.opt.sRestoreButtonImage, 452 sUrl: '#', 453 sCustom: ' onclick="return ' + this.opt.sSelf + '.handleSubmit(\'restore\')"' 454 }); 455 456 // Adding these buttons once should be enough. 457 this.bButtonsShown = true; 458 } 459 460 // Keep stats on how many items were selected. 461 this.iNumSelected += oCheckbox.checked ? 1 : -1; 462 463 // Show the number of messages selected in the button. 464 if (this.opt.bCanRemove && !this.opt.bUseImageButton) 465 { 466 setInnerHTML(document.getElementById(this.opt.sSelf + '_remove_button'), this.opt.sRemoveButtonLabel + ' [' + this.iNumSelected + ']'); 467 document.getElementById(this.opt.sSelf + '_remove_button').style.display = this.iNumSelected < 1 ? "none" : ""; 468 } 469 470 if (this.opt.bCanRestore && !this.opt.bUseImageButton) 471 { 472 setInnerHTML(document.getElementById(this.opt.sSelf + '_restore_button'), this.opt.sRestoreButtonLabel + ' [' + this.iNumSelected + ']'); 473 document.getElementById(this.opt.sSelf + '_restore_button').style.display = this.iNumSelected < 1 ? "none" : ""; 474 } 475 476 // Try to restore the correct position. 477 var aItems = document.getElementById(this.opt.sButtonStrip).getElementsByTagName('span'); 478 if (aItems.length > 3) 479 { 480 if (this.iNumSelected < 1) 481 { 482 aItems[aItems.length - 3].className = aItems[aItems.length - 3].className.replace(/\s*position_holder/, 'last'); 483 aItems[aItems.length - 2].className = aItems[aItems.length - 2].className.replace(/\s*position_holder/, 'last'); 484 } 485 else 486 { 487 aItems[aItems.length - 2].className = aItems[aItems.length - 2].className.replace(/\s*last/, 'position_holder'); 488 aItems[aItems.length - 3].className = aItems[aItems.length - 3].className.replace(/\s*last/, 'position_holder'); 489 } 490 } 491} 492 493InTopicModeration.prototype.handleSubmit = function (sSubmitType) 494{ 495 var oForm = document.getElementById(this.opt.sFormId); 496 497 // Make sure this form isn't submitted in another way than this function. 498 var oInput = document.createElement('input'); 499 oInput.type = 'hidden'; 500 oInput.name = this.opt.sSessionVar; 501 oInput.value = this.opt.sSessionId; 502 oForm.appendChild(oInput); 503 504 switch (sSubmitType) 505 { 506 case 'remove': 507 if (!confirm(this.opt.sRemoveButtonConfirm)) 508 return false; 509 510 oForm.action = oForm.action.replace(/;restore_selected=1/, ''); 511 break; 512 513 case 'restore': 514 if (!confirm(this.opt.sRestoreButtonConfirm)) 515 return false; 516 517 oForm.action = oForm.action + ';restore_selected=1'; 518 break; 519 520 default: 521 return false; 522 break; 523 } 524 525 oForm.submit(); 526 return true; 527} 528 529 530// *** Other functions... 531function expandThumb(thumbID) 532{ 533 var img = document.getElementById('thumb_' + thumbID); 534 var link = document.getElementById('link_' + thumbID); 535 var tmp = img.src; 536 img.src = link.href; 537 link.href = tmp; 538 img.style.width = ''; 539 img.style.height = ''; 540 return false; 541}
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.