Markdown toolbar for reddit.com

Creates a Markdown toolbar whenever you make/edit text posts or comments in reddit.com

  1. // ==UserScript==
  2. // @name Markdown toolbar for reddit.com
  3. // @namespace darkred
  4. // @version 1.4.1
  5. // @description Creates a Markdown toolbar whenever you make/edit text posts or comments in reddit.com
  6. // @author wOxxOm, darkred
  7. // @license MIT
  8. // @include https://www.reddit.com/*submit*
  9. // @include https://old.reddit.com/*submit*
  10. // @include https://www.reddit.com/*comments*
  11. // @include https://old.reddit.com/*comments*
  12. // @grant GM_addStyle
  13. // @icon https://raw.githubusercontent.com/dcurtis/markdown-mark/master/png/66x40-solid.png
  14. //
  15. //
  16. // This is a modified version of the script "Markdown toolbar for GreasyFork and UserStyles.org" ()https://greatest.deepsurf.us/en/scripts/6779-markdown-toolbar-for-greasyfork-and-userstyles-org)
  17. // Thanks a lot to wOxxOm for making that script.
  18. //
  19. // @supportURL https://github.com/darkred/Userscripts/issues
  20. // ==/UserScript==
  21.  
  22.  
  23. var x;
  24.  
  25. // IF IT'S A SUBMIT PAGE
  26. if (window.location.href.indexOf('submit') > - 1) {
  27. // THEN ADD TOOLBAR TO THE 'NEW POST' TEXTBOX
  28. x = document.querySelectorAll('div.md > textarea:nth-child(1)')[0].parentNode;
  29. addFeatures(x);
  30. }
  31. else {
  32. var textareas = document.querySelectorAll('textarea');
  33.  
  34. // ADD TOOLBAR: TO EDITING YOUR POST, TO 'NEW COMMENT' FORM AND TO EDITING YOUR EXISTING COMMENT(S)
  35. for (var i = 0; i < textareas.length; i++) {
  36. x = document.querySelectorAll('textarea') [i].parentNode;
  37. addFeatures(x);
  38. }
  39. }
  40.  
  41.  
  42.  
  43.  
  44.  
  45. function addFeatures(n) {
  46.  
  47. n.parentNode.textAreaNode = x.firstChild;
  48.  
  49. GM_addStyle('\
  50. .Button {\
  51. display: inline-block;\
  52. cursor: pointer;\
  53. margin: 0px;\
  54. font-size: 12px;\
  55. line-height: 1;\
  56. font-weight: bold;\
  57. padding: 4px 6px;\
  58. background: -moz-linear-gradient(center bottom , #CCC 0%, #FAFAFA 100%) repeat scroll 0% 0% #F8F8F8;\
  59. border: 1px solid #999;\
  60. border-radius: 2px;\
  61. white-space: nowrap;\
  62. text-shadow: 0px 1px 0px #FFF;\
  63. box-shadow: 0px 1px 0px #FFF inset, 0px -1px 2px #BBB inset;\
  64. color: #333;}');
  65.  
  66.  
  67. // add buttons
  68. btnMake(n, '<b>B</b>', 'Bold', '**');
  69. btnMake(n, '<i>I</i>', 'Italic', '*');
  70. // btnMake(n, '<u>U</u>', 'Underline', '<u>','</u>');
  71. // btnMake(n, '<s>S</s>', 'Strikethrough', '<s>','</s>');
  72. btnMake(n, '<s>S</s>', 'Strikethrough', '~~');
  73. btnMake(n, '^', 'Superscript', '^','', true);
  74. btnMake(n, '\\n', 'Line break', '&nbsp;\n', '', true);
  75. btnMake(n, '---', 'Horizontal line', '\n\n---\n\n', '', true);
  76. btnMake(n, 'URL', 'Add URL to selected text',
  77. function(e) {
  78. try {edWrapInTag('[', ']('+prompt('URL'+':')+')', edInit(e.target));}
  79. catch(e) {}
  80. });
  81. // btnMake(n, 'Image', 'Convert selected https://url to inline image', '!['+'image'+'](', ')');
  82. btnMake(n, 'Table', 'Insert table template', '\n| head1 | head2 |\n|-------|-------|\n| cell1 | cell2 |\n| cell3 | cell4 |\n', '', true);
  83. btnMake(n, 'Code', 'Apply CODE markdown to selected text',
  84. function(e){
  85. var ed = edInit(e.target);
  86. if (ed.sel.indexOf('\n') < 0)
  87. edWrapInTag('`', '`', ed);
  88. else
  89. edWrapInTag(((ed.sel1==0) || (ed.text.charAt(ed.sel1-1) == '\n') ? '' : '\n') + '```' + (ed.sel.charAt(0) == '\n' ? '' : '\n'),
  90. (ed.sel.substr(-1) == '\n' ? '' : '\n') + '```' + (ed.text.substr(ed.sel2,1) == '\n' ? '' : '\n'),
  91. ed);
  92. });
  93. }
  94.  
  95. function btnMake(afterNode, label, title, tag1, tag2, noWrap) {
  96. var a = document.createElement('a');
  97. a.className = 'Button';
  98. a.innerHTML = label;
  99. a.title = title;
  100. a.style.setProperty('float','right');
  101.  
  102. a.addEventListener('click',
  103. typeof(tag1) === 'function'
  104. ? tag1
  105. : noWrap ? function(e){edInsertText(tag1, edInit(e.target));}
  106. : function(e){edWrapInTag(tag1, tag2, edInit(e.target));});
  107.  
  108. var nparent = afterNode.parentNode;
  109. a.textAreaNode = nparent.textAreaNode;
  110. nparent.insertBefore(a, nparent.firstElementChild);
  111. }
  112.  
  113.  
  114.  
  115. function edInit(btn) {
  116.  
  117. var ed = {node: btn.parentNode.textAreaNode } ;
  118.  
  119. ed.sel1 = ed.node.selectionStart;
  120. ed.sel2 = ed.node.selectionEnd,
  121. ed.text = ed.node.value;
  122. ed.sel = ed.text.substring(ed.sel1, ed.sel2);
  123. return ed;
  124. }
  125.  
  126.  
  127.  
  128.  
  129. function edWrapInTag(tag1, tag2, ed) {
  130. ed.node.value = ed.text.substr(0, ed.sel1) + tag1 + ed.sel + (tag2?tag2:tag1) + ed.text.substr(ed.sel2);
  131. ed.node.setSelectionRange(ed.sel1 + tag1.length, ed.sel1 + tag1.length + ed.sel.length);
  132. ed.node.focus();
  133. }
  134.  
  135. function edInsertText(text, ed) {
  136. ed.node.value = ed.text.substr(0, ed.sel2) + text + ed.text.substr(ed.sel2);
  137. ed.node.setSelectionRange(ed.sel2 + text.length, ed.sel2 + text.length);
  138. ed.node.focus();
  139. }