Mods.de Button Overhaul

Mods.de - prettify new post button

  1. // ==UserScript==
  2. // @name Mods.de Button Overhaul
  3. // @namespace phil.red
  4. // @description Mods.de - prettify new post button
  5. // @description:de Mods.de - New-Post-Buttons verschönern
  6. // @version 1.3.2
  7. // @include https://forum.mods.de/bb/newreply.php*
  8. // @include https://forum.mods.de/bb/editreply.php*
  9. // @include https://forum.mods.de/bb/newthread.php*
  10. // @include https://forum.mods.de/bb/thread.php?*
  11. // ==/UserScript==
  12.  
  13. function addStyle(css) {
  14. const head = document.getElementsByTagName('head')[0]
  15. if (!head) return
  16. const style = document.createElement('style')
  17. style.setAttribute('type', 'text/css')
  18. style.textContent = css
  19. head.appendChild(style)
  20. }
  21.  
  22. //when used on a text input widget, this inserts bb tags around the selection
  23. //use what you would use in the start tag.
  24. //example:
  25. //given a textarea with the id 'ta' and the selected content <selection>,
  26. //insertRoundCaret(elem, 'url=http://goo.gl') yields [url="http://goo.gl"]<selection>[/url] and
  27. //insertRoundCaret(elem, 'url=http://','Insert URL:') yields [url=<url>]<selection>[/url],
  28. //where <url> is fetched via a popup which is prefilled with 'http://'
  29.  
  30. function insertRoundCaret(elem, tag, question) {
  31. const i = tag.indexOf('=')
  32. const tagName = (i === -1) ? tag : tag.substring(0, i)
  33. let tagValue = (i === -1) ? '' : tag.substring(i + 1)
  34. //if there is a question, prompt it, using the value as preset, else use the value if present
  35. let strStart = `[${tagName}`
  36. const strEnd = `[/${tagName}]`
  37.  
  38. if (tagValue.length > 0 || question) {
  39. if (question) {
  40. tagValue = window.prompt(`Bitte ${question}`, tagValue) //Autopoliteness (TM)
  41. }
  42. if (tagValue.length > 0) {
  43. strStart += '="' + tagValue + '"'
  44. }
  45. }
  46. strStart += ']'
  47.  
  48. insertCustomCaret(elem, strStart, strEnd)
  49. }
  50.  
  51. function insertCustomCaret(elem, strStart, strEnd) {
  52. //if there is a selection, wrap tags around it
  53. if (elem.selectionStart || elem.selectionStart === 0) {
  54. const startPos = elem.selectionStart
  55. const endPos = elem.selectionEnd
  56. const scrollTop = elem.scrollTop
  57. elem.value = elem.value.substring(0, startPos) + strStart + elem.value.substring(startPos, endPos) + strEnd + elem.value.substring(endPos)
  58. elem.focus()
  59. elem.selectionStart = startPos + strStart.length
  60. elem.selectionEnd = endPos + strStart.length
  61. elem.scrollTop = scrollTop
  62. } else { // if no selection is present, just append tags to the end
  63. elem.value += strStart + strEnd
  64. elem.focus()
  65. elem.selectionStart = elem.selectionEnd = elem.value.length - strEnd.length
  66. }
  67. }
  68.  
  69. function insertPerLine(elem, str) {
  70. if (elem.selectionStart || elem.selectionStart === 0) {
  71. const startPos = elem.selectionStart
  72. const endPos = elem.selectionEnd
  73. const scrollTop = elem.scrollTop
  74. const lines = elem.value.substring(startPos, endPos).split('\n').map(l => str + l)
  75. elem.value = elem.value.substring(0, startPos) + lines.join('\n') + elem.value.substring(endPos)
  76. elem.focus()
  77. elem.selectionStart = startPos + str.length
  78. elem.selectionEnd = endPos + (str.length * lines.length)
  79. elem.scrollTop = scrollTop
  80. } else {
  81. elem.value += str
  82. elem.focus()
  83. elem.selectionStart = elem.selectionEnd = elem.value.length
  84. }
  85. }
  86.  
  87. function smileyWindow() {
  88. window.open(
  89. 'misc.php?view=smilies&amp;window=1',
  90. 'smilieWindow',
  91. 'width=300, height=400, status=no, toolbar=no, menubar=no, location=no, directories=no, resizeable=no, scrollbars=yes')
  92. }
  93.  
  94. addStyle(`
  95. #qr_insertcustombuttonshere > img,
  96. .newInsertButton {
  97. float: left;
  98. max-width: 28px;
  99. }
  100.  
  101. #qr_insertcustombuttonshere > img,
  102. .newInsertButton,
  103. input[type="submit"] {
  104. border: 1px solid #224;
  105. background-color: #394e63;
  106. box-shadow: 0px 1px 3px rgba(255,255,255,.3) inset;
  107. height: 24px;
  108. overflow: show;
  109. text-align: center;
  110. color: white;
  111. margin-right: 3px;
  112. }
  113.  
  114. #qr_insertcustombuttonshere > img:hover:not(:active),
  115. .newInsertButton:hover:not(:active),
  116. input[type="submit"]:hover:not(:active) {
  117. border-color: #008fe1;
  118. box-shadow: 0px 1px 3px rgba(255,255,255,.3) inset,
  119. 0px 0px 2px #008fe1;
  120. }
  121.  
  122. #qr_insertcustombuttonshere > img:hover:active,
  123. .newInsertButton:hover:active,
  124. input[type="submit"]:hover:active {
  125. box-shadow: 0px 1px 3px rgba(0,0,0,.3) inset;
  126. }
  127.  
  128. .newInsertButton .border {border:1px solid silver; display:inline-block; width:1.2em}
  129. .newInsertButton .spoiler {text-shadow:0px 0px 2px rgba(255,255,255,.5)}
  130. .newInsertButton .brdr,
  131. .newInsertButton .spoiler {min-width:16px; display:inline-block}
  132. .newInsertButton .tex {font-family:serif}
  133. `)
  134.  
  135. //shamelessly stolen from kambfhase
  136. if (!document.evaluate('//a[contains(@href, "./quickmod")]', document, null, 8, null).singleNodeValue) {
  137. addStyle('.iAmMod { display:none }')
  138. }
  139.  
  140. const toolbar = document.querySelector('img[title="Fett"]').parentNode
  141. const ta = document.querySelector('#pstmsg, textarea[name="message"], #thrmsg')
  142. const buttons = [
  143. ['Fett', '<b>F</b>', () => insertRoundCaret(ta, 'b')],
  144. ['Unterstreichen', '<u>U</u>', () => insertRoundCaret(ta, 'u')],
  145. ['Code', '<code class="border">C</code>', () => insertRoundCaret(ta, 'code')],
  146. ['Kursiv', '<i>K</i>', () => insertRoundCaret(ta, 'i')],
  147. ['Durchstreichen', '<s>S</s>', () => insertRoundCaret(ta, 's')],
  148. ['Trigger', '<span class="trigger">T</span>', () => insertRoundCaret(ta, 'trigger')],
  149. ['Monospace', '<code>M</code>', () => insertRoundCaret(ta, 'm')],
  150. ['TeX', '<span class="tex">T</span>', () => insertRoundCaret(ta, 'tex')],
  151. ['Audio', '♫', () => insertRoundCaret(ta, 'audio')],
  152. ['Video', '▶', () => insertRoundCaret(ta, 'video')],
  153. ['PHP', '<code class="border">P</code>', () => insertRoundCaret(ta, 'php')],
  154. ['Bild einfügen', '⌧', () => insertRoundCaret(ta, 'img')],
  155. ['Link', '<u>url</u>', () => insertRoundCaret(ta, 'url=http://', 'URL angeben')],
  156. ['Liste', '☰', () => {
  157. insertRoundCaret(ta, 'list=1', 'Listentyp angeben: 1, a oder leer')
  158. insertCustomCaret(ta, '\n', '\n')
  159. insertPerLine(ta, '[*] ')
  160. }],
  161. ['Listenelement', '•', () => insertCustomCaret(ta, '[*] ','')],
  162. ['Smiley einfügen', '☺', smileyWindow],
  163. ['Quote', '<span class="border">Q</i>', () => insertRoundCaret(ta, 'quote')],
  164. ['Spoiler', '<span class="spoiler">S</i>', () => insertRoundCaret(ta, 'spoiler')],
  165. ['Mod', 'Mod', () => insertRoundCaret(ta, 'mod')],
  166. ]
  167.  
  168. toolbar.innerHTML = ''
  169. for (const [alt, code, cb] of buttons) {
  170. const button = document.createElement('button')
  171. button.classList.add('newInsertButton')
  172. button.setAttribute('type', 'button')
  173. button.setAttribute('alt', alt)
  174. button.innerHTML = code
  175. button.addEventListener('click', cb)
  176. toolbar.appendChild(button)
  177. }
  178.  
  179. const modBtn = document.querySelector('button[alt="Mod"]')
  180. if (modBtn) modBtn.classList.add('iAmMod')