Greasyfork forum MARKDOWN for comments

Select MARKDOWN format by default for new comments, add help links, add toolbar markdown formatting buttons

当前为 2014-12-05 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name Greasyfork forum MARKDOWN for comments
  3. // @author wOxxOm
  4. // @description Select MARKDOWN format by default for new comments, add help links, add toolbar markdown formatting buttons
  5. // @namespace wOxxOm.scripts
  6. // @version 1.11
  7. // @include https://greasyfork.org/*forum/discussion/*
  8. // @include https://greasyfork.org/*forum/post/discussion*
  9. // @run-at document-start
  10. // @grant none
  11. // ==/UserScript==
  12.  
  13. var ob = new MutationObserver(function(mutations){
  14. for (var i=0, ml=mutations.length, m; (i<ml) && (m=mutations[i]); i++)
  15. for (var j=0, nodes=m.addedNodes, nl=nodes.length, n; (j<nl) && (n=nodes[j]); j++)
  16. if (n.nodeType == 1) {
  17. if (n.localName == 'label') {
  18. if (n.for != 'Form_Format2')
  19. continue;
  20. }
  21. else if (!(n = n.querySelector('label[for="Form_Format2"]')))
  22. continue;
  23.  
  24. if (n.parentNode.parentNode.querySelector('.Form_PostComment'))
  25. n.click();
  26.  
  27. addFeatures(n);
  28. return;
  29. }
  30. });
  31. ob.observe(document, {subtree:true, childList:true});
  32.  
  33. function addFeatures(n) {
  34. // add formatting help tooltips
  35. n.previousElementSibling.insertAdjacentHTML('beforeend',
  36. ' (<a href="/help/allowed-markup" target="_blank" title="'+
  37. '* (name, title), a (href), abbr, b, blockquote (cite), br, center, cite, code, dd, del, dfn, div, dl, dt, em, '+
  38. 'h1, h2, h3, h4, h5, h6, hr, i, ins, img (alt, height, src (https), width), kbd, li, mark, ol, p, pre, q (cite), '+
  39. 'rp, rt, ruby, s, samp, small, span, strike, strong, tt, table, tbody, tfoot, thead, td, th, tr, sub, sup, '+
  40. 'time (datetime, pubdate), u, ul, var">?</a>)');
  41. n.insertAdjacentHTML('beforeend',
  42. ' (<a href="http://www.darkcoding.net/software/markdown-quick-reference/" target="_blank">?</a>)');
  43.  
  44. // add buttons
  45. n.parentNode.textAreaNode = n.parentNode.querySelector('textarea');
  46. btnMake(n, '<b>B</b>', 'Bold', '**');
  47. btnMake(n, '<i>I</i>', 'Italic', '*');
  48. btnMake(n, '<u>U</u>', 'Underline', '<u>','</u>');
  49. btnMake(n, '<s>S</s>', 'Strikethrough', '<s>','</s>');
  50. btnMake(n, '---', 'Horizontal line', '\n\n---\n\n', '', true);
  51. btnMake(n, 'URL', 'Add URL to selected text',
  52. function(e) {
  53. try {edWrapInTag('[', ']('+prompt("URL:")+')', edInit(e.target))}
  54. catch(e) {};
  55. });
  56. btnMake(n, 'Image (https)', 'Convert selected https://url to inline image', '![image](', ')');
  57. btnMake(n, 'Table', 'Insert table template', '\n| head1 | head2 |\n|-------|-------|\n| cell1 | cell2 |\n| cell3 | cell4 |\n', '', true);
  58. btnMake(n, 'Code', 'Apply CODE markdown to selected text',
  59. function(e){
  60. var ed = edInit(e.target);
  61. if (ed.sel.indexOf('\n') < 0)
  62. edWrapInTag('`', '`', ed);
  63. else
  64. edWrapInTag(((ed.sel1==0) || (ed.text.charAt(ed.sel1-1) == '\n') ? '' : '\n') + '```' + (ed.sel.charAt(0) == '\n' ? '' : '\n'),
  65. (ed.sel.substr(-1) == '\n' ? '' : '\n') + '```' + (ed.text.substr(ed.sel2,1) == '\n' ? '' : '\n'),
  66. ed);
  67. });
  68. }
  69.  
  70. function btnMake(afterNode, label, title, tag1_or_cb, tag2, noWrap) {
  71. var a = document.createElement('a');
  72. a.className = 'Button';
  73. a.style.setProperty('float','right');
  74. a.innerHTML = label;
  75. a.title = title;
  76. a.addEventListener('click',
  77. typeof(tag1_or_cb) == 'function'
  78. ? tag1_or_cb
  79. : noWrap ? function(e){edInsertText(tag1_or_cb, edInit(e.target))}
  80. : function(e){edWrapInTag(tag1_or_cb, tag2, edInit(e.target))});
  81. a.textAreaNode = afterNode.parentNode.textAreaNode;
  82. afterNode.parentNode.insertBefore(a, afterNode.nextElementSibling);
  83. }
  84.  
  85. function edInit(btn) {
  86. var ed = {node: btn.textAreaNode || btn.parentNode.textAreaNode}
  87. ed.sel1 = ed.node.selectionStart;
  88. ed.sel2 = ed.node.selectionEnd,
  89. ed.text = ed.node.value;
  90. ed.sel = ed.text.substring(ed.sel1, ed.sel2);
  91. return ed;
  92. }
  93.  
  94. function edWrapInTag(tag1, tag2, ed) {
  95. ed.node.value = ed.text.substr(0, ed.sel1) + tag1 + ed.sel + (tag2?tag2:tag1) + ed.text.substr(ed.sel2);
  96. ed.node.setSelectionRange(ed.sel1 + tag1.length, ed.sel1 + tag1.length + ed.sel.length);
  97. ed.node.focus();
  98. }
  99.  
  100. function edInsertText(text, ed) {
  101. ed.node.value = ed.text.substr(0, ed.sel2) + text + ed.text.substr(ed.sel2);
  102. ed.node.setSelectionRange(ed.sel2 + text.length, ed.sel2 + text.length);
  103. ed.node.focus();
  104. }