Sleazy Fork is available in English.

E-Hentai Grep

Searches forum posts for lines that match given string patterns

Fra og med 09.07.2015. Se den nyeste version.

  1. // ==UserScript==
  2. // @name E-Hentai Grep
  3. // @description Searches forum posts for lines that match given string patterns
  4. // @include http://forums.e-hentai.org/index.php?*showtopic=*
  5. // @version 0.0.1.20150709081006
  6. // @namespace https://greasyfork.org/users/2233
  7. // ==/UserScript==
  8.  
  9. /*** Settings ***/
  10.  
  11. var default_on = true
  12. var hotkey = 71 // http://www.cambiaresearch.com/articles/15/javascript-char-codes-key-codes
  13. var max_length = 60
  14. var display_title_and_poster = false
  15. var remove_stockout_line = true
  16. var remove_strike_through_line = true
  17. var remove_quoted_text = true
  18. if(typeof result_box_position == 'undefined') {
  19. var result_box_position = 'center' // where to show the result box ("left", "center" or "right")
  20. }
  21. var blacklist = [
  22. '22234', // Ask the Experts
  23. '163637', // The Shared Free Shop
  24. '169987',
  25. '170830',
  26. ]
  27. if(typeof grep_patterns == 'undefined') {
  28. var grep_patterns = [ // Add [[pattern_1, pattern_2, ... , pattern_n], 'color'] to the array by yourself.
  29. [ // Items
  30. [
  31. // Rare materials
  32. /phazon/i,
  33. // Bindings for staff
  34. /binding.*(slaughter|destruction|focus|friendship|heimdall|fenrir|heaven-sent|demon-fiend|curse-weaver|earth-walker|fox|owl)/i,
  35. /^\s*(slaughter|destruction|focus|friendship|heimdall|fenrir|heaven-sent|demon-fiend|curse-weaver|earth-walker|fox|owl)/i,
  36. // Bindings for armor
  37. /binding.*(balance|focus|protection|warding|fleet|negation|heimdall|dampening|cheetah|fox|owl|heaven-sent)/i,
  38. /^\s*(balance|focus|protection|warding|fleet|negation|heimdall|dampening|cheetah|fox|owl|heaven-sent)/i,
  39. // Graded materials
  40. /(low|mid|high).*grade.*(cloth|wood)/i,
  41. /(lg|mg|hg).?(cloth|wood)/i,
  42. /scrap.*(cloth|wood).*@/i,
  43. /scrap.*(cloth|wood).*\d *\bc\b/i,
  44. // ED
  45. /(energy|drink).*[@0]/i,
  46. /(energy|drink).*\d *k\b/i,
  47. // Shards
  48. /amnesia/i,
  49. // Potions
  50. /health.*elixir/i,
  51. /(mana|spirit).*(potion|elixir)/i,
  52. // Artifact
  53. /artifact/i,
  54. //// Trophy
  55. ///\b(troph|manbearpig|antioch|mithra|dalek|lock|costume|hinamatsuri|broken|sapling|shirt|unicorn|noodl)/i,
  56. ], 'purple'
  57. ],
  58. [ // Holy Gear
  59. [
  60. /(Peer|Leg|Mag).*(Hallowed|Astral).*Katalox.*Staff.*of.*Destruction/i,
  61. /(Peer|Leg|Mag).*(Hallowed|Astral).*Oak.*Staff.*of.*Heimdall/i,
  62. /(Peer|Leg|Mag).*Phase.*Heimdall/i,
  63. /Ex.*Radiant.*Heimdall/i,
  64. /(Peer|Leg).*(Charged|Frugal).*(Cotton|Gossamer).*(Heaven-sent|Protection)/i,
  65. ], 'darkred'
  66. ],
  67. [ // Toys
  68. [
  69. /\bPeerless\b/i,
  70. /(Peer|Leg).*Radiant/i,
  71. ], 'darkgreen'
  72. ],
  73. ]
  74. }
  75.  
  76. /*** End of Settings ***/
  77.  
  78. var wnd = window
  79. var doc = wnd.document
  80. var loc = location
  81. var href = loc.href
  82.  
  83. if(!/&?\bst=[^0]/.test(href)) {
  84. for(var i=0; i<blacklist.length; i++) { if(new RegExp('showtopic=' + blacklist[i] + '\\b').test(href)) { default_on = false } }
  85.  
  86. var $ = function(e, css) { if(!css) { css=e; e=doc }; return e.querySelector(css) }
  87. var $$ = function(e, css) { if(!css) { css=e; e=doc }; return e.querySelectorAll(css) }
  88.  
  89. var stockout = function(line) {
  90. if(!remove_stockout_line) { return false }
  91. var stockout_patterns = [
  92. /[\|\(\[【(:x@]\s*[-0x×\/]+(\D|$)/i,
  93. // /(^|\D)[-0x×\/]+\s*[@×x:)】\]\)\|]/i,
  94. /(^|\D)[-0×\/]+\s*[@×:)】\]\)\|]/i,
  95. /\b0+\s*[x×]/i,
  96. /\(\/?\)/i,
  97. /\[\/?\]/i,
  98. /【\/?】/i,
  99. /(\/?)/i,
  100. /\bnot\s+available\b/i,
  101. /\bunavailable\b/i,
  102. /\bnone\b/i,
  103. /\[restocking\]/i,
  104. /\s+0\s*$/i,
  105. /out of stock/i,
  106. ]
  107. for(var i=0, len=stockout_patterns.length; i<len; i++) {
  108. if(stockout_patterns[i].test(line)) { return true }
  109. }
  110. return false
  111. }
  112.  
  113. var get_text = function(e) {
  114. var s = e.innerHTML
  115. if(remove_quoted_text){
  116. s = s.replace(/<div class=.quotemain.>.+?<!--QuoteEnd--><\/div><!--QuoteEEnd-->/gi, '')
  117. }
  118. if(remove_strike_through_line) { s = s.replace(/<strike>.*?<\/strike>/g, '') }
  119. s = s.replace(/<br\s*[^>]*>/g, '\n').replace(/<\/li>/g, '\n').replace(/<ul>/g, '\n').replace(/<\/blockquote>/g, '\n')
  120. s = s.replace(/<[^>]+>/g, '').replace(/\[(\w+)[^\]]*](.*?)\[\/\1]/g, '')
  121. s = s.replace(/&nbsp;/g, ' ').replace(/&amp;/g, '&')
  122. s = s.replace(/[ \t]+/g, ' ')
  123. return s
  124. }
  125. var out = ''
  126.  
  127. if(result_box_position == 'left') {
  128. var first_post = $('.post2')
  129. var posts = $$('.borderwrap')
  130. for(var i=0, len=posts.length; i<len; i++) {
  131. var poster = $(posts[i], '.bigusername')
  132. if((!poster) || (poster.textContent != $('.bigusername').textContent)) { continue } // skip threads that are not posted by the shop owner
  133.  
  134. var lines = get_text($(posts[i], '.postcolor')).split('\n')
  135. //console.log(lines)
  136. var out = ''
  137. for(var j=0, len2=lines.length; j<len2; j++) {
  138. var line = lines[j].substring(0, max_length)
  139. if(stockout(line)) { continue }
  140. for(var k=0, len3=grep_patterns.length; k<len3; k++) {
  141. for(var m=0, len4=grep_patterns[k][0].length; m<len4; m++) {
  142. if(grep_patterns[k][0][m].test(line)) { out = out + line + '\n'; break }
  143. }
  144. }
  145. }
  146. if(out) {
  147. if(display_title_and_poster && (/#1/.test($(posts[i], '.postdetails').textContent))) {
  148. var shop_title = $$('.maintitle>table>tbody>tr>td>div')[0].textContent
  149. out = '[Title]\t' + shop_title.substring(0, max_length) + '\n' + '[Poster] ' + poster.textContent.substring(0, max_length)+ '\n\n' + out
  150. }
  151. var d = doc.createElement('DIV')
  152. d.className = 'result'
  153. d.style.cssText = 'background:rgba(237,235,223,1); color:#5C0D11'
  154. //d.appendChild($(posts[i], '.postdetails').cloneNode(true))
  155. var anchor = doc.createElement('A')
  156. anchor.text = $(posts[i], '.postdetails').textContent
  157. anchor.href = href.replace(loc.hash, '') + '#' + $(posts[i], '*[id^="post-main-"]').id
  158. d.appendChild(anchor)
  159. var pre = doc.createElement('PRE')
  160. pre.appendChild(doc.createTextNode(out))
  161. d.appendChild(pre)
  162. first_post.parentNode.insertBefore(d, first_post)
  163. }
  164. }
  165.  
  166. var toggle_results = function() {
  167. var divs = $$(first_post.parentNode, '.result')
  168. for(var i=divs.length-1; i>=0; i--) {
  169. if(divs[i].style.display != 'none') { divs[i].style.display = 'none' } else { divs[i].style.display = '' }
  170. }
  171. }
  172. addEventListener('keydown', function(evt) { if((evt.target.tagName!='INPUT') && (evt.target.tagName!='TEXTAREA') && (evt.keyCode == hotkey)) { toggle_results() } }, false)
  173. if(!default_on) { toggle_results() }
  174. }
  175. else {
  176. var result_box = doc.createElement('DIV')
  177. result_box.id = 'result_box'
  178. var position = 'inherent'
  179. if(result_box_position == 'right') { position = 'fixed' }
  180. result_box.style.cssText = 'top:' + wnd.innerHeight/6 + 'px; right:0px; position:' + position + '; z-index:2147483647;'
  181. var posts = $$('.borderwrap')
  182. for(var i=0, len=posts.length; i<len; i++) {
  183. var poster = $(posts[i], '.bigusername')
  184. if((!poster) || (poster.textContent != $('.bigusername').textContent)) { continue } // skip threads that are not posted by the shop owner
  185.  
  186. var lines = get_text($(posts[i], '.postcolor')).split('\n')
  187. //console.log(lines)
  188. var out = ''
  189. for(var j=0, len2=lines.length; j<len2; j++) {
  190. var line = lines[j].substring(0, max_length)
  191. if(stockout(line)) { continue }
  192. for(var k=0, len3=grep_patterns.length; k<len3; k++) {
  193. var grepped = false
  194. for(var m=0, len4=grep_patterns[k][0].length; m<len4; m++) {
  195. if(grep_patterns[k][0][m].test(line)) {
  196. grepped = true
  197. out = out + line + '\n'
  198. break
  199. }
  200. }
  201. if(grepped) { break }
  202. }
  203. }
  204. if(out) {
  205. if(display_title_and_poster && (/#1/.test($(posts[i], '.postdetails').textContent))) {
  206. var shop_title = $$('.maintitle>table>tbody>tr>td>div')[0].textContent
  207. out = '[Title]\t' + shop_title.substring(0, max_length) + '\n' + '[Poster] ' + poster.textContent.substring(0, max_length)+ '\n\n' + out
  208. }
  209. var d = doc.createElement('DIV')
  210. d.className = 'result'
  211. d.style.cssText = 'background:rgba(237,235,223,1); color:#5C0D11'
  212. //d.appendChild($(posts[i], '.postdetails').cloneNode(true))
  213. var anchor = doc.createElement('A')
  214. anchor.text = $(posts[i], '.postdetails').textContent
  215. anchor.href = href.replace(loc.hash, '') + '#' + $(posts[i], '*[id^="post-main-"]').id
  216. d.appendChild(anchor)
  217. var pre = doc.createElement('PRE')
  218. pre.appendChild(doc.createTextNode(out))
  219. d.appendChild(pre)
  220. result_box.appendChild(d)
  221. }
  222. }
  223. $('.postcolor').parentNode.insertBefore(result_box, $('.postcolor'))
  224.  
  225. var toggle_result_box = function() {
  226. var result_box = $('#result_box')
  227. if(result_box.style.display != 'none') { result_box.style.display = 'none' } else { result_box.style.display = '' }
  228. }
  229. addEventListener('keydown', function(evt) { if((evt.target.tagName!='INPUT') && (evt.target.tagName!='TEXTAREA') && (evt.keyCode == hotkey)) { toggle_result_box() } }, false)
  230. if(!default_on) { toggle_result_box() }
  231. }
  232.  
  233. // Highlights equipments and items
  234. var posts = $$('.postcolor')
  235. for(var i=posts.length-1; i>=0; i--) {
  236. var lnks = $$(posts[i], 'A')
  237. for(var j=lnks.length-1; j>=0; j--) {
  238. for (var k=0, len=grep_patterns.length; k<len; k++) {
  239. var highlighted = false
  240. for(var m=grep_patterns[k][0].length-1; m>=0; m--) {
  241. if(grep_patterns[k][0][m].test(lnks[j].text)) {
  242. highlighted = true
  243. var spans = lnks[j].querySelectorAll('span')
  244. if(spans.length) {
  245. for(var n=spans.length-1; n>=0; n--) {
  246. (function(){
  247. var text = spans[n].textContent
  248. var node = doc.createTextNode(text)
  249. spans[n].parentNode.replaceChild(node, spans[n])
  250. }
  251. )()
  252. }
  253. }
  254. lnks[j].style.color = 'white'
  255. lnks[j].style.backgroundColor = grep_patterns[k][1]
  256. break
  257. }
  258. } if(highlighted) { break }
  259. }
  260. }
  261. }
  262. }