Greasyfork forum MARKDOWN for comments

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

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

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