Guest User

Soylent Upgrade Greasemonkey/Tampermonkey extension v14

a guest
Oct 28th, 2017
128
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. // ==UserScript==
  2. // @name Soylent Upgrade
  3. // @version 14.0
  4. // @grant none
  5. // @match http://soylentnews.org/*article.pl*
  6. // @match http://*.soylentnews.org/*article.pl*
  7. // @match https://soylentnews.org/*article.pl*
  8. // @match https://*.soylentnews.org/*article.pl*
  9.  
  10. // @match http://soylentnews.org/*submit.pl*
  11. // @match http://*.soylentnews.org/*submit.pl*
  12. // @match https://soylentnews.org/*submit.pl*
  13. // @match https://*.soylentnews.org/*submit.pl*
  14.  
  15. // @match http://soylentnews.org/*admin.pl*
  16. // @match http://*.soylentnews.org/*admin.pl*
  17. // @match https://soylentnews.org/*admin.pl*
  18. // @match https://*.soylentnews.org/*admin.pl*
  19.  
  20. // @match http://soylentnews.org/*comments.pl*
  21. // @match http://*.soylentnews.org/*comments.pl*
  22. // @match https://soylentnews.org/*comments.pl*
  23. // @match https://*.soylentnews.org/*comments.pl*
  24.  
  25. // @include /^https?://(.*\.)?soylentnews\.org/.*?journal\.pl.*?/
  26. // @match http://soylentnews.org/*journal.pl*
  27. // @match http://*.soylentnews.org/*journal.pl*
  28. // @match https://soylentnews.org/*journal.pl*
  29. // @match https://*.soylentnews.org/*journal.pl*
  30.  
  31. // @include /^https?://(.*\.)?soylentnews\.org/.*?pollBooth\.pl\?qid=.*/
  32. // ==/UserScript==
  33.  
  34. // Begin User Options:
  35.  
  36. var simplifyChars = true; // Change to false if you don't want stylized quotation marks, ellipses, etc. to be replaced
  37. var stripEmail = false; // Remove auto-filled email from submission
  38. var doiChecker = true; // Add Crossref search to DOIs in the summary
  39. var disableCycler = false; // Change to true to disable the button that cycles through *New* comments
  40.  
  41. // End User Options
  42.  
  43. /* ! http://mths.be/fromcodepoint v0.1.0 by @mathias */
  44. if (!String.fromCodePoint) { (function() { var defineProperty = (function() { try { var object = {}; var $defineProperty = Object.defineProperty; var result = $defineProperty(object, object, object) && $defineProperty; } catch(error) {} return result; }()); var stringFromCharCode = String.fromCharCode; var floor = Math.floor; var fromCodePoint = function() { var MAX_SIZE = 0x4000; var codeUnits = []; var highSurrogate; var lowSurrogate; var index = -1; var length = arguments.length; if (!length) { return ''; } var result = ''; while (++index < length) { var codePoint = Number(arguments[index]); if ( !isFinite(codePoint) || codePoint < 0 || codePoint > 0x10FFFF || floor(codePoint) != codePoint ) { throw RangeError('Invalid code point: ' + codePoint); } if (codePoint <= 0xFFFF) { codeUnits.push(codePoint); } else { codePoint -= 0x10000; highSurrogate = (codePoint >> 10) + 0xD800; lowSurrogate = (codePoint % 0x400) + 0xDC00; codeUnits.push(highSurrogate, lowSurrogate); } if (index + 1 == length || codeUnits.length > MAX_SIZE) { result += stringFromCharCode.apply(null, codeUnits); codeUnits.length = 0; } } return result; }; if (defineProperty) { defineProperty(String, 'fromCodePoint', { 'value': fromCodePoint, 'configurable': true, 'writable': true }); } else { String.fromCodePoint = fromCodePoint; } }()); }
  45.  
  46. // Add "Quote This" buttons to all initially visible comments
  47. var spans = document.getElementsByTagName("span");
  48. for (var x=0; x<spans.length; x++)
  49. {
  50.     if (spans[x].id.indexOf("reply_link_")==0)
  51.     {
  52.         var button = document.createElement("span");
  53.         button.setAttribute("class","nbutton");
  54.         var p = document.createElement("p");
  55.         var b = document.createElement("b");
  56.         var a = document.createElement("a");
  57.         // Set the href of the "Quote This" button to the href of the "Reply to This" button, with the escaped contents of the post added to URL and any [domain.names] following links in the post cut out:
  58.         a.setAttribute("href",spans[x].getElementsByTagName("a")[0].href.replace("#post_comment","&postercomment="+escape("<blockquote>"+document.getElementById("comment_body_"+spans[x].id.replace("reply_link_","")).innerHTML.replace(/<\/a>\s\[.*?\..*?\]/g,"<\/a>")+"<\/blockquote>\n\n")+"#post_comment"));
  59.         // To Do: Shorten URLs longer than 2000 characters
  60.         a.appendChild(document.createTextNode("Quote This"));
  61.         b.appendChild(a);
  62.         p.appendChild(b);
  63.         button.appendChild(p);
  64.         spans[x].parentNode.insertBefore(button, spans[x].nextSibling);
  65.         spans[x].parentNode.insertBefore(document.createTextNode(" "), spans[x].nextSibling); // Divider
  66.     }
  67. }
  68.  
  69. // DOI checker in the summary
  70. if (doiChecker && window.location.href.search(/https?\:\/\/.*soylentnews\.org.*?\/article\.pl/)!=-1)
  71. {
  72.     var summary = document.getElementById("articles").getElementsByClassName("intro")[0];
  73.     summary.innerHTML = summary.innerHTML.replace(/(\(|\[)DOI: (10[^\s\n<]*)(\)|\])/gi,"$1DOI: <a href='http://search.crossref.org/?q=$2' target='_blank'>$2</a>$3");
  74.     summary.innerHTML = summary.innerHTML.replace(/(\(|\[)open, DOI: (10[^\s\n<]*)(\)|\])/gi,"$1open, DOI: <a href='http://search.crossref.org/?q=$2' target='_blank'>$2</a>$3");
  75.     if (document.getElementById("articles").getElementsByClassName("full").length > 0)
  76.     {
  77.         var summary2 = document.getElementById("articles").getElementsByClassName("full")[0];
  78.         summary2.innerHTML = summary2.innerHTML.replace(/(\(|\[)DOI: (10[^\s\n<]*)(\)|\])/gi,"$1DOI: <a href='http://search.crossref.org/?q=$2' target='_blank'>$2</a>$3");
  79.         summary2.innerHTML = summary2.innerHTML.replace(/(\(|\[)open, DOI: (10[^\s\n<]*)(\)|\])/gi,"$1open, DOI: <a href='http://search.crossref.org/?q=$2' target='_blank'>$2</a>$3");
  80.     }
  81. }
  82.  
  83. // Empty email input area, but only on submission page
  84. if (stripEmail && window.location.href.search(/https?\:\/\/.*soylentnews\.org.*?\/submit\.pl/)!=-1)
  85. {
  86.     var boxes = document.getElementsByTagName("input");
  87.     for (var x=0; x<boxes.length; x++)
  88.     {
  89.         if (boxes[x].name == "email")
  90.         {
  91.             boxes[x].value = "";
  92.         }
  93.     }
  94. }
  95.  
  96. // Add title case button next to title/subj field on Story Submissions, Submission Preview, Story Preview, and New Journal
  97. if (window.location.href.search(/https?\:\/\/.*soylentnews\.org.*?\/(submit\.pl|admin\.pl|journal\.pl|journal\.pl\?op=edit)/)!=-1)
  98. {
  99.     var boxes = document.getElementsByTagName("input");
  100.     for (var x=0; x<boxes.length; x++)
  101.     {
  102.         if (boxes[x].name == "title" || boxes[x].name == "subj" || boxes[x].name == "description")
  103.         {
  104.             boxes[x].id = "storyTitle";
  105.             var button = document.createElement("input");
  106.             button.setAttribute("type","button");
  107.             button.setAttribute("value","Title Case");
  108.             button.setAttribute("title","Convert title to title case.");
  109.             button.setAttribute("onclick","document.getElementById('storyTitle').value=document.getElementById('storyTitle').value.replace(/^\\s/gi,'').replace(/\\b([a-z])/gi,function(m, p1){return p1.toUpperCase();}).replace(/\\b(at|of|is|and|to|in|by|as|its|be|the|on|a|an|but|or|for)\\b/gi,function(m, p1){return p1.toLowerCase();}).replace(/^([a-z])/gi,function(m, p1){return p1.toUpperCase();}).replace(/:\\s([a-z])/gi,function(m, p1){return ': '+p1.toUpperCase();}).replace(/([a-z])['\u2019]([a-z])/gi,function(m, p1, p2){return p1+'\\''+p2.toLowerCase();}).replace(/\\bx(86|64)\\b/gi,'x$1').replace(/\\bIphone/gi,'iPhone').replace(/\\s$/gi,'');");
  110.             boxes[x].parentNode.insertBefore(button, boxes[x].nextSibling);
  111.             if (window.location.href.search(/https?\:\/\/.*soylentnews\.org.*?\/admin\.pl/)!=-1 || boxes[x].name == "subj")
  112.             {
  113.                 boxes[x].parentNode.insertBefore(document.createElement("br"), boxes[x].nextSibling);
  114.             }
  115.             else
  116.             {
  117.                 boxes[x].parentNode.insertBefore(document.createTextNode(" "), boxes[x].nextSibling);
  118.             }
  119.         }
  120.     }
  121. }
  122.  
  123. // Add warning for creating a story in the past
  124. if (window.location.href.search(/https?\:\/\/.*soylentnews\.org.*?\/admin\.pl/)!=-1)
  125. {
  126.     var boxes = document.getElementsByTagName("input");
  127.     for (var x=0; x<boxes.length; x++)
  128.     {
  129.         if (boxes[x].name == "op" && (boxes[x].value == "save"))
  130.         {
  131.             // New onclick extracts the post date, compares to the current date, and only submits if the post date is in the future or the user overrides the warning:
  132.             boxes[x].setAttribute("onclick","var d = new Date(document.getElementById('slashstoryform').elements['time'].value.replace(/\\s/,'T')); var a = true; if (d < Date.now()){a = confirm('Are you sure you want to post a story '+(Math.round((Date.now()-d)/60000))+' minutes in the past?');} if (a) {st_submit(this);}");
  133.         }
  134.     }
  135. }
  136.  
  137. // Expand all initially hidden spoiler blocks when editing a story
  138. if (window.location.href.search(/https?\:\/\/.*soylentnews\.org.*?\/admin\.pl/)!=-1)
  139. {
  140.     var boxes = document.getElementsByTagName("input");
  141.     for (var x=0; x<boxes.length; x++)
  142.     {
  143.         if (boxes[x].className == "spoiler")
  144.         {
  145.             boxes[x].checked = true;
  146.         }
  147.     }
  148. }
  149.  
  150. // Add draft capabilties to story submission form
  151. if (window.location.href.search(/https?\:\/\/.*soylentnews\.org.*?\/submit\.pl/)!=-1)
  152. {
  153.     var boxes = document.getElementsByTagName("textarea");
  154.     for (var x=0; x<boxes.length; x++)
  155.     {
  156.         if (boxes[x].name == "story")
  157.         {
  158.             var p = document.createElement("p");
  159.            
  160.             // Save Draft button
  161.             var button = document.createElement("input");
  162.             button.setAttribute("type","button");
  163.             button.setAttribute("value","Save Draft");
  164.             button.setAttribute("onclick","saveSoydraft();");
  165.             p.appendChild(button);
  166.            
  167.             p.appendChild(document.createTextNode(" "));
  168.            
  169.             // Discard Draft button
  170.             var button = document.createElement("input");
  171.             button.setAttribute("type","button");
  172.             button.setAttribute("id","discardDraft");
  173.             button.setAttribute("value","Discard");
  174.             // Disable the Discard Draft button onload if no draft is available
  175.             if(!localStorage.getItem("soydraft"))
  176.             {
  177.                 button.setAttribute("disabled","disabled");
  178.             }
  179.             else
  180.             {
  181.                 button.setAttribute("onclick","discardSoydraft();");
  182.             }
  183.             p.appendChild(button);
  184.            
  185.             p.appendChild(document.createTextNode(" "));
  186.            
  187.             // Autosave checkbox
  188.             var span = document.createElement("span");
  189.             span.setAttribute("id","autosaveBar");
  190.             // Hide autosave checkbox onload if no draft is available
  191.             if (document.getElementById("storyTitle").value == "" && boxes[x].value == "")
  192.             {
  193.                 if(localStorage.getItem("soydraft"))
  194.                 {
  195.                     span.setAttribute("style","visibility:visible;");
  196.                 }
  197.                 else
  198.                 {
  199.                     span.setAttribute("style","visibility:hidden;");
  200.                 }
  201.             }
  202.             span.appendChild(document.createTextNode("Autosave?"));
  203.             var checkbox = document.createElement("input");
  204.             checkbox.setAttribute("type","checkbox");
  205.             checkbox.setAttribute("id","autosave");
  206.             checkbox.setAttribute("value","");
  207.             checkbox.setAttribute("onclick","if (this.checked==false){autosaveOff();} else {autosaveOn();}");
  208.             checkbox.setAttribute("style","vertical-align:middle;");
  209.             span.appendChild(checkbox);
  210.             span.appendChild(document.createTextNode(" "));
  211.             p.appendChild(span);
  212.            
  213.             // "Saved." text will appear and fade out whenever a draft is saved
  214.             var span2 = document.createElement("span");
  215.             span2.setAttribute("id","autosaveState");
  216.             span2.setAttribute("style","opacity:0;");
  217.             span2.appendChild(document.createTextNode("Saved."));
  218.             p.appendChild(span2);
  219.            
  220.             boxes[x].parentNode.insertBefore(p, boxes[x]);
  221.            
  222.             // Load draft if it exists, but only if workspace is clear
  223.             if (document.getElementById("storyTitle").value == "" && boxes[x].value == "")
  224.             {
  225.                 if(localStorage.getItem("soydraft"))
  226.                 {
  227.                     document.getElementById("storyTitle").value = decodeURI(JSON.parse(localStorage.getItem("soydraft"))[0]);
  228.                     for (var y=0; y<document.getElementsByClassName("fullbox").length; y++)
  229.                     {
  230.                         if (document.getElementsByClassName("fullbox")[y].name == "dept")
  231.                         {
  232.                             document.getElementsByClassName("fullbox")[y].value = decodeURI(JSON.parse(localStorage.getItem("soydraft"))[1]);
  233.                             break;
  234.                         }
  235.                     }
  236.                     document.getElementById("primaryskid").value = JSON.parse(localStorage.getItem("soydraft"))[2];
  237.                     document.getElementById("tid").value = JSON.parse(localStorage.getItem("soydraft"))[3];
  238.                     boxes[x].value = decodeURI(JSON.parse(localStorage.getItem("soydraft"))[4]);
  239.                 }
  240.             }
  241.         }
  242.     }
  243. }
  244.  
  245. var boxes = document.getElementsByTagName("textarea");
  246. for (var x=0; x<boxes.length; x++)
  247. {
  248.     if (boxes[x].name == "introtext" || boxes[x].name == "bodytext" || boxes[x].name == "story")
  249.     {
  250.         var temp = boxes[x].value; // Retrieve textarea contents
  251.         temp = temp.replace(/<\/p><p>/g,"<\/p>\n\n<p>"); // Add newlines between paragraphs
  252.         temp = temp.replace(/<br>\s?<br>/g,"<\/p>\n\n<p>"); // Convert double break tags to paragraph tags
  253.         temp = temp.replace(/<\/blockquote><p>/g,"<\/blockquote>\n\n<p>"); // Add newlines after blockquotes
  254.         temp = temp.replace(/<\/p><blockquote>/g,"<\/p>\n\n<blockquote>"); // Add newlines before blockquotes
  255.         temp = temp.replace(/<blockquote><div><p>/g,"<blockquote><div>\n\n<p>"); // Add newlines within start of blockquotes
  256.         temp = temp.replace(/<\/p><\/div><\/blockquote>/g,"<\/p>\n\n<\/div><\/blockquote>"); // Add newlines within end of blockquotes
  257.         temp = temp.replace(/<\/blockquote><blockquote>/g,"<\/blockquote>\n\n<blockquote>"); // Add newlines between two blockquotes
  258.         temp = temp.replace(/<p class="byline">\s/i,"<p class=\"byline\">"); // Remove extra space from byline
  259.         temp = temp.replace(/<p>\s/g,"<p>"); // Remove extra space from start of paragraph
  260.         temp = temp.replace(/\s<\/p>/g,"<\/p>"); // Remove extra space from end of paragraph
  261.         temp = temp.replace(/<\/li><li>/g,"<\/li>\n<li>"); // Add newlines between list items
  262.         temp = temp.replace(/(<\/li>)(<\/[u|o]l>)/g,'$1\n$2'); // Add newline after last list item
  263.         temp = temp.replace(/(<\/p>)(<[u|o]l>)/g,'$1\n$2'); // Add newlines before lists
  264.         temp = temp.replace(/<p>\[...\]/g,"<p>[...] "); // Add space within beginning of foreshortened paragraph
  265.         while (temp.indexOf("  ")!=-1)
  266.         {
  267.             temp = temp.replace(/  /g," "); // Replace double spaces with single spaces
  268.         }
  269.         if (simplifyChars)
  270.         {
  271.             temp = temp.replace(/\u2018/g,"'"); // 'LEFT SINGLE QUOTATION MARK' (U+2018) to (U+0027)
  272.             temp = temp.replace(/\u2019/g,"'"); // 'RIGHT SINGLE QUOTATION MARK' (U+2019) to (U+0027)
  273.             temp = temp.replace(/\u201C/g,"\""); // 'LEFT DOUBLE QUOTATION MARK' (U+201C) to (U+0022)
  274.             temp = temp.replace(/\u201D/g,"\""); // 'RIGHT DOUBLE QUOTATION MARK' (U+201D) to (U+0022)
  275.             temp = temp.replace(/\u2026/g,"..."); // 'HORIZONTAL ELLIPSIS' (U+2026) to (U+002E) x3
  276.         }
  277.         boxes[x].value = temp;
  278.         boxes[x].rows = 32; // Expand textarea height to 32 rows
  279.     }
  280.     var toolbar = document.createElement("div");
  281.    
  282.     // Blockquote button
  283.     var tempbutton = document.createElement("input");
  284.     tempbutton.setAttribute("type","button");
  285.     tempbutton.setAttribute("value","Blockquote");
  286.     tempbutton.setAttribute("title","Wrap \u003Cblockquote\u003E tags around the selected text.");
  287.     tempbutton.setAttribute("onclick","addBlockquote(document.getElementsByTagName('textarea')["+x+"]);");
  288.     toolbar.appendChild(tempbutton);
  289.    
  290.     // Paragraph and Line break buttons
  291.     var tempspan = document.createElement("span");
  292.     tempspan.setAttribute("id","htmlFormatButtons");
  293.     if (document.getElementById("posttype") && document.getElementById("posttype").selectedIndex == 0)
  294.     {
  295.         tempspan.setAttribute("style","display:none;"); // Hide if initial post type option is "Plain Old Text"
  296.     }
  297.     if (document.getElementById("posttype"))
  298.     {
  299.         document.getElementById("posttype").addEventListener("change", function() {if (document.getElementById('posttype').selectedIndex == 0) {document.getElementById('htmlFormatButtons').style.display = 'none'} else {document.getElementById('htmlFormatButtons').style.display = 'inline'}}); // Change visibility of these buttons based on value of post type
  300.     }
  301.     var tempbutton = document.createElement("input");
  302.     tempbutton.setAttribute("type","button");
  303.     tempbutton.setAttribute("value","P");
  304.     tempbutton.setAttribute("title","Wrap \u003Cp\u003E tags around the selected text.");
  305.     tempbutton.setAttribute("onclick","addPara(document.getElementsByTagName('textarea')["+x+"]);");
  306.     tempspan.appendChild(tempbutton);
  307.     var tempbutton = document.createElement("input");
  308.     tempbutton.setAttribute("type","button");
  309.     tempbutton.setAttribute("value","BR");
  310.     tempbutton.setAttribute("title","Insert a line break.");
  311.     tempbutton.setAttribute("onclick","addBreak(document.getElementsByTagName('textarea')["+x+"]);");
  312.     tempspan.appendChild(tempbutton);
  313.     toolbar.appendChild(tempspan);
  314.    
  315.     // HR button, if editing a story
  316.     if (boxes[x].name == "introtext" || boxes[x].name == "bodytext" || boxes[x].name == "story")
  317.     {
  318.         var tempbutton = document.createElement("input");
  319.         tempbutton.setAttribute("type","button");
  320.         tempbutton.setAttribute("value","HR");
  321.         tempbutton.setAttribute("title","Insert a horizontal rule.");
  322.         tempbutton.setAttribute("style","text-decoration:underline overline;");
  323.         tempbutton.setAttribute("onclick","addHRule(document.getElementsByTagName('textarea')["+x+"]);");
  324.         tempspan.appendChild(tempbutton);
  325.         toolbar.appendChild(tempspan);
  326.     }
  327.    
  328.     // URL button
  329.     var tempbutton = document.createElement("input");
  330.     tempbutton.setAttribute("type","button");
  331.     tempbutton.setAttribute("value","URL");
  332.     tempbutton.setAttribute("title","Create a hyperlink around the selected text.");
  333.     tempbutton.setAttribute("style","text-decoration:underline;");
  334.     tempbutton.setAttribute("onclick","addHyperlink(document.getElementsByTagName('textarea')["+x+"]);");
  335.     toolbar.appendChild(tempbutton);
  336.     toolbar.appendChild(document.createTextNode(" "));
  337.    
  338.     // Bold button
  339.     var tempbutton = document.createElement("input");
  340.     tempbutton.setAttribute("type","button");
  341.     tempbutton.setAttribute("value","B");
  342.     tempbutton.setAttribute("title","Bold");
  343.     tempbutton.setAttribute("style","font-weight:bold;");
  344.     tempbutton.setAttribute("onclick","addBold(document.getElementsByTagName('textarea')["+x+"]);");
  345.     toolbar.appendChild(tempbutton);
  346.    
  347.     // Italic button
  348.     var tempbutton = document.createElement("input");
  349.     tempbutton.setAttribute("type","button");
  350.     tempbutton.setAttribute("value","I");
  351.     tempbutton.setAttribute("title","Italic");
  352.     tempbutton.setAttribute("style","font-style:italic;");
  353.     tempbutton.setAttribute("onclick","addItalic(document.getElementsByTagName('textarea')["+x+"]);");
  354.     toolbar.appendChild(tempbutton);
  355.    
  356.     // Strike button
  357.     var tempbutton = document.createElement("input");
  358.     tempbutton.setAttribute("type","button");
  359.     tempbutton.setAttribute("value","S");
  360.     tempbutton.setAttribute("title","Strikethrough");
  361.     tempbutton.setAttribute("style","text-decoration:line-through;");
  362.     tempbutton.setAttribute("onclick","addStrike(document.getElementsByTagName('textarea')["+x+"]);");
  363.     toolbar.appendChild(tempbutton);
  364.    
  365.     toolbar.appendChild(document.createTextNode(" ")); // Divider
  366.    
  367.     // Code button
  368.     var tempbutton = document.createElement("input");
  369.     tempbutton.setAttribute("type","button");
  370.     tempbutton.setAttribute("value","Code");
  371.     tempbutton.setAttribute("title","Wrap \u003Cecode\u003E tags around the selected text.");
  372.     tempbutton.setAttribute("style","font-family:monospace;");
  373.     tempbutton.setAttribute("onclick","addEcode(document.getElementsByTagName('textarea')["+x+"]);");
  374.     toolbar.appendChild(tempbutton);
  375.    
  376.     // Teletype button
  377.     var tempbutton = document.createElement("input");
  378.     tempbutton.setAttribute("type","button");
  379.     tempbutton.setAttribute("value","TT");
  380.     tempbutton.setAttribute("title","Wrap \u003Ctt\u003E (teletype, i.e. monospace) tags around the selected text.");
  381.     tempbutton.setAttribute("style","font-family:monospace;");
  382.     tempbutton.setAttribute("onclick","addTT(document.getElementsByTagName('textarea')["+x+"]);");
  383.     toolbar.appendChild(tempbutton);
  384.    
  385.     // Spoiler button
  386.     var tempbutton = document.createElement("input");
  387.     tempbutton.setAttribute("type","button");
  388.     tempbutton.setAttribute("value","\u25A0\u25A0\u25A0");
  389.     tempbutton.setAttribute("title","Wrap \u003Cspoiler\u003E tags around the selected text.");
  390.     //tempbutton.setAttribute("style","font-family:monospace;");
  391.     tempbutton.setAttribute("onclick","addSpoiler(document.getElementsByTagName('textarea')["+x+"]);");
  392.     toolbar.appendChild(tempbutton);
  393.    
  394.     // Small button, if editing a story
  395.     if (boxes[x].name == "introtext" || boxes[x].name == "bodytext" || boxes[x].name == "story")
  396.     {
  397.         var tempbutton = document.createElement("input");
  398.         tempbutton.setAttribute("type","button");
  399.         tempbutton.setAttribute("value","\u0073\u1D0D\u1D00\u029F\u029F");
  400.         tempbutton.setAttribute("title","Wrap \u003Csmall\u003E tags around the selected text.");
  401.         // tempbutton.setAttribute("style","font-size:75%;");
  402.         tempbutton.setAttribute("onclick","addSmall(document.getElementsByTagName('textarea')["+x+"]);");
  403.         toolbar.appendChild(tempbutton);
  404.     }
  405.    
  406.     toolbar.appendChild(document.createTextNode(" ")); // Divider
  407.    
  408.     // Superscript button
  409.     var tempbutton = document.createElement("input");
  410.     tempbutton.setAttribute("type","button");
  411.     tempbutton.setAttribute("value","x\u00B2");
  412.     tempbutton.setAttribute("title","Superscript");
  413.     tempbutton.setAttribute("style","font-family:monospace;");
  414.     tempbutton.setAttribute("onclick","addSuper(document.getElementsByTagName('textarea')["+x+"]);");
  415.     toolbar.appendChild(tempbutton);
  416.    
  417.     // Subscript button
  418.     var tempbutton = document.createElement("input");
  419.     tempbutton.setAttribute("type","button");
  420.     tempbutton.setAttribute("value","x\u2082");
  421.     tempbutton.setAttribute("title","Subscript");
  422.     tempbutton.setAttribute("style","font-family:monospace;");
  423.     tempbutton.setAttribute("onclick","addSubsc(document.getElementsByTagName('textarea')["+x+"]);");
  424.     toolbar.appendChild(tempbutton);
  425.    
  426.     toolbar.appendChild(document.createTextNode(" ")); // Divider
  427.    
  428.     // Ordered list button
  429.     var tempbutton = document.createElement("input");
  430.     tempbutton.setAttribute("type","button");
  431.     tempbutton.setAttribute("value","1. List");
  432.     tempbutton.setAttribute("title","Insert an ordered list or convert newline-separated text into an ordered list.");
  433.     tempbutton.setAttribute("onclick","addOrdlist(document.getElementsByTagName('textarea')["+x+"],'1');");
  434.     toolbar.appendChild(tempbutton);
  435.    
  436.     // Ordered list button - Alpha
  437.     var tempbutton = document.createElement("input");
  438.     tempbutton.setAttribute("type","button");
  439.     tempbutton.setAttribute("value","A. List");
  440.     tempbutton.setAttribute("title","Insert an ordered list or convert newline-separated text into an ordered list.");
  441.     tempbutton.setAttribute("onclick","addOrdlist(document.getElementsByTagName('textarea')["+x+"],'A');");
  442.     toolbar.appendChild(tempbutton);
  443.    
  444.     // Ordered list button - Roman
  445.     var tempbutton = document.createElement("input");
  446.     tempbutton.setAttribute("type","button");
  447.     tempbutton.setAttribute("value","I. List");
  448.     tempbutton.setAttribute("title","Insert an ordered list or convert newline-separated text into an ordered list.");
  449.     tempbutton.setAttribute("onclick","addOrdlist(document.getElementsByTagName('textarea')["+x+"],'I');");
  450.     toolbar.appendChild(tempbutton);
  451.    
  452.     // Unordered list button
  453.     var tempbutton = document.createElement("input");
  454.     tempbutton.setAttribute("type","button");
  455.     tempbutton.setAttribute("value","\u2022 List");
  456.     tempbutton.setAttribute("title","Insert an unordered list or convert newline-separated text into an unordered list.");
  457.     tempbutton.setAttribute("onclick","addUnordlist(document.getElementsByTagName('textarea')["+x+"]);");
  458.     toolbar.appendChild(tempbutton);
  459.    
  460.     toolbar.appendChild(document.createElement("br")); // Divider
  461.     toolbar.appendChild(document.createElement("br")); // Divider
  462.    
  463.     // Create 7 macro buttons
  464.     for (var i=1; i<=7; i++)
  465.     {
  466.         // Create macros if they don't exist
  467.         if(!localStorage.getItem("soymacro"+i))
  468.         {
  469.             localStorage.setItem("soymacro"+i,JSON.stringify(["M"+i,"string","Sample Text"]));
  470.             //localStorage.setItem("soymacro"+i,JSON.stringify(["M"+i,"regexp","/a/gi","b"]));
  471.         }
  472.         var tempbutton = document.createElement("input");
  473.         tempbutton.setAttribute("type","button");
  474.         tempbutton.setAttribute("id","soymacros"+x+"button"+i);
  475.         tempbutton.setAttribute("value",JSON.parse(localStorage.getItem("soymacro"+i))[0]);
  476.         if (JSON.parse(localStorage.getItem("soymacro"+i))[1]=="string")
  477.         {
  478.             if (JSON.parse(localStorage.getItem("soymacro"+i))[2].length < 40)
  479.             {
  480.                 tempbutton.setAttribute("title","Insert or replace selected text with: " + JSON.parse(localStorage.getItem("soymacro"+i))[2]);
  481.             }
  482.             else
  483.             {
  484.                 tempbutton.setAttribute("title","Insert or replace selected text with: " + JSON.parse(localStorage.getItem("soymacro"+i))[2].substring(0,40)+"...");
  485.             }
  486.             tempbutton.setAttribute("onclick","macroChoose(document.getElementsByTagName('textarea')["+x+"],"+i+");");
  487.         }
  488.         else
  489.         {
  490.             tempbutton.setAttribute("title","Replace text matched by the regular expression: " + JSON.parse(localStorage.getItem("soymacro"+i))[2] + " with: " + JSON.parse(localStorage.getItem("soymacro"+i))[3]);
  491.             tempbutton.setAttribute("onclick","macroChoose(document.getElementsByTagName('textarea')["+x+"],"+i+");");
  492.         }
  493.         toolbar.appendChild(tempbutton);
  494.     }
  495.     // Create macros edit button
  496.     var tempbutton = document.createElement("input");
  497.     tempbutton.setAttribute("type","button");
  498.     tempbutton.setAttribute("value","Edit");
  499.     tempbutton.setAttribute("title","Configure user macros or discard changes.");
  500.     tempbutton.setAttribute("onclick","if (document.getElementById('macrobar"+x+"').style.display == 'none') {document.getElementById('macrobar"+x+"').style.display = 'block'; macrobarInit("+x+");} else {document.getElementById('macrobar"+x+"').style.display = 'none'; if (p = document.getElementById('postercomment')) { var x = p.offsetTop; while (p = p.offsetParent) {x += p.offsetLeft;} window.scrollTo(0,x-75);}}");
  501.     toolbar.appendChild(tempbutton);
  502.    
  503.     toolbar.appendChild(document.createElement("br")); // Divider
  504.    
  505.     // Despace button
  506.     var tempbutton = document.createElement("input");
  507.     tempbutton.setAttribute("type","button");
  508.     tempbutton.setAttribute("value","Despace");
  509.     tempbutton.setAttribute("title","Delete newlines within the selection.");
  510.     tempbutton.setAttribute("onclick","despace(document.getElementsByTagName('textarea')["+x+"]);");
  511.     toolbar.appendChild(tempbutton);
  512.    
  513.     // Symbol button
  514.     var tempbutton = document.createElement("input");
  515.     tempbutton.setAttribute("type","button");
  516.     tempbutton.setAttribute("value",":-)");
  517.     tempbutton.setAttribute("title","Insert a symbol.");
  518.     tempbutton.setAttribute("onclick","if (document.getElementById('smilebar"+x+"').style.display == 'none') {document.getElementById('smilebar"+x+"').style.display = 'block'} else {document.getElementById('smilebar"+x+"').style.display = 'none'; if (p = document.getElementById('postercomment')) { var x = p.offsetTop; while (p = p.offsetParent) {x += p.offsetLeft;} window.scrollTo(0,x-75); } }");
  519.     toolbar.appendChild(tempbutton);
  520.     boxes[x].parentNode.insertBefore(toolbar, boxes[x].nextSibling);
  521.    
  522.     // Symbol list
  523.     var smilebar = document.createElement("div");
  524.     smilebar.setAttribute("style","-moz-user-select:none; -webkit-user-select:none; display:none; font-size:16pt; max-height:240px; overflow:auto; padding:0.5em;");
  525.     smilebar.setAttribute("id","smilebar"+x);
  526.     var smiles = ["\u0026amp;","\u0026lt;","\u0026gt;","\u0026nbsp;"];
  527.    
  528.     var codes = [[161,169],[171,172],[174],[176,177],[180,183],[187,191],[215],[224,255],[402],[629],[632],[916],[920],[931],[934],[937],[945,946],[956],[960],[963],[8211,8213],[8216,8221],[8226],[8230],[8251],[8315],[8331],[8364],[8478],[8482],[8528,8542],[8585],[8592,8652],[8712,8716],[8721],[8730],[8733,8734],[8736],[8743,8749],[8756,8757],[8773],[8776],[8800,8805],[8834,8837],[8984],[9095],[9760],[9762,9765],[9770],[9773,9775],[9784,9794],[9812,9831],[9833,9842],[9850],[9855,9861],[9874,9877],[9882,9885],[9888,9893],[9913],[9940],[9962],[9971],[9981],[9992,10087],[12316],[12336],[21328],[65533],[127744,127756],[127759],[127775,127776],[127797],[127801],[127804,127812],[127817],[127820,127822],[127828,127831],[127838,127839],[127843],[127849],[127855],[127860,127867],[127873,127877],[127884],[127891],[127904,127911],[127918],[127939],[127942],[127977],[128025],[128039],[128074,128078],[128123,128131],[128137,128142],[128148,128150],[128152],[128158],[128161,128165],[128168,128170],[128172],[128175,128177],[128187],[128189,128190],[128193,128194],[128197],[128200,128204],[128206],[128214],[128225,128227],[128231,128233],[128241],[128244],[128246],[128250,128252],[128259],[128266,128270],[128273,128276],[128278,128280],[128286],[128293,128299],[128302,128303],[128509,128565],[128640],[128659],[128681],[128684,128685],[128701]];
  529.    
  530.     for (var i=0; i<codes.length; i++) { if (codes[i].length > 1) { for (var j=codes[i][0]; j<=codes[i][1]; j++) { smiles[smiles.length] = String.fromCodePoint(j); } } else { smiles[smiles.length] = String.fromCodePoint(codes[i][0]); } } // Populate smiles array with code ranges converted to individual characters
  531.    
  532.     smiles = smiles.concat(["xD",":-)",":^)","(^_^;)","(\u00A0\u0361\u00B0\u00A0\u035C\u0296\u00A0\u0361\u00B0)","(\u00A0\u0361\u007E\u00A0\u035C\u0296\u00A0\u0361\u00B0)\uFEFF","\u00AF\u005C\u005F(\u30C4)\u005F\u002F\u00AF","(\u256F\u00B0\u25A1\u00B0\uFF09\u256F\uFE35\u00A0\u253B\u2501\u253B","(\u30CE\u0CA0\u76CA\u0CA0)\u30CE\u5F61\u253B\u2501\u253B","(\u0060\uFF65\u03C9\uFF65\u00B4)","\u0CA0_\u0CA0","\u0295\u2022\u1D25\u2022\u0294","(\u3065\uFFE3\u00A0\u00B3\uFFE3)\u3065","\u0669(\u204E\u275B\u1D17\u275B\u204E)\u06F6","\u30FD\u0F3C\u0E88\u0644\u035C\u0E88\u0F3D\uFF89","(\uB208\u2038\uB208)","\u006F(\u3003\uFF3E\u25BD\uFF3E\u3003)\u006F","\u0028\u0028\u30FE\u0028\u2267\u76BF\u2266\uFF1B\u0029\u30CE\uFF3F\u0029\u0029","\u30FD\u0028\u002A\u2312\u2207\u2312\u002A\u0029\uFF89","\u0028\u2267\u2207\u2266\u0029\u002F","\u0028\u0E07\u00A0\u0360\u00B0\u00A0\u035F\u0644\u035C\u00A0\u0361\u00B0\u0029\u0E07"]); // Add in arbitrary emoticons
  533.     // Note: \u00A0 is a non-breaking space character.
  534.    
  535.     for (var i=0; i<smiles.length; i++)
  536.     {
  537.         var smile = document.createElement("span");
  538.         smile.setAttribute("style","cursor:pointer; padding:2px; white-space:nowrap;");
  539.         smile.setAttribute("onclick","addSmile(document.getElementsByTagName('textarea')["+x+"],'"+smiles[i].replace("\u005C","\u005C\u005C")+"');");
  540.         smile.appendChild(document.createTextNode(smiles[i]));
  541.         smilebar.appendChild(smile);
  542.         if (i<smiles.length) // A space is added after every symbol including the final one
  543.         {
  544.             smilebar.appendChild(document.createTextNode(" "));
  545.         }
  546.     }
  547.    
  548.     var flags = [];
  549.     flags = flags.concat([[[127462,127467],"Afghanistan"]]); // AF/Afghanistan
  550.     flags = flags.concat([[[127462,127478],"Antarctica"]]); // AQ/Antarctica
  551.     flags = flags.concat([[[127462,127482],"Australia"]]); // AU/Australia
  552.     flags = flags.concat([[[127463,127465],"Bangladesh"]]); // BD/Bangladesh
  553.     flags = flags.concat([[[127463,127479],"Brazil"]]); // BR/Brazil
  554.     flags = flags.concat([[[127464,127462],"Canada"]]); // CA/Canada
  555.     flags = flags.concat([[[127464,127475],"China"]]); // CN/China
  556.     flags = flags.concat([[[127464,127476],"Colombia"]]); // CO/Colombia
  557.     flags = flags.concat([[[127464,127482],"Cuba"]]); // CU/Cuba
  558.     flags = flags.concat([[[127465,127466],"Germany"]]); // DE/Germany
  559.     flags = flags.concat([[[127466,127468],"Egypt"]]); // EG/Egypt
  560.     flags = flags.concat([[[127466,127480],"Spain"]]); // ES/Spain
  561.     flags = flags.concat([[[127988,917605,917619,917603,917620,917631],"Catalonia"]]); // ES-CT/Catalonia
  562.     flags = flags.concat([[[127466,127482],"European Union"]]); // EU/European Union
  563.     flags = flags.concat([[[127467,127479],"France"]]); // FR/France
  564.     flags = flags.concat([[[127468,127463],"United Kingdom"]]); // GB/United Kingdom
  565.     flags = flags.concat([[[127988,917607,917602,917605,917614,917607,917631],"England"]]); // GB-ENG/England
  566.     flags = flags.concat([[[127988,917607,917602,917619,917603,917620,917631],"Scotland"]]); // GB-SCT/Scotland
  567.     flags = flags.concat([[[127988,917607,917602,917623,917612,917619,917631],"Wales"]]); // GB-WLS/Wales
  568.     flags = flags.concat([[[127468,127479],"Greece"]]); // GR/Greece
  569.     flags = flags.concat([[[127469,127472],"Hong Kong"]]); // HK/Hong Kong
  570.     flags = flags.concat([[[127470,127465],"Indonesia"]]); // ID/Indonesia
  571.     flags = flags.concat([[[127470,127466],"Ireland"]]); // IE/Ireland
  572.     flags = flags.concat([[[127470,127473],"Israel"]]); // IL/Israel
  573.     flags = flags.concat([[[127470,127475],"India"]]); // IN/India
  574.     flags = flags.concat([[[127470,127478],"Iraq"]]); // IQ/Iraq
  575.     flags = flags.concat([[[127470,127479],"Iran"]]); // IR/Iran
  576.     flags = flags.concat([[[127470,127481],"Italy"]]); // IT/Italy
  577.     flags = flags.concat([[[127471,127474],"Jamaica"]]); // JM/Jamaica
  578.     flags = flags.concat([[[127471,127477],"Japan"]]); // JP/Japan
  579.     flags = flags.concat([[[127472,127466],"Kenya"]]); // KE/Kenya
  580.     flags = flags.concat([[[127472,127477],"North Korea"]]); // KP/North Korea
  581.     flags = flags.concat([[[127472,127479],"South Korea"]]); // KR/South Korea
  582.     flags = flags.concat([[[127473,127463],"Lebanon"]]); // LB/Lebanon
  583.     flags = flags.concat([[[127473,127486],"Libya"]]); // LY/Libya
  584.     flags = flags.concat([[[127474,127475],"Mongolia"]]); // MN/Mongolia
  585.     flags = flags.concat([[[127474,127485],"Mexico"]]); // MX/Mexico
  586.     flags = flags.concat([[[127475,127468],"Nigeria"]]); // NG/Nigeria
  587.     flags = flags.concat([[[127477,127466],"Peru"]]); // PE/Peru
  588.     flags = flags.concat([[[127477,127472],"Pakistan"]]); // PK/Pakistan
  589.     flags = flags.concat([[[127477,127479],"Puerto Rico"]]); // PR/Puerto Rico
  590.     flags = flags.concat([[[127477,127480],"Palestinian Territory"]]); // PS/Palestinian Territory
  591.     flags = flags.concat([[[127479,127482],"Russia"]]); // RU/Russia
  592.     flags = flags.concat([[[127480,127462],"Saudi Arabia"]]); // SA/Saudi Arabia
  593.     flags = flags.concat([[[127480,127465],"Sudan"]]); // SD/Sudan
  594.     flags = flags.concat([[[127480,127466],"Sweden"]]); // SE/Sweden
  595.     flags = flags.concat([[[127480,127468],"Singapore"]]); // SG/Singapore
  596.     flags = flags.concat([[[127480,127476],"Somalia"]]); // SO/Somalia
  597.     flags = flags.concat([[[127481,127469],"Thailand"]]); // TH/Thailand
  598.     flags = flags.concat([[[127481,127479],"Turkey"]]); // TR/Turkey
  599.     flags = flags.concat([[[127481,127484],"Taiwan"]]); // TW/Taiwan
  600.     flags = flags.concat([[[127482,127468],"Uganda"]]); // UG/Uganda
  601.     flags = flags.concat([[[127482,127480],"United States"]]); // US/United States
  602.     flags = flags.concat([[[127483,127462],"Vatican City"]]); // VA/Vatican City
  603.     flags = flags.concat([[[127483,127466],"Venezuela"]]); // VE/Venezuela
  604.     flags = flags.concat([[[127487,127462],"South Africa"]]); // ZA/South Africa
  605.     flags = flags.concat([[[127487,127484],"Zimbabwe"]]); // ZW/Zimbabwe
  606.     flags = flags.concat([[[127987],"White Flag"]]); // Waving White Flag
  607.     flags = flags.concat([[[127988],"Black Flag"]]); // Waving Black Flag
  608.     flags = flags.concat([[[127987,65039,8205,127752],"Rainbow Flag"]]); // Waving White Flag + Rainbow
  609.     flags = flags.concat([[[127988,8205,9760,65039],"Pirate Flag"]]); // Waving Black Flag + Skull and Crossbones
  610.     //flags = flags.concat([[[000000,000000],"STRING"]]); // STRING
  611.    
  612.     for (var i=0; i<flags.length; i++)
  613.     {
  614.         var flag = document.createElement("span");
  615.         flag.setAttribute("style","cursor:pointer; padding:2px; white-space:nowrap;");
  616.         var s1 = "", s2 = "";
  617.         for (var j=0; j<flags[i][0].length; j++)
  618.         {
  619.             s1 += String.fromCodePoint(flags[i][0][j]);
  620.             s2 += "&#"+flags[i][0][j]+";";
  621.         }
  622.         flag.setAttribute("onclick","addSmile(document.getElementsByTagName('textarea')["+x+"],'"+s2+"');");
  623.         flag.setAttribute("title",flags[i][1]);
  624.         flag.appendChild(document.createTextNode(s1));
  625.         smilebar.appendChild(flag);
  626.         if (i+1<flags.length)
  627.         {
  628.             smilebar.appendChild(document.createTextNode(" "));
  629.         }
  630.     }
  631.    
  632.     toolbar.parentNode.insertBefore(smilebar, toolbar.nextSibling);
  633.    
  634.     // Create macro configuration interface
  635.     var macrobar = document.createElement("div");
  636.     macrobar.setAttribute("style","display:none; padding:0.5em;");
  637.     macrobar.setAttribute("id","macrobar"+x);
  638.     var table = document.createElement("table");
  639.     var tr = document.createElement("tr");
  640.     var th = document.createElement("th");
  641.     th.appendChild(document.createTextNode("Name"));
  642.     tr.appendChild(th);
  643.     var th = document.createElement("th");
  644.     th.appendChild(document.createTextNode("Type"));
  645.     tr.appendChild(th);
  646.     var th = document.createElement("th");
  647.     th.appendChild(document.createTextNode("String | Expression"));
  648.     tr.appendChild(th);
  649.     var th = document.createElement("th");
  650.     th.setAttribute("title","Only used with expressions. Parenthesized substring matches (e.g. '$1') can be used.");
  651.     th.setAttribute("style","cursor:help;");
  652.     th.appendChild(document.createTextNode("Expression Replace"));
  653.     tr.appendChild(th);
  654.     table.appendChild(tr);
  655.     for (var i=1; i<=7; i++)
  656.     {
  657.         var tr = document.createElement("tr");
  658.        
  659.         // Macro name
  660.         var td = document.createElement("td");
  661.         var name = document.createElement("input");
  662.         name.setAttribute("type","text");
  663.         name.setAttribute("id","soymacros"+x+"name"+i);
  664.         td.appendChild(name);
  665.         tr.appendChild(td);
  666.        
  667.         // Macro type
  668.         var td = document.createElement("td");
  669.         var rad = document.createElement("input");
  670.         rad.setAttribute("type","radio");
  671.         rad.setAttribute("name","soymacros"+x+"type"+i);
  672.         rad.setAttribute("id","soymacros"+x+"type"+i+"S");
  673.         td.appendChild(rad);
  674.         td.appendChild(document.createTextNode(" String "));
  675.         var rad = document.createElement("input");
  676.         rad.setAttribute("type","radio");
  677.         rad.setAttribute("name","soymacros"+x+"type"+i);
  678.         rad.setAttribute("id","soymacros"+x+"type"+i+"E");
  679.         td.appendChild(rad);
  680.         td.appendChild(document.createTextNode(" Expression "));
  681.         tr.appendChild(td);
  682.        
  683.         // Field A
  684.         var td = document.createElement("td");
  685.         var f1 = document.createElement("input");
  686.         f1.setAttribute("type","text");
  687.         f1.setAttribute("id","soymacros"+x+"fieldA"+i);
  688.         td.appendChild(f1);
  689.         tr.appendChild(td);
  690.        
  691.         // Field B
  692.         var td = document.createElement("td");
  693.         var f1 = document.createElement("input");
  694.         f1.setAttribute("type","text");
  695.         f1.setAttribute("id","soymacros"+x+"fieldB"+i);
  696.         td.appendChild(f1);
  697.         tr.appendChild(td);
  698.        
  699.         table.appendChild(tr);
  700.     }
  701.     macrobar.appendChild(table);
  702.    
  703.     var p = document.createElement("p");
  704.     var save = document.createElement("input");
  705.     save.setAttribute("type","button");
  706.     save.setAttribute("value","Save");
  707.     save.setAttribute("title","Save any edits to the macro configuration.");
  708.     save.setAttribute("onclick","macrobarSave("+x+");");
  709.     p.appendChild(save);
  710.     p.appendChild(document.createTextNode(" "));
  711.     var guide = document.createElement("a");
  712.     guide.setAttribute("href","https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions");
  713.     guide.setAttribute("target","_blank");
  714.     guide.appendChild(document.createTextNode("Regexp Guide"));
  715.     p.appendChild(guide);
  716.     macrobar.appendChild(p);
  717.    
  718.     toolbar.parentNode.insertBefore(macrobar, toolbar.nextSibling);
  719. }
  720.  
  721. // Change Stories link to regular admin.pl on breakingnews, meta, politics, and communityreviews nexii
  722. if (window.location.href.search(/https?\:\/\/.*soylentnews\.org.*?\/(breakingnews|meta|politics|communityreviews)\//)!=-1)
  723. {
  724.     if (document.getElementById("adminmenu"))
  725.     {
  726.         var t = document.getElementById("adminmenu").getElementsByTagName("a");
  727.         for (var i=0; i<t.length; i++)
  728.         {
  729.             if (t[i].innerText == "Stories")
  730.             {
  731.                 t[i].setAttribute("href","//soylentnews.org/admin.pl");
  732.             }
  733.         }
  734.     }
  735. }
  736.  
  737. // Easily cycle through *New* comments
  738. if (!disableCycler && (document.querySelector(".newBadge") || (document.querySelector(".dimmed") && document.querySelector(".comment > div.commentDiv:not(.dimmed)"))))
  739. {
  740.     var temp = document.getElementById("links");
  741.     var temp2 = document.createElement("div");
  742.     temp2.setAttribute("style","position:fixed; bottom:15px; z-index:-100;");
  743.     var temp3 = document.createElement("input");
  744.     temp3.setAttribute("type","button");
  745.     temp3.setAttribute("value","New Comment \u00BB");
  746.     temp3.setAttribute("onclick","cycleNew();");
  747.     temp2.appendChild(temp3);
  748.     temp.appendChild(temp2);
  749. }
  750.  
  751. var temp = document.createElement("script");
  752.  
  753. // Add selection handling function
  754. temp.appendChild(document.createTextNode("function getSelection(textarea) { if ('selectionStart' in textarea) { if (textarea.selectionStart != textarea.selectionEnd) { return [textarea.selectionStart,textarea.selectionEnd]; } } } "));
  755.  
  756. // Add comment formatting buttons
  757. temp.appendChild(document.createTextNode("function addBlockquote(area) { var sel = getSelection(area); if (!(sel[0] == 0 && sel[1] == 0)) { area.value = area.value.substring(0,sel[0]) + '<blockquote>'+area.value.substring(sel[0],sel[1])+'<\/blockquote>' + area.value.substring(sel[1]); } } function addPara(area) { var sel = getSelection(area); if (!(sel[0] == 0 && sel[1] == 0)) { area.value = area.value.substring(0,sel[0]) + '<p>'+area.value.substring(sel[0],sel[1])+'<\/p>' + area.value.substring(sel[1]); } } function addBreak(area) { if ('selectionStart' in area) { var pos = area.selectionStart; area.value = area.value.substring(0,area.selectionStart) + '<br>' + area.value.substring(pos); area.focus(); area.setSelectionRange(pos+4,pos+4) } } function addHRule(area) { if ('selectionStart' in area) { var pos = area.selectionStart; area.value = area.value.substring(0,area.selectionStart) + '<hr>' + area.value.substring(pos); area.focus(); area.setSelectionRange(pos+4,pos+4) } } function addHyperlink(area) { var sel = getSelection(area); if (!(sel[0] == 0 && sel[1] == 0)) { url = prompt('URL:', 'https://'); if (url==null) {return false;} area.value = area.value.substring(0,sel[0]) + '<a href=\"'+url+'\">'+area.value.substring(sel[0],sel[1])+'<\/a>' + area.value.substring(sel[1]); } } function addBold(area) { var sel = getSelection(area); if (!(sel[0] == 0 && sel[1] == 0)) { area.value = area.value.substring(0,sel[0]) + '<b>'+area.value.substring(sel[0],sel[1])+'<\/b>' + area.value.substring(sel[1]); } } function addItalic(area) { var sel = getSelection(area); if (!(sel[0] == 0 && sel[1] == 0)) { area.value = area.value.substring(0,sel[0]) + '<em>'+area.value.substring(sel[0],sel[1])+'<\/em>' + area.value.substring(sel[1]); } } function addStrike(area) { var sel = getSelection(area); if (!(sel[0] == 0 && sel[1] == 0)) { area.value = area.value.substring(0,sel[0]) + '<del>'+area.value.substring(sel[0],sel[1])+'<\/del>' + area.value.substring(sel[1]); } } function addEcode(area) { var sel = getSelection(area); if (!(sel[0] == 0 && sel[1] == 0)) { area.value = area.value.substring(0,sel[0]) + '<ecode>'+area.value.substring(sel[0],sel[1])+'<\/ecode>' + area.value.substring(sel[1]); } } function addTT(area) { var sel = getSelection(area); if (!(sel[0] == 0 && sel[1] == 0)) { area.value = area.value.substring(0,sel[0]) + '<tt>'+area.value.substring(sel[0],sel[1])+'<\/tt>' + area.value.substring(sel[1]); } } function addSpoiler(area) { var sel = getSelection(area); if (!(sel[0] == 0 && sel[1] == 0)) { area.value = area.value.substring(0,sel[0]) + '<spoiler>'+area.value.substring(sel[0],sel[1])+'<\/spoiler>' + area.value.substring(sel[1]); } } function addSmall(area) { var sel = getSelection(area); if (!(sel[0] == 0 && sel[1] == 0)) { area.value = area.value.substring(0,sel[0]) + '<small>'+area.value.substring(sel[0],sel[1])+'<\/small>' + area.value.substring(sel[1]); } } function addSuper(area) { var sel = getSelection(area); if (!(sel[0] == 0 && sel[1] == 0)) { area.value = area.value.substring(0,sel[0]) + '<sup>'+area.value.substring(sel[0],sel[1])+'<\/sup>' + area.value.substring(sel[1]); } } function addSubsc(area) { var sel = getSelection(area); if (!(sel[0] == 0 && sel[1] == 0)) { area.value = area.value.substring(0,sel[0]) + '<sub>'+area.value.substring(sel[0],sel[1])+'<\/sub>' + area.value.substring(sel[1]); } } "));
  758.  
  759. // Add list creation functions
  760. temp.appendChild(document.createTextNode("function addOrdlist(area,type) { if ('selectionStart' in area) { if (area.selectionStart != area.selectionEnd) { area.value = area.value.substring(0,area.selectionStart) + '<ol type=\\\"' + type + '\\\"><li>' + area.value.substring(area.selectionStart,area.selectionEnd).replace(/\\n/g,'<\/li>\\n<li>').replace(/\\n<li><\\/li>/g,'') + '<\/li><\/ol>' + area.value.substring(area.selectionEnd); } else { temp = '<ol type=\\\"' + type + '\\\">'; while(listitem = prompt('Enter a list item. Leave the box empty or press Cancel to complete the list:', '')) { temp += '<li>' + listitem + '<\/li>\\n'; } if (temp=='<ol type=\\\"' + type + '\\\">') {return;} area.value = area.value.substring(0,area.selectionStart) + temp.substring(0,temp.length-1) + '<\/ol>' + area.value.substring(area.selectionStart); } } } function addUnordlist(area) { if ('selectionStart' in area) { if (area.selectionStart != area.selectionEnd) { area.value = area.value.substring(0,area.selectionStart) + '<ul><li>' + area.value.substring(area.selectionStart,area.selectionEnd).replace(/\\n/g,'<\/li>\\n<li>').replace(/\\n<li><\\/li>/g,'') + '<\/li><\/ul>' + area.value.substring(area.selectionEnd); } else { temp = '<ul>'; while(listitem = prompt('Enter a list item. Leave the box empty or press Cancel to complete the list:', '')) { temp += '<li>' + listitem + '<\/li>\\n'; } if (temp=='<ul>') {return;} area.value = area.value.substring(0,area.selectionStart) + temp.substring(0,temp.length-1) + '<\/ul>' + area.value.substring(area.selectionStart); } } }"));
  761.  
  762. // Add macro functions
  763. temp.appendChild(document.createTextNode("function macroChoose(area,x) { if (JSON.parse(localStorage.getItem('soymacro'+x))[1]=='string') { macroString(area,x); } else { macroRegexp(area,x); } }"));
  764. temp.appendChild(document.createTextNode("function macroString(area,x) { var sel = getSelection(area); if (sel && sel[0] != sel[1]) { area.value = area.value.substring(0,sel[0]) + JSON.parse(localStorage.getItem('soymacro'+x))[2] + area.value.substring(sel[1]); } else if ('selectionStart' in area) { var pos = area.selectionStart; area.value = area.value.substring(0,area.selectionStart) + JSON.parse(localStorage.getItem('soymacro'+x))[2] + area.value.substring(pos); area.focus(); area.setSelectionRange(pos+JSON.parse(localStorage.getItem('soymacro'+x))[2].length,pos+JSON.parse(localStorage.getItem('soymacro'+x))[2].length); } }"));
  765. temp.appendChild(document.createTextNode("function macroRegexp(area,x) { var sel = getSelection(area); if (sel && sel[0] != sel[1]) { var reg = JSON.parse(localStorage.getItem('soymacro'+x))[2]; area.value = area.value.substring(0,sel[0]) + area.value.substring(sel[0],sel[1]).replace(new RegExp(reg.substring(reg.indexOf('/')+1,reg.lastIndexOf('/')), reg.substring(reg.lastIndexOf('/')+1)),JSON.parse(localStorage.getItem('soymacro'+x))[3]) + area.value.substring(sel[1]); } }"));
  766. temp.appendChild(document.createTextNode("function macrobarInit(x) { for (var y=1; y<=7; y++) { document.getElementById('soymacros'+x+'name'+y).value = JSON.parse(localStorage.getItem('soymacro'+y))[0]; if (JSON.parse(localStorage.getItem('soymacro'+y))[1]=='string') { document.getElementById('soymacros'+x+'type'+y+'S').checked = true; } else { document.getElementById('soymacros'+x+'type'+y+'E').checked = true; } document.getElementById('soymacros'+x+'fieldA'+y).value = JSON.parse(localStorage.getItem('soymacro'+y))[2]; if (JSON.parse(localStorage.getItem('soymacro'+y))[1]!='string') { document.getElementById('soymacros'+x+'fieldB'+y).value = JSON.parse(localStorage.getItem('soymacro'+y))[3]; } else { document.getElementById('soymacros'+x+'fieldB'+y).value = ''; } } }"));
  767. temp.appendChild(document.createTextNode("function macrobarSave(x) { for (var y=1; y<=7; y++) { if (document.getElementById('soymacros'+x+'type'+y+'S').checked == true) { localStorage.setItem('soymacro'+y,JSON.stringify([document.getElementById('soymacros'+x+'name'+y).value,'string',document.getElementById('soymacros'+x+'fieldA'+y).value])); } else { localStorage.setItem('soymacro'+y,JSON.stringify([document.getElementById('soymacros'+x+'name'+y).value,'regexp',document.getElementById('soymacros'+x+'fieldA'+y).value,document.getElementById('soymacros'+x+'fieldB'+y).value])); } } document.getElementById('macrobar'+x).style.display = 'none'; var boxes = document.getElementsByTagName('textarea'); for (var z=0; z<boxes.length; z++) { for (var y=1; y<=7; y++) { document.getElementById('soymacros'+z+'button'+y).value = JSON.parse(localStorage.getItem('soymacro'+y))[0]; if (JSON.parse(localStorage.getItem('soymacro'+y))[1]=='string') { if (JSON.parse(localStorage.getItem('soymacro'+y))[2].length < 40) { document.getElementById('soymacros'+z+'button'+y).title = 'Insert or replace selected text with: ' + JSON.parse(localStorage.getItem('soymacro'+y))[2]; } else { document.getElementById('soymacros'+z+'button'+y).title = 'Insert or replace selected text with: ' + JSON.parse(localStorage.getItem('soymacro'+y))[2].substring(0,40)+'...'; } } else { document.getElementById('soymacros'+z+'button'+y).title = 'Replace text matched by the regular expression: ' + JSON.parse(localStorage.getItem('soymacro'+y))[2] + ' with: ' + JSON.parse(localStorage.getItem('soymacro'+y))[3]; } } } }"));
  768.  
  769. // Add despace function
  770. temp.appendChild(document.createTextNode("function despace(area) { var sel = getSelection(area); if (!(sel[0] == 0 && sel[1] == 0)) { area.value = area.value.substring(0,sel[0]) + area.value.substring(sel[0],sel[1]).replace(/\\r/g,' ').replace(/\\n/g,' ').replace(/\\s\\s/g,' ').replace(/\\s\\s/g,' ').replace(/\\s\\s/g,' ').replace(/\\s\\s/g,' ').replace(/\\s\\s/g,' ') + area.value.substring(sel[1]); } }"));
  771.  
  772. // Add unicode insertion function
  773. temp.appendChild(document.createTextNode("function addSmile(area, smile) { if ('selectionStart' in area) { var pos = area.selectionStart; area.value = area.value.substring(0,pos) + smile + area.value.substring(pos); area.focus(); area.setSelectionRange(pos+smile.length,pos+smile.length) } }"));
  774.  
  775. // Add save submission function
  776. temp.appendChild(document.createTextNode("function saveSoydraft() { try {window.clearTimeout(timer);} catch(e){} var boxes = document.getElementsByTagName('textarea'); for (var x=0; x<boxes.length; x++) { if (boxes[x].name == 'story') { if (document.getElementById('storyTitle').value!=''||boxes[x].value!='') { document.getElementById('autosaveBar').style.visibility='visible'; document.getElementById('autosaveState').style.transition='opacity 0s'; document.getElementById('autosaveState').style.opacity='1'; document.getElementById('autosaveState').offsetWidth = document.getElementById('autosaveState').offsetWidth; document.getElementById('autosaveState').style.transition='opacity 1s'; document.getElementById('autosaveState').style.opacity='0'; var y=0; for (y=0; y<document.getElementsByClassName('fullbox').length; y++) { if (document.getElementsByClassName('fullbox')[y].name == 'dept') { break; } } localStorage.setItem('soydraft',JSON.stringify([encodeURI(document.getElementById('storyTitle').value),encodeURI(document.getElementsByClassName('fullbox')[y].value),document.getElementById('primaryskid').value,document.getElementById('tid').value,encodeURI(boxes[x].value)])); document.getElementById('discardDraft').removeAttribute('disabled'); document.getElementById('discardDraft').setAttribute('onclick','discardSoydraft();'); } else { alert('There is no title or story to save.'); } break; } } }"));
  777.  
  778. // Add discard submission function
  779. temp.appendChild(document.createTextNode("function discardSoydraft() { autosaveOff(); document.getElementById('autosave').checked=false; document.getElementById('autosaveBar').style.visibility='hidden'; localStorage.removeItem('soydraft'); document.getElementById('discardDraft').setAttribute('disabled','disabled'); document.getElementById('discardDraft').removeAttribute('onclick'); }"));
  780.  
  781. // Add autosave functions
  782. temp.appendChild(document.createTextNode("function autosaveOn() { var boxes = document.getElementsByTagName('textarea'); for (var x=0; x<boxes.length; x++) { if (boxes[x].name == 'story') { boxes[x].onkeydown = function() {try {window.clearTimeout(timer);} catch(e){} timer = window.setTimeout(function() { if(document.getElementById(\"autosaveBar\").style.visibility==\"visible\") {saveSoydraft();} }, 3000);}; } } document.getElementById('storyTitle').onkeydown = function() {try {window.clearTimeout(timer);} catch(e){} timer = window.setTimeout(function() { if(document.getElementById(\"autosaveBar\").style.visibility==\"visible\") {saveSoydraft();} }, 3000);}; }"));
  783. temp.appendChild(document.createTextNode("function autosaveOff() { var boxes = document.getElementsByTagName('textarea'); for (var x=0; x<boxes.length; x++) { if (boxes[x].name == 'story') { try {window.clearTimeout(timer);} catch(e){} boxes[x].onkeydown = null; } } document.getElementById('storyTitle').onkeydown = null; }"));
  784.  
  785. // Add new comment cycling function
  786. // Credit: charon
  787. temp.appendChild(document.createTextNode("var newComN = 0; var newComments = document.querySelector('.newBadge') ? document.querySelectorAll('.newBadge') : document.querySelectorAll('.comment > div:not(.dimmed)'); function cycleNew() {if (!newComments[newComN]) {return;} if (newComN != 0 && window.pageYOffset > newComments[newComN].offsetTop + 100) {while (newComments[newComN].offsetTop <= window.pageYOffset){newComN++;}} var p = newComments[newComN++]; var y = p.offsetTop; while (p = p.offsetParent) {y += p.offsetLeft;} window.scrollTo(0,y); if(newComN>=newComments.length-1){newComN=0;}}"));
  788.  
  789. document.getElementsByTagName('head')[0].appendChild(temp); // Add script to page
Add Comment
Please, Sign In to add comment