Advertisement
Guest User

E-Hentai Highlighter By etcetc (6/12/2011; Edited by sanity)

a guest
Feb 15th, 2012
181
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. // ==UserScript==
  2. // @name           E-Hentai Highlighter
  3. // @namespace      http://userscripts.org/users/106844
  4. // @description    Highlighter for E-Hentai (e-hentai.org/exhentai.org). Supports regular expressions.
  5. // @include        http://g.e-hentai.org/*
  6. // @include        http://gu.e-hentai.org/*
  7. // @exclude        http://g.e-hentai.org/g/*
  8. // @include        http://exhentai.org/*
  9. // @include        http://u.exhentai.org/*
  10. // @exclude        http://exhentai.org/g/*
  11. // @version        0.2.3
  12. // ==/UserScript==
  13.  
  14. // -------------------- OPTIONS -------------------
  15.  
  16. var DEFAULT_COLOR = '#a9938f'; // background color for highlighted items (E-Hentai)
  17. var EX_COLOR = '#3f4148'; // background color for highlighted items (Exhentai)
  18. var HIGHLIGHTER_ROWS = 9; // height (in # of rows) of the highlighter textarea
  19. var FILTER_ROWS = 6; // height (in # of rows) of the filter textarea
  20. var TEXTAREA_COLS = 40; // width (in # of columns) of both textareas
  21. var USE_NEWLINES = true; // use newline as the default delimiter (instead of ;)
  22.  
  23. // --------------- COMMON FUNCTIONS ---------------
  24.  
  25. function C(x,html) {
  26.     var tokens = x.match(/^[^#.]+|[#.][^#.]+/g),
  27.         res = document.createElement(tokens[0]);
  28.     tokens.shift();
  29.     tokens.forEach(function(k) {
  30.         if (k.charAt(0) == '.') res.className += k.substr(1) + ' ';
  31.         else if (k.charAt(0) == '#') res.id = k.substr(1);
  32.     });
  33.     if (html != null) res.innerHTML = html;
  34.     return res;
  35. }
  36.  
  37. function I(id) {
  38.     return document.getElementById(id);
  39. }
  40.  
  41. function Q(css) {
  42.     return document.querySelector(css);
  43. }
  44.  
  45. function q(css) {
  46.     return document.querySelectorAll(css);
  47. }
  48.  
  49. function S(sub,str) {
  50.     return (str||document.URL).indexOf(sub)!=-1;
  51. }
  52.  
  53. function E(exp,root) {
  54.     return document.evaluate(exp,root||document.body,null,XPathResult.FIRST_ORDERED_NODE_TYPE,null).singleNodeValue;
  55. }
  56.  
  57. function e(exp,root) {
  58.     return document.evaluate(exp,root||document.body,null,XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,null);
  59. }
  60.  
  61. function load(key,def) {
  62.     var res;
  63.     if (typeof(GM_deleteValue) != 'undefined') res = GM_getValue(key,def);
  64.     else res = (x=localStorage.getItem(key))!=null?x:def;
  65.     return JSON.parse(res);
  66. }
  67.  
  68. function save(key,value) {
  69.     if (typeof(GM_deleteValue) != 'undefined') GM_setValue(key,JSON.stringify(value));
  70.     else localStorage.setItem(key,JSON.stringify(value));
  71. }
  72.  
  73. // --------------------- MAIN ---------------------
  74.  
  75. var EHH = {
  76.    
  77.     init: function() {
  78.  
  79.         // User data
  80.    
  81.         EHH.keywords = load('keywords','[]');
  82.         EHH.filters = load('filters','[]');
  83.        
  84.         EHH.highlighterDisabled = load('highlighterDisabled',false);
  85.         EHH.filterDisabled = load('filterDisabled',false);
  86.            
  87.         // Permanent style
  88.        
  89.         document.head.appendChild(C('style',
  90.             '#e-HentaiPopup {' +
  91.                 'position: fixed; top: 0; right: 0; padding: 3px;' +
  92.                 'border: 1px black solid; background: #686868; z-index: 10;' +
  93.             '} #e-HentaiPopup:not(:hover) *:not(:first-child) { display: none; }' +
  94.             '#e-HentaiPopup * {' +
  95.                 'font-family: Verdana, Tahoma, Georgia, Dejavu, "Times New Roman", Serif;' +
  96.                 'font-size: 10px;' +
  97.             '} #e-HentaiPopup *:not(textarea) { color: white; }' +
  98.             '#e-HentaiPopup div { text-align: center; }' +
  99.             '#e-HentaiPopup tr:last-child { text-align: left; }' +
  100.             '#e-HentaiPopup td:nth-child(2) { text-align: right; }' +
  101.             '#e-HentaiPopup td:nth-child(2) a, #e-HentaiPopup tr:last-child a {' +
  102.                 'cursor: pointer; font-weight: bold; border-bottom: 1px dotted;' +
  103.             '} #e-HentaiPopup .e-Disable { color: #94de80; }' +
  104.             '#e-HentaiPopup .e-Disable:hover { color: #b9ffa6; }' +
  105.             '#e-HentaiPopup .e-Enable { color: #d98080; }' +
  106.             '#e-HentaiPopup .e-Enable:hover { color: #f1bebe; }' +
  107.             '#e-HentaiPopup tr:last-child a:hover { color: black; }' +
  108.             '#e-HentaiPopup td > span { margin-right: 5px; float: right; }' +
  109.             '.itg > .c { display: none; }' +
  110.             '.itd1, .ido > h1.ih ~ div {' +
  111.                 'float: none !important; display: inline-block;' +
  112.                 'margin: 0px !important; vertical-align: top;' +
  113.             '} .e-Highlighted b { font-weight: inherit; }'));
  114.  
  115.         // Swappable styles
  116.  
  117.         EHH.highlighterCSS = C('style#e-Highlighter',
  118.             '.e-Highlighted { background: -moz-linear-gradient(top, rgba(255,255,255,0), ' + (S('e-hentai')?DEFAULT_COLOR:EX_COLOR) + ' 100%) !important; border: 2px solid ' + (S('e-hentai')?DEFAULT_COLOR:EX_COLOR) + ' !important; border-radius: 5px; margin: 3px; padding: 2px !important}' +
  119.             '.e-Highlighted b { font-weight: bold !important; text-decoration: none; }');
  120.        
  121.         EHH.filterCSS = C('style#e-Filter',
  122.             'tr.color0 { background: ' + (S('e-hentai')?'#F2F0E4':'#363940') + '; }' +
  123.             'tr.color1 { background: ' + (S('e-hentai')?'#EDEBDF':'#4F535B') + '; }' +
  124.             '#toppane ~ .c, .e-Filtered { display: none !important; }');
  125.        
  126.         // Popup
  127.            
  128.         document.body.appendChild(C('div#e-HentaiPopup',
  129.             '<div><b>E-H Highlighter</b></div><hr /><table align="right">' +
  130.             '<tr><td>Keywords:</td><td><a id="e-HighlighterSwitch">Highlighter: enabled</a></tr>' +
  131.             '<tr><td colspan="2"><textarea rows="' + HIGHLIGHTER_ROWS +
  132.             '" cols="' + TEXTAREA_COLS + '"></textarea></td></tr>' +
  133.             '<tr><td>Filters:</td><td><a id="e-FilterSwitch">Filter: enabled</a></td></tr>' +
  134.             '<tr><td colspan="2"><textarea rows="' + FILTER_ROWS +
  135.             '" cols="' + TEXTAREA_COLS + '"></textarea></td></tr>' +
  136.             '<tr><td colspan="2"><a id="e-PopupSave">Save changes</a>' +
  137.             '<span><b>Filtered items:</b> <span id="e-FilteredItems"></span></span></tr></table>'));
  138.        
  139.         // Popup elements
  140.        
  141.         EHH.highlighterSwitch = I('e-HighlighterSwitch');
  142.         EHH.filterSwitch = I('e-FilterSwitch');
  143.         EHH.updateSwitch(EHH.highlighterSwitch,EHH.highlighterDisabled);
  144.         EHH.updateSwitch(EHH.filterSwitch,EHH.filterDisabled);
  145.        
  146.         var textareas = q('#e-HentaiPopup textarea');
  147.         EHH.highlighterArea = textareas[0];
  148.         EHH.filterArea = textareas[1];
  149.         EHH.highlighterArea.textContent = EHH.keywords.join(USE_NEWLINES?'\n':';');
  150.         EHH.filterArea.textContent = EHH.filters.join(USE_NEWLINES?'\n':';');
  151.        
  152.         // Events
  153.  
  154.         EHH.highlighterSwitch.addEventListener('click',function() {
  155.             EHH.highlighterDisabled = /enabled/.test(this.textContent);
  156.             EHH.updateSwitch(this,EHH.highlighterDisabled);
  157.             save('highlighterDisabled',EHH.highlighterDisabled);
  158.         },false);
  159.  
  160.         EHH.filterSwitch.addEventListener('click',function() {
  161.             EHH.filterDisabled = /enabled/.test(this.textContent);
  162.             EHH.updateSwitch(this,EHH.filterDisabled);
  163.             save('filterDisabled',EHH.filterDisabled);
  164.         },false);
  165.        
  166.         I('e-PopupSave').addEventListener('click',function() {
  167.             EHH.keywords = EHH.highlighterArea.value.split(/[;\n]/).filter(function(x) { return x.length>0; });
  168.             EHH.filters = EHH.filterArea.value.split(/[;\n]/).filter(function(x) { return x.length>0; });
  169.             save('keywords',EHH.keywords);
  170.             save('filters',EHH.filters);
  171.             EHH.walk();
  172.         },false);
  173.        
  174.         document.addEventListener('DOMNodeInserted',function(e) {
  175.             if (e.target.nodeName == 'TBODY')
  176.                 EHH.walk(e.target);
  177.         },false);
  178.        
  179.         // Start
  180.        
  181.         EHH.swap();
  182.         EHH.walk();
  183.  
  184.     },
  185.    
  186.     swap: function() { 
  187.         if (!EHH.highlighterDisabled && !I('e-Highlighter')) document.head.appendChild(EHH.highlighterCSS);
  188.         else if (EHH.highlighterDisabled && I('e-Highlighter')) document.head.removeChild(EHH.highlighterCSS);
  189.         if (!EHH.filterDisabled && !I('e-Filter')) document.head.appendChild(EHH.filterCSS);
  190.         else if (EHH.filterDisabled && I('e-Filter')) document.head.removeChild(EHH.filterCSS);
  191.         I('e-FilteredItems').textContent = EHH.filterDisabled?0:q('.e-Filtered').length;
  192.     },
  193.    
  194.     updateSwitch: function(target,disable) {
  195.         target.textContent = target.textContent.replace(/[^\s]+$$/,disable?'disabled':'enabled');
  196.         target.className = disable?'e-Enable':'e-Disable';
  197.         EHH.swap();
  198.     },
  199.    
  200.     walk: function(root) {
  201.  
  202.         var highlightReg = !EHH.keywords.length?null:new RegExp('(' + EHH.keywords.join('|') + ')','gi'),
  203.             filterReg = !EHH.filters.length?null:new RegExp(EHH.filters.join('|'),'i'),
  204.             flip = false,
  205.             targets = e('.//*[starts-with(@class,"gtr") or starts-with(@class,"itd1")]|.//table[@class="t2"]//tr');
  206.        
  207.         for (var i=0;i!=targets.snapshotLength;i++) {
  208.        
  209.             var target = targets.snapshotItem(i),
  210.                 title = E('.//div[@class="it3" or @class="itd2" or @class="t2"]/' +
  211.                     'a[not(@rel="nofollow")]',target)||E('./td//a',target);
  212.  
  213.             if (filterReg) {
  214.                 if (filterReg.test(title.textContent)) {
  215.                     if (!S('e-Filtered',target.className)) target.className += ' e-Filtered';
  216.                     flip = !flip;
  217.                 } else if (S('e-Filtered',target.className)) {
  218.                     target.className = target.className.replace(/ ?e-Filtered/g,'');
  219.                 }
  220.             }
  221.            
  222.             if (highlightReg) {
  223.                 if (highlightReg.test(title.textContent)) {
  224.                     if (!S('e-Highlighted',target.className)) target.className += ' e-Highlighted';
  225.                     title.innerHTML = title.innerHTML.replace(highlightReg,'<b>$1</b>').replace(/(<\/?b>)+/g,'$1');
  226.                 } else if (S('e-Highlighted',target.className)) {
  227.                     target.className = target.className.replace(/ ?e-Highlighted/g,'');
  228.                     title.innerHTML = title.innerHTML.replace(/<b>(.+?)<\/b>/g,'$1');
  229.                 }
  230.             } else if (S('e-Highlighted',target.className)) {
  231.                 target.className = target.className.replace(/\s?e-Highlighted/,'');
  232.                 title.innerHTML = title.innerHTML.replace(/<b>(.+?)<\/b>/g,'$1');
  233.             }
  234.            
  235.             if (!/^gtr/.test(target.className)) continue;
  236.             if (!S('color',target.className)) target.className += ' color' + Number(flip=!flip);
  237.             else target.className = target.className.replace(/color\d/,'color' + Number(flip=!flip));
  238.         }
  239.        
  240.         I('e-FilteredItems').textContent = EHH.filterDisabled?0:q('.e-Filtered').length;
  241.        
  242.     }
  243.    
  244. }
  245.  
  246. EHH.init();
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement