[s4s] interface

Lets you view the greenposts.

目前为 2018-04-04 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name [s4s] interface
  3. // @namespace s4s4s4s4s4s4s4s4s4s
  4. // @include https://boards.4chan.org/s4s/thread/*
  5. // @include http://boards.4chan.org/s4s/thread/*
  6. // @version 1.041
  7. // @grant none
  8. // @author le fun css man AKA Doctor Worse Than Hitler
  9. // @email doctorworsethanhitler@gmail.com
  10. // @description Lets you view the greenposts.
  11. // ==/UserScript==
  12. // basic post html
  13.  
  14. /////////////////////////////////////////////////////////////////////
  15. //////// WANNA SET SOME STUFF UP HERE? GO FOR IT BBY! ///////////////
  16. //////// IT IS THE CONFIGURATION SPOTS WOW ///////////////
  17. var TEXT_COLOR = '#000'; // any css option for color is fine, eg #000, #000000, red, etc
  18. /////////////////////////////////////////////////////////////////////
  19. // (more to come for above)
  20.  
  21.  
  22. //// global variables
  23.  
  24. // The basic HTML of a 4chan post. split into a couple of parts so we can remove the number field. The fields surrounded with &...& are fields to replace later with post text.
  25. var baseHTML = '<div class="sideArrows" id="sa&AFTER_NO&-&ID&">&gt;&gt;</div><div id="p&AFTER_NO&-&ID&" class="post reply" style="background-color: #6f6; border:2px solid green !important;"><div class="postInfo desktop" id="pi&AFTER_NO&-&ID&"><input name="ignore" value="delete" type="checkbox"><span class="nameBlock"><span class="name">&USERNAME&</span> </span> <span class="dateTime" data-utc="&TIMESTAMP&">&DATE& </span>';
  26. var noHTML = '<span class="postNum desktop"><a href="#p&AFTER_NO&-&ID&" title="Link to this post">No.</a><a href="javascript:quote(\'&AFTER_NO&-&ID&\');" title="Reply to this post">&AFTER_NO&-&ID&</a></span>';
  27. var baseHTML2 = '</div><blockquote class="postMessage" style="color:'+TEXT_COLOR+';" id="m&AFTER_NO&-&ID&"><span>&TEXT&</span></blockquote></div>';
  28.  
  29. // the url of the interface.
  30. var url = "https://funposting.online/interface/";
  31.  
  32. // the last good substite for a deleted post. used to correctly place the shadow posts whose [s4s] counterparts have been deleted
  33. var lastGoodSubstitute;
  34.  
  35. // date nonsense
  36. // ripped from https://www.elated.com/articles/working-with-dates/ along with the later date code.
  37. var day_names = new Array();
  38. day_names[day_names.length] = "Sun";
  39. day_names[day_names.length] = "Mon";
  40. day_names[day_names.length] = "Tue";
  41. day_names[day_names.length] = "Wed";
  42. day_names[day_names.length] = "Thu";
  43. day_names[day_names.length] = "Fri";
  44. day_names[day_names.length] = "Sat";
  45.  
  46. //// functions
  47.  
  48. // for sending a GET request, used to fetch post JSON from the server.
  49. // ripped from https://stackoverflow.com/questions/247483/http-get-request-in-javascript
  50. var HttpClient = function() {
  51. this.get = function(aUrl, aCallback) {
  52. var anHttpRequest = new XMLHttpRequest();
  53. anHttpRequest.onreadystatechange = function() {
  54. if (anHttpRequest.readyState == 4 && anHttpRequest.status == 200)
  55. aCallback(anHttpRequest.responseText);
  56. }
  57. anHttpRequest.open("GET", aUrl, true);
  58. anHttpRequest.send(null);
  59. }
  60. }
  61.  
  62. // add a post to the proper position in the thread
  63. function addPost(aPost) {
  64. // date options ripped from the site mentioned in the global vars sections
  65. var options = {
  66. weekday: 'long',
  67. year: 'numeric',
  68. month: 'long',
  69. day: 'numeric'
  70. };;
  71. // build the shadow post's html
  72. var posthtml = baseHTML;
  73. if(aPost["options"] == "numberless") {
  74. posthtml += baseHTML2;
  75. posthtml = posthtml.replace(/\&AFTER_NO\&/g, "XXXXXX");
  76. }
  77. else {
  78. posthtml += noHTML;
  79. posthtml += baseHTML2
  80. posthtml = posthtml.replace(/\&AFTER_NO\&/g, aPost["after_no"]);
  81. }
  82. posthtml = posthtml.replace(/\&ID\&/g, aPost["id"]);
  83. posthtml = posthtml.replace(/\&TEXT\&/g, aPost["text"]);
  84. posthtml = posthtml.replace(/\&TIMESTAMP\&/g, aPost["timestamp"]);
  85. var d = new Date(aPost["timestamp"] * 1000);
  86. posthtml = posthtml.replace(/\&DATE\&/g, d.toLocaleDateString() + ' (' + day_names[d.getDay()] + ') ' + d.toLocaleTimeString());
  87. posthtml = posthtml.replace(/\&USERNAME\&/g, aPost["username"]);
  88.  
  89. // insert the post
  90. var after_post = document.getElementById('pc' + aPost["after_no"]);
  91.  
  92.  
  93. var post = document.createElement("div");
  94. post.className = "postContainer replyContainer";
  95. post.id = 'pc' + aPost["after_no"]; // if the last post in a thread isn't a valid post based on the id, when the thread updates the whole fugging thread is reloaded. this is a hacky work around sorry.
  96. post.innerHTML = posthtml;
  97.  
  98. // add the post
  99. if(document.getElementById('p'+aPost["after_no"]) !== null) {
  100. after_post.parentNode.insertBefore(post, after_post.nextSibling);
  101. }
  102. else {
  103. // an [s4s] post was deleted, so we'll search for an appropriate spot to insert this post.
  104. // start at the last known existing post
  105. // var currentPost = lastGoodSubstitute;
  106. var currentPost = getThread();
  107.  
  108. // go through the remaining posts and find the most recent one that is not more recent than the post the interface post originally came after.
  109. while(document.getElementById('pc'+currentPost).nextSibling !== null && document.getElementById('pc'+currentPost).nextSibling.id.split('pc')[1] < aPost["after_no"]
  110. && document.getElementById('pc'+currentPost).nextSibling.id.split('pc')[1] != currentPost)
  111. {
  112. currentPost = document.getElementById('pc'+currentPost).nextSibling.id.split('pc')[1];
  113. }
  114. after_post = document.getElementById('pc' + currentPost);
  115. after_post.parentNode.insertBefore(post, after_post.nextSibling);
  116. lastGoodSubstitute = currentPost;
  117. }
  118.  
  119. return;
  120. }
  121.  
  122. // what thread are we in?
  123. function getThread() {
  124. var thread = document.getElementsByClassName("thread")[0].id;
  125. return thread.split('t')[1];
  126. }
  127.  
  128.  
  129. function LocalMain () {
  130. // add in all the posts
  131. var client = new HttpClient();
  132. lastGoodSubstitute = getThread();
  133. client.get(url+'get.php?thread=' + getThread(), function(response) {
  134. var arr = JSON.parse(response);
  135.  
  136. Object.keys(arr).forEach(function(k) {
  137. addPost(arr[k]);
  138. });
  139. });
  140.  
  141. // add the posting form
  142. var form = document.createElement("div");
  143. form.innerHTML = '<form name="post" action="'+url+'post.php" method="post" enctype="multipart/form-data"> <input name="thread" value="'+ getThread()+'" type="hidden"> <table class="postForm hideMobile" id="postForm" style="display: table; border: 2px solid #0f0; background-color: #9f9"> <tbody> <tr><td colspan="2" style="text-align:center; background-color:green">[s4s] Interface Green Posting Form</td></tr> <tr data-type="Name"> <td style="background-color:green">Name</td> <td> <input name="username" tabindex="1" placeholder="Anonymous" type="text"> </td> </tr> <tr data-type="Name"> <td style="background-color:green">Options</td> <td> <input name="options" tabindex="1" placeholder="Options" type="text"> </td> </tr> <tr data-type="Options"> <td style="background-color:green">Submit: </td> <td> <input value="Post" tabindex="6" type="submit"> </td> </tr> <tr data-type="Comment"> <td style="background-color:green">Comment</td> <td> <textarea name="text" cols="48" rows="4" tabindex="4" wrap="soft"></textarea> </td> </tr> </tbody> </table> </form>'
  144. document.getElementsByClassName("thread")[0].parentNode.insertBefore(form, document.getElementsByClassName("thread")[0].nextSibling);
  145. }
  146.  
  147. // run this stufffffff
  148. window.addEventListener ("load", LocalMain, false);