vBulletin Thread Split

In the thread split interface it allows for toggling between summaries and posts. It makes splitting threads easier.

  1. // ==UserScript==
  2. // @name vBulletin Thread Split
  3. // @description In the thread split interface it allows for toggling between summaries and posts. It makes splitting threads easier.
  4. // @namespace http://home.comcast.net/~mailerdaemon/
  5. // @include http://forums.secondlife.com/postings.php
  6. // @version 0.0.1.20140517011141
  7. // ==/UserScript==
  8.  
  9. //label[starts-with(@for,"checkpost")]
  10. //td[text()="Split Thread" and @class="tcat"]
  11.  
  12. if(!String.prototype.trim) String.prototype.trim = function() { return this.replace(/^\s*/,'').replace(/\s*$/, ''); }//necessary evil
  13.  
  14. var base = $X('//td[text()="Split Thread" and @class="tcat"]/../../../..')
  15. if(!base)
  16. return;
  17.  
  18. var all = $X('//label[@for="cb_allbox"]');
  19. var p = insertAfter(document.createElement("label"), insertAfter(document.createTextNode(" "), all));
  20. var extended = p.insertBefore(document.createElement("input"),null);
  21. extended.type="checkbox"
  22. p.htmlFor=extended.id="cb_full";
  23. insertAfter(document.createTextNode("Extended Information"), extended);
  24.  
  25. var posts = $Y('//label[starts-with(@for,"checkpost")]', base);
  26. var i, post;
  27. var toggles = new Array(posts.length);
  28. for (i = 0; post = posts.snapshotItem(i); ++i)
  29. {
  30. var postnumber = post.htmlFor.replace("checkpost", "");
  31. var table = GetParentNodeByTag(post, "TABLE");
  32. var link = table.rows[2].cells[0];
  33. link.style.cursor="pointer";
  34. var a = table.getElementsByTagName("div")[0];
  35. var b = insertAfter(document.createElement("div"), a);
  36. b.style.cssText=a.style.cssText;
  37. var t = buildToggle(postnumber, i + 1, a, b);
  38. toggles[i] = t;
  39. addEvent( link, "click", t);
  40. // t();
  41. }
  42. addEvent( extended, "click", function(){
  43. for(i = 0; f = toggles[i];i++)
  44. f(extended.checked)
  45. });
  46.  
  47. function buildToggle(postnumber, j, a, b)
  48. {
  49. return function Toggle(force){
  50. if(force != (a.style.display == "none"))
  51. {
  52. if(b.innerHTML == "")
  53. {
  54. GM_xmlhttpRequest({
  55. method: 'GET',
  56. headers: {
  57. 'User-agent': 'Mozilla/4.0 (compatible) Greasemonkey',
  58. 'Content-type': 'application/x-www-form-urlencoded'
  59. },
  60. url: "http://forums.secondlife.com/showpost.php?p="+postnumber+"&postcount="+j,
  61. onload: function load(responseDetails){
  62. b.innerHTML=responseDetails.responseText.replace(/^[\w\W]*?(<!-- icon and title -->[\w\W]*?|)(<!-- message -->[\w\W]*?<!-- \/ message -->)[\w\W]*$/, "$1$2");
  63. a.style.display="none";
  64. b.style.display="block";
  65. // GM_log("got " + postnumber);
  66. }
  67. });
  68. }
  69. else
  70. {
  71. if(a.style.display == "none")
  72. {
  73. a.style.display="block";
  74. b.style.display="none";
  75. // GM_log("hide " + postnumber);
  76. }
  77. else
  78. {
  79. a.style.display="none";
  80. b.style.display="block";
  81. // GM_log("show " + postnumber);
  82. }
  83. }
  84. }
  85. }
  86. }
  87.  
  88. function insertAfter(insert, after){return after.parentNode.insertBefore(insert, after.nextSibling);}
  89. function $X(_xpath, node){return document.evaluate(_xpath, node?node:document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null).snapshotItem(0);}
  90. function $Y(_xpath, node){return document.evaluate(_xpath, node?node:document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);}
  91.  
  92. function GetParentNodeByTag(child, tag, bad) {
  93. tag = tag.toUpperCase();
  94. while((child = child.parentNode) && child.tagName != tag);
  95. return child?child:bad;
  96. }
  97.  
  98. function addEvent( obj, type, fn ) {
  99. if ( obj.attachEvent ) {
  100. obj["e"+type+fn] = fn;
  101. obj[type+fn] = function() { obj["e"+type+fn]( window.event ); }
  102. obj.attachEvent( "on"+type, obj[type+fn] );
  103. } else
  104. obj.addEventListener( type, fn, false );
  105. }
  106. function removeEvent( obj, type, fn ) {
  107. if ( obj.detachEvent ) {
  108. obj.detachEvent( "on"+type, obj[type+fn] );
  109. obj[type+fn] = obj["e"+type+fn] = null;
  110. } else
  111. obj.removeEventListener( type, fn, false );
  112. }