Greasy Fork is available in English.

Stack Snippets Console

Add a console to "Stack Snippets" executable code on StackExchange

2014-10-05 يوللانغان نەشرى. ئەڭ يېڭى نەشرىنى كۆرۈش.

  1. // ==UserScript==
  2. // @name Stack Snippets Console
  3. // @namespace http://stackexchange.com/users/3846032/scimonster
  4. // @version 1.0.0
  5. // @description Add a console to "Stack Snippets" executable code on StackExchange
  6. // @include http://*.stackexchange.com/*
  7. // @include http://stackoverflow.com/*
  8. // @include http://*.stackoverflow.com/*
  9. // @include http://stacksnippets.net/*
  10. // @copyright 2014+, Scimonster
  11. // ==/UserScript==
  12.  
  13. if (location.hostname == 'stacksnippets.net') {
  14. (function(){
  15.  
  16. // define some functions
  17.  
  18. function isSEDomainName(dname) {
  19. return !!~["stackoverflow.com", "stackexchange.com"].indexOf(dname.split('.').slice(-2).join('.'));
  20. }
  21.  
  22. function URLparser(href) {
  23. var p = document.createElement('a');
  24. p.href = href;
  25. return p;
  26. }
  27.  
  28. // listen for the ping
  29.  
  30. this.addEventListener('message', function(ev){
  31. if (isSEDomainName(URLparser(ev.origin).hostname) && ev.data == 'console ping') {
  32. // passes the test
  33. listen(ev);
  34. }
  35. }, false);
  36.  
  37. // listen for console.log()s
  38.  
  39. function listen(ev) {
  40.  
  41. var oldLog = console.log;
  42.  
  43. function log(firstArg) {
  44. var args = [].slice.call(arguments);
  45.  
  46. oldLog.apply(console, args); // use the default console.log()
  47.  
  48. if (typeof firstArg == 'string') { // might require replacing
  49. if (~firstArg.indexOf('%s') || ~firstArg.indexOf('%d') || ~firstArg.indexOf('%i') || ~firstArg.indexOf('%f')) {
  50. // there is something to be replaced
  51. args.shift();
  52. firstArg = firstArg.replace(/%[sdif]/g, function(match){
  53. switch (match) {
  54. case '%s': return args.shift().toString();
  55. case '%d': case '%i': return parseInt(args.shift());
  56. case '%f': return parseFloat(args.shift());
  57. default: return match;
  58. }
  59. });
  60. args.unshift(firstArg);
  61. }
  62. }
  63. // replacements done, ready for concat
  64. var text = args.map(function(a){
  65. if (typeof a == 'object') {
  66. try {
  67. return JSON.strigify(a);
  68. } catch(e) {
  69. return "{bad object}";
  70. }
  71. }
  72. return a.toString();
  73. });
  74.  
  75. postMessage('log', firstArg, text.join(''));
  76. }
  77.  
  78. this.console.log = log;
  79.  
  80. function postMessage(type, message) {
  81. ev.source.postMessage({
  82. type: 'log',
  83. message: message,
  84. time: new Date,
  85. snippet: this.name // the iframe
  86. }, ev.origin);
  87. }
  88.  
  89. }
  90.  
  91. })();
  92. } else {
  93. (function(){
  94. $(document).on('click', 'div.snippet-result input[type=button]', function(){
  95. var container = $(this).parent().parent();
  96. container.children('.snippet-console').remove();
  97. if (!this.className) { // the run button
  98. $('<div class="snippet-console"><h6>Snippet Console <small>v1.0.0</small></h6><ul></ul></div>').appendTo(container).css({
  99. position: 'relative',
  100. width: '100%',
  101. maxHeight: 200,
  102. borderTopWidth: 1,
  103. borderTopStyle: 'solid',
  104. borderTopColor: 'rgb(170, 170, 170)',
  105. overflow: 'auto'
  106. }).children('ul').css({
  107. listStyleType: 'none'
  108. });
  109.  
  110. var snippet = container.find('iframe')[0];
  111.  
  112. snippet.onload = function(){
  113. setTimeout(function(){
  114. snippet.contentWindow.postMessage('console ping', "*");
  115. // need to accept all because the iframe has no URL
  116. }, 100);
  117. };
  118. }
  119. });
  120.  
  121. window.addEventListener('message', function(ev){
  122. if (ev.origin == 'null' && ev.data.snippet) { // seems to be a snippet
  123. var time = ev.data.time.getHours()+':'+ev.data.time.getMinutes()+':'+ev.data.time.getSeconds()+'.'+ev.data.time.getMilliseconds();
  124. var li = $('<li data-type="'+ev.data.type+'"><span style="color:gray">'+time+':</span> <span></span></li>');
  125. li.find('span').last().text(ev.data.message);
  126. var snCons = $('iframe[name="'+ev.data.snippet+'"]').parent().parent().children('.snippet-console');
  127. snCons.children('ul').append(li);
  128. snCons.scrollTop(snCons.children('ul').height()); // scroll to bottom
  129. }
  130. }, false);
  131. })();
  132. }