Fiddle-ify!

Converts code blocks on Stack Overflow into JSFiddles with a few clicks

  1. // ==UserScript==
  2. // @name Fiddle-ify!
  3. // @author Cameron Bernhardt (AstroCB)
  4. // @version 0.1.0
  5. // @namespace http://github.com/AstroCB
  6. // @description Converts code blocks on Stack Overflow into JSFiddles with a few clicks
  7. // @include http://stackoverflow.com/*
  8. // ==/UserScript==
  9. var tags = document.getElementsByClassName("post-taglist")[0].children;
  10. var tagged = false,
  11. jQuery = false;
  12. var index = 0;
  13. var html, css, javascript; //store contents of selected code blocks
  14. var blocks = document.getElementsByClassName("default prettyprint prettyprinted"); //get code blocks
  15. for (var i = 0; i < tags.length; i++) {
  16. var tagName = tags[i].innerHTML;
  17. if (tagName === "html" || tagName === "css" || tagName === "javascript") { //check if tagged HTML, CSS, or JavaScript
  18. tagged = true;
  19. }
  20.  
  21. if (tagName === "jQuery") {
  22. jQuery = true;
  23. }
  24. }
  25.  
  26. if (tagged && blocks) { //only display button if tagged HTML, CSS, or JavaScript and has code blocks
  27. //(TODO: add jQuery support (toggle menu in Fiddle))
  28. var question = document.getElementsByClassName("vt")[0];
  29. question.innerHTML += "<br/><button id='fiddleify'>Fiddle-ify!</button>"; //inject "Fiddle-ify" button
  30. document.getElementById("fiddleify").addEventListener("click", function () { //listen for "enter" keypresses for skipping
  31. alert("Click a code block for HTML or press enter to skip.");
  32. document.addEventListener("keyup", function (e) {
  33. if (e.which === 37) {
  34. e.preventDefault();
  35. assign(null, index);
  36. index++;
  37. }
  38. });
  39.  
  40. for (var j = 0; j < blocks.length; j++) {
  41. blocks[j].addEventListener("click", function () { //listen for clicks on code blocks
  42. if (index === 0) {
  43. this.style.backgroundColor = "orange";
  44. } else if (index == 1) {
  45. this.style.backgroundColor = "blue";
  46. } else if (index == 2) {
  47. this.style.backgroundColor = "yellow";
  48. }
  49. assign(this.children[0].children, index);
  50. index++;
  51. });
  52. }
  53. });
  54. }
  55.  
  56. function assign(element, num) {
  57. //TODO: add visual cue that code block has been selected
  58. switch (num) { //instructions for each click: HTML -> CSS -> JavaScript (runs for both "enter" keypresses and block clicks)
  59. case 0:
  60. html = element;
  61. alert("Click a code block for CSS or press enter to skip.");
  62. break;
  63. case 1:
  64. css = element;
  65. alert("Click a code block for JavaScript or press enter to skip.");
  66. break;
  67. case 2:
  68. javascript = element;
  69. run();
  70. break;
  71. default:
  72. console.log("Finished");
  73. }
  74. }
  75.  
  76. function run() { //unwrap text from code blocks (each word is in its own span)
  77. confirm("Loading JSFiddle...");
  78. var htmlText = "",
  79. cssText = "",
  80. jsText = "";
  81. for (var x = 0; x < html.length; x++) {
  82. htmlText += html[x].innerHTML;
  83. }
  84.  
  85. for (var y = 0; y < css.length; y++) {
  86. cssText += css[y].innerHTML;
  87. }
  88.  
  89. for (var z = 0; z < javascript.length; z++) {
  90. jsText += javascript[z].innerHTML;
  91. }
  92.  
  93. var url = "//jsfiddle.net/api/post/";
  94.  
  95. if (jQuery) { //determine whether to use jQuery
  96. url += "jquery/2.1.0";
  97. } else {
  98. url += "library/pure";
  99. }
  100.  
  101. var data = {
  102. "html": html,
  103. "css": css,
  104. "js": javascript,
  105. }
  106.  
  107. function load() {
  108. console.log(post);
  109. }
  110.  
  111. var post = new GM_xmlhttpRequest({
  112. data: data,
  113. method: "POST",
  114. url: url,
  115. onload: function () {
  116. console.log(post);
  117. }
  118. }); //create POST request for Fiddle
  119. }