Advertisement
somepbanon

Thread Page Finder 1.4.11

May 13th, 2011
141
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. // ==UserScript==
  2. // @name           Thread Page Finder
  3. // @namespace      tpf
  4. // @description    Find's the thread's page number. Can also auto-update.
  5. // @include        http://boards.4chan.org/*/res/*
  6. // @include        https://boards.4chan.org/*/res/*
  7. // @version     1.4.11.05142012
  8. // @copyright       05092011, tpf
  9. // @compatibility   Firefox 4, Chrome 11 (with Tampermonkey 2.0)
  10. // ==/UserScript==
  11. /*Changelog
  12. 1.4.11.05142012 - updated regex for the new HTML
  13. 1.4.10.03262012 - included Auto to saved variables
  14. 1.4.9.05142011 - changed init trigger
  15. 1.4.8.05142011 - release, no records
  16. */
  17. (function(){
  18. //Please use the GM registered menus if present
  19. //clearSettings();//Reset defaults
  20. //toggleTitles(false);//Turn off titles/hover messages
  21.  
  22. var Frontpage = {
  23.     url: location.href.match(/(^.*\/)res\//i)[1],
  24.     board: null,
  25.     lastmodify: null,
  26.    
  27.     is_f: false,
  28.     rx_threadnos: null,
  29.     rx_pages: null,
  30.    
  31.     init: function(){
  32.         this.is_f = /\.org\/f\//i.test(this.url);
  33.         this.board = Frontpage.url.replace(/.*\.org/i,'');
  34.         this.rx_threadnos = (this.is_f ?           
  35.             /<a\shref=(?:["']|)res\/(\d+)(?:["']|)>/gi : //f
  36.             /<a\shref=(?:["']|)res\/(\d+)(?:["']|)\sclass=(?:["']|)replylink(?:["']|)/gi );
  37.         this.rx_pages = /\[<a\shref=(?:["']|)(\d+)(?:["']|)>\1<\/a>\]/gi;
  38.         this.check(); //Initialize lastmodify
  39.     },
  40.    
  41.     check:function(chklastdate, callfunc){
  42.         function chkStatus(res){           
  43.             if(res.status == 200)
  44.                 Frontpage.lastmodify = new Date(
  45.                     res.getResponseHeader('Last-Modified')
  46.                 );         
  47.             if(callfunc)
  48.                 callfunc(res);         
  49.         }
  50.         xhr(
  51.             this.url,
  52.             chkStatus,
  53.             'head',
  54.             (chklastdate? this.lastmodify.toUTCString() : null)
  55.         );
  56.     }  
  57. }//Frontpage
  58.  
  59. var Thread = {
  60.     id: location.href.match(/\/res\/(\d+)/i)[1],
  61.     rx_id: null,
  62.     init: function(){
  63.         //this.rx_id = RegExp('((nothread|res\/)'+this.id+')[^\d]');
  64.         this.rx_id = RegExp('(res\/'+this.id+')[^\d]');    
  65.     },
  66.    
  67.     check: function(callfunc){
  68.         xhr(Frontpage.url+'res/'+this.id, callfunc, 'head');
  69.     }
  70. }//Thread
  71.  
  72. function container(outer){
  73.     this.outer = outer;
  74.    
  75.     this.add = function(id, element, title, parent){
  76.         this[id] = document.createElement(element);
  77.         this[id].id = id;
  78.         if(title){
  79.             if(Box.showTitles) this[id].title = title;
  80.             this[id].temptitle = title;
  81.         }
  82.         if(parent)
  83.             this[parent].appendChild(this[id]);
  84.         else
  85.             this.outer.appendChild(this[id]);
  86.     }
  87. }
  88.  
  89. function createContainer(){
  90.     var con = new container(document.createElement('div'));
  91.     con.outer.id = Box.uid;
  92.     con.add('msg', 'span');
  93.     con.add('pin', 'a', 'Pin/Unpin');
  94.     con.add('drag', 'a', 'Move');
  95.     con.add('mini', 'a', 'Full/Mini');
  96.     con.add('upd', 'a', 'Update Now');
  97.     con.add('af', 'span');
  98. //<!--af
  99.     con.add('auto', 'a', 'Enable Auto-update', 'af');
  100. //<!--uif
  101.     con.add('uif', 'span', null, 'af');
  102.     con.add('set', 'span', null, 'uif');
  103.     con.add('inp', 'input', 'Update interval [enter]', 'uif');
  104.     con.inp.type = 'text';
  105. //form-->
  106. //af-->
  107.     con.add('stat', 'span');   
  108.     document.body.insertBefore(con.outer, document.body.firstChild);
  109.     return con;
  110. }//createContainer
  111.  
  112. function setCustomStyle(css){
  113.     var customStyle = [
  114.         ' #', Box.uid, ' { ',
  115.             (Box.isMini?'':'border: 1px solid black; '),
  116.             (Box.isMini?'':'padding: 5px 8px 5px 8px; '),
  117.             'z-index: ', (Math.pow(2, 31)-1), '; ',
  118.         ' }',
  119.         ' #', Box.uid, ' > * { ',//defaults
  120.             'clear: none; ',
  121.             'white-space: nowrap; ',
  122.             'margin: 0 0; ',
  123.             'border: 0 none; ',
  124.             'padding: 0 0; ',
  125.         ' }',
  126.         //p,d,m
  127.         '\n #', Box.uid, '> #pin, ',
  128.         ' #', Box.uid, '> #drag, ',
  129.         ' #', Box.uid, '> #mini { ',
  130.             'position:', (Box.isMini?'static; ':'absolute; '),
  131.             (Box.isMini?'margin: 0 2px; ':''),
  132.             'top: -5px; ',
  133.             'font-weight: bold; ',
  134.             'font-size: 1.1em; ',
  135.             'cursor: pointer; ',
  136.             'background: none; ',
  137.             'display: none; ',
  138.         ' }',
  139.         '\n #', Box.uid, '> #mini { right:1px; }',
  140.         '\n #', Box.uid, '> #drag { ',
  141.             'left: 10px; ',
  142.             'cursor: move; ',
  143.             'width: 80%; ',
  144.         ' }',
  145.         '\n #', Box.uid, '> #pin { ',
  146.             'left: 1px; ', 
  147.             'top: -2px; ',
  148.             'font-size: 0.8em; ',
  149.         ' }',
  150.         '\n #', Box.uid, ':hover > #pin, ',
  151.         ' #', Box.uid, ':hover > #drag, ',
  152.         ' #', Box.uid, ':hover > #mini { display: inline; }',
  153.         //ms,st
  154.         '\n #', Box.uid, '> #msg { ',
  155.             'display:', (Box.isMini?'inline; ':'block; '),
  156.             'font-size:', (Box.isMini?'1.01em; ':'1.2em; '),
  157.             'font-variant: small-caps; ',
  158.             (Box.isMini?'margin: 0 5px; ':''),
  159.             (Box.isMini ?'':'clear: both; '),
  160.         ' }',
  161.         '\n #', Box.uid, '> #stat { ',
  162.             'font-size: 0.9em; ',
  163.             'font-style: italic; ',
  164.             'color: #555555; ',
  165.             'display:', (Box.isMini?'none; ':'block; '),
  166.             'clear: both; ',
  167.         ' }',      
  168.         '\n #', Box.uid, '.left > #msg, ',
  169.         ' #', Box.uid, '.left > #stat { ',
  170.             'text-align: left; ',   //(Box.isMini ?'float: left; ':''),
  171.         ' }',
  172.         '\n #', Box.uid, '.right > #msg, ',
  173.         ' #', Box.uid, '.right > #stat { ',
  174.             'text-align: right; ',  //(Box.isMini ?'float: right; ':''),
  175.         ' }',
  176.         //up,af
  177.         '\n #', Box.uid, '> #upd, ',
  178.         ' #', Box.uid, '> #af > #auto { ',
  179.             'margin: 0 ', (Box.isMini?'2':'1'), 'px; ',
  180.             'cursor: pointer; ',
  181.             'font-size: 1em; ',
  182.             'font-variant: small-caps; ',
  183.             'font-weight: bold; ',
  184.             'display: none; ',
  185.         ' }',//bca.style.color = Box.isAuto? '#119911':'';
  186.         '\n #', Box.uid, '> #af > #auto.on { ',
  187.             ' color: #119911; ',
  188.             (Box.isMini?' display: inline; ':' '),
  189.         ' }',      
  190.         '\n #', Box.uid, '> #af > #uif { ',
  191.             'clear: none; ',
  192.             'position: relative; ', //(Box.isMini?'':'top: 3px; '),
  193.         ' }',
  194.         '\n #', Box.uid, '> #af > #uif > #inp { ',
  195.             'font-size: 0.9em; ',
  196.             'text-align: right; ',
  197.             'width: 40px; ',
  198.             'padding: 0 0; ',//'margin: 0 2px; ',
  199.         ' }',
  200.         '\n #', Box.uid, '> #af > #uif > #set { ',
  201.             'font-size: 0.9em; ',
  202.             'color: #555555; ',
  203.             'margin: 0 3px; ',
  204.             'position: relative; ',
  205.             (Box.isMini?'':'top: 2px; '),
  206.         ' }',
  207.         '\n #', Box.uid, '> #af > #uif { ',
  208.             'display: none; ',
  209.             'margin: 2px 0; ',
  210.             'clear: none; ',
  211.         ' }',
  212.         '\n #', Box.uid, ':hover > #upd, ',
  213.         ' #', Box.uid, ':hover > #af > #auto { display: inline; }',
  214.         '\n #', Box.uid, '> #af:hover > #uif { display: inline; }',
  215.        
  216.         '\n #', Box.uid, '.left > #upd, ',  //' #', Box.uid, '.left > #af, ',
  217.         ' #', Box.uid, '.left > #af > *, ',
  218.         ' #', Box.uid, '.left > #af > #uif > * { float: left; }',
  219.         '\n #', Box.uid, '.right > #upd, ', //' #', Box.uid, '.right > #af, ',
  220.         ' #', Box.uid, '.right > #af > *, ',
  221.         ' #', Box.uid, '.right > #af > #uif > * { float: right; }',    
  222.     ].join('');
  223.        
  224.     if(!css){
  225.         var css = document.createElement('style');
  226.         css.id = Box.uid+'_css';
  227.         css.type = 'text/css';
  228.         document.getElementsByTagName('head')[0].appendChild(css);
  229.     }
  230.     css.innerHTML = customStyle;
  231. }
  232.  
  233. var Box = {
  234.     uid:'thread_page_finder',
  235.     con:null,   //container
  236.     toh:null,
  237.     lastdetails:null,
  238.     pagelastfound:0,
  239.     interval:60,    //In seconds
  240.     isAuto:false,
  241.     isMini:false,
  242.     isPinned:true,
  243.     showTitles: true,
  244.    
  245.     init: function(){
  246.         this.isAuto = GM_getValue('_isAuto', this.isAuto);
  247.         this.isMini = GM_getValue('_isMini', this.isMini);
  248.         this.isPinned = GM_getValue('_isPinned', this.isPinned);
  249.         this.interval = GM_getValue('_interval', this.interval);
  250.         this.showTitles = GM_getValue('_showTitles', this.showTitles);
  251.         setCustomStyle();
  252.         this.con = createContainer();
  253.         var tc = this.con;
  254.         var tcos = tc.outer.style;
  255.         document.body.style.position = 'relative';
  256.         tcos.position = this.isPinned?'fixed':'absolute',
  257.         tcos.left = GM_getValue('_offset_left', null);
  258.         tcos.top = GM_getValue('_offset_top', null);
  259.         tcos.right = GM_getValue('_offset_right', '0px');
  260.         tcos.bottom = GM_getValue('_offset_bottom', '0px');
  261.         this.toggleAuto(null, true);
  262.        
  263.         this.setLabels();
  264.         tc.msg.innerHTML = [
  265.             '<span style="font-variant:normal;">',
  266.             Frontpage.url, '</span>',
  267.             '<b>', Thread.id, '</b>',
  268.             ].join('');
  269.        
  270.         listen(tc.pin, 'click', Box.togglePin);
  271.         listen(tc.mini, 'click', Box.toggleMinimal);
  272.         listen(tc.upd, 'click', Box.forceUpdate);
  273.         listen(tc.auto, 'click', Box.toggleAuto);
  274.         //listen(tc.uif, 'submit', function(e){ Box.setInterval(e); });
  275.         listen(tc.inp, 'keypress', function(e){ Box.validateInput(e); });
  276.         listen(tc.drag, 'mousedown', Box.dragStart);
  277.     },
  278.    
  279.     saveValues: function(){
  280.         GM_setValue('_isAuto', Box.isAuto);
  281.         GM_setValue('_isMini', Box.isMini);
  282.         GM_setValue('_isPinned', Box.isPinned);
  283.         GM_setValue('_interval', Box.interval);
  284.         var bcos = Box.con.outer.style;
  285.         GM_setValue('_offset_left', bcos.left);
  286.         GM_setValue('_offset_top', bcos.top);
  287.         GM_setValue('_offset_right', bcos.right);
  288.         GM_setValue('_offset_bottom', bcos.bottom);
  289.     },
  290.    
  291.     setLabels: function(opt){
  292.         opt = opt?opt:'111'; //If opt is omitted/null, do all;
  293.         var bc = Box.con;
  294.         var bim = Box.isMini;
  295.         var align = bc.outer.style.left?'left':'right';
  296.         bc.outer.className = bim?'':'reply ' + align;
  297.         if(opt[0]){//Full/mini
  298.             bc.upd.innerHTML = bim?'U':'[update]';
  299.             bc.auto.innerHTML = bim?'A':'[auto]';
  300.             bc.drag.innerHTML = bim?'+':'&nbsp;';
  301.             bc.mini.innerHTML = bim?'\u53E3':'\u2013';//\u039e
  302.             bc.mini.temptitle = bim?'Full':'Mini';
  303.             if(Box.showTitles) bc.mini.title = bc.mini.temptitle;
  304.         }//
  305.         if(opt[1]){//Pinned/unpinned
  306.             bc.pin.innerHTML = Box.isPinned?'\u51fa':'\u4e2d';//\u00a4':'\u00f8';//d7';
  307.             bc.pin.temptitle = Box.isPinned?'Unpin':'Pin';
  308.             if(Box.showTitles) bc.pin.title = bc.pin.temptitle;
  309.         }
  310.         if(opt[2]){//Update interval
  311.             bc.inp.value = Box.interval;
  312.             bc.set.innerHTML = Box.interval+'sec'+
  313.                 ((Box.interval>1)?'s':null);
  314.         }
  315.     },
  316.     //Buttons/input
  317.     toggleMinimal: function(){
  318.         Box.isMini = !Box.isMini;
  319.         Box.saveValues();
  320.         setCustomStyle(document.getElementById(Box.uid+'_css'));
  321.         Box.setLabels('1');
  322.         Box.updateMsg();
  323.     },
  324.     recalcYOffset: function(){//fixed(px)/absolute(%) offset conversion
  325.         var bco = Box.con.outer;
  326.         var bcos = bco.style;
  327.         var wih = window.innerHeight;
  328.         var wpyo = window.pageYOffset;
  329.         var pageh = document.documentElement.scrollHeight; //wsmy + wih
  330.         var wsmy = pageh - wih; //window.scrollMaxY
  331.         var fixedoffset = Box.isPinned;
  332.         var top, btm;
  333.         function cvt(val, offset){
  334.             return fixedoffset?
  335.                 parseInt(val) + offset:
  336.                 Math.round(pageh * parseFloat(val)/100) - offset;
  337.         }
  338.         if(bcos.top){
  339.             top = cvt(bcos.top, wpyo);
  340.             btm = (fixedoffset?pageh:wih) - top - bco.offsetHeight;
  341.         }else{
  342.             btm = cvt(bcos.bottom, wsmy - wpyo);
  343.             top = (fixedoffset?pageh:wih) - btm - bco.offsetHeight;
  344.         }
  345.         function suffix(val){
  346.             val = val<10?0:val;
  347.             return fixedoffset?
  348.                 Math.round(((val/pageh) * 100)) + '%' :
  349.                 val + 'px';
  350.         }
  351.         bcos.top = (top<=btm)? suffix(top) :null;
  352.         bcos.bottom = (top<=btm)? null: suffix(btm);
  353.     },
  354.     togglePin: function(){
  355.         Box.recalcYOffset();
  356.         Box.isPinned = !Box.isPinned;
  357.         Box.con.outer.style.position = Box.isPinned?'fixed':'absolute';
  358.         Box.saveValues();
  359.         Box.setLabels('01');
  360.     },
  361.     setInterval: function(evt){
  362.         //evt.preventDefault();
  363.         Box.interval = parseInt(Box.con.inp.value);
  364.         Box.saveValues();
  365.         Box.setLabels('001');
  366.     },
  367.     validateInput: function(evt){
  368.         if(evt.keyCode == 13)   //Enter
  369.             Box.setInterval(evt);
  370.         if(!evt.charCode) return;
  371.         if(
  372.             evt.charCode < 48 ||
  373.             evt.charCode > 57 ||
  374.             evt.target.value.toString().length >= 5
  375.         )
  376.             evt.preventDefault();      
  377.     },
  378.     toggleAuto: function(set, load){
  379.         if(!load){
  380.             Box.isAuto = ((set == 'off')? false : !Box.isAuto);
  381.             Box.saveValues();
  382.         }
  383.         var bca = Box.con.auto;
  384.         //bca.style.color = Box.isAuto? '#119911':'';
  385.         bca.className = Box.isAuto? 'on':'';
  386.         bca.temptitle = (Box.isAuto?'Disable':'Enable') +' Auto-update';
  387.         if(Box.showTitles) bca.title = bca.temptitle;
  388.         if(Box.isAuto && !load) Box.searchProcess(0);
  389.     },
  390.     //Move/drag
  391.     offset:{ left:0, top:0, unpin: false,
  392.         tempShow:function(dis){
  393.             var el = ['pin', 'mini', 'drag', 'upd', 'af'];
  394.             for(i in el)
  395.                 Box.con[el[i]].style.display = dis?'inline':'';
  396.         }
  397.     },
  398.     dragStart: function(evt){
  399.         if(!Box.isPinned){ //Pin temporarily (Todo: Full page dragging.)
  400.             Box.togglePin();
  401.             Box.offset.unpin = true;;
  402.         }
  403.         Box.offset.tempShow(true);
  404.         var bco = Box.con.outer
  405.         var bcos = bco.style;
  406.         Box.offset.left = evt.clientX -
  407.             (bcos.left? parseInt(bcos.left) :
  408.                 (window.innerWidth -
  409.                 parseInt(bcos.right) -
  410.                 bco.offsetWidth));
  411.         Box.offset.top = evt.clientY -
  412.             (bcos.top? parseInt(bcos.top) :
  413.                 (window.innerHeight -
  414.                 parseInt(bcos.bottom) -
  415.                 bco.offsetHeight));
  416.         listen(document, 'mousemove', Box.doDrag);
  417.         listen(document, 'mouseup', Box.dragStop);
  418.         document.body.focus();
  419.     },
  420.     doDrag: function(evt){
  421.         var bco = Box.con.outer;
  422.         var bcos = bco.style;
  423.         var left = evt.clientX - Box.offset.left;
  424.         var right = window.innerWidth - left - bco.offsetWidth;
  425.         var top = evt.clientY - Box.offset.top;
  426.         var bottom = window.innerHeight - top - bco.offsetHeight;
  427.         bcos.left = (left<=right)? ((left<10?0:left)+'px') :null;
  428.         bcos.right = (left<=right)? null: ((right<10?0:right)+'px');
  429.         bcos.top = (top<=bottom)? ((top<10?0:top)+'px') :null;
  430.         bcos.bottom = (top<=bottom)? null: ((bottom<10?0:bottom)+'px');
  431.     },
  432.     dragStop: function(evt){
  433.         if(Box.offset.unpin){ //Return pin-state (Todo)
  434.             Box.togglePin();
  435.             Box.offset.unpin = false;
  436.         }
  437.         Box.offset.tempShow(false);
  438.         listen(document, 'mousemove', Box.doDrag, 'remove');
  439.         listen(document, 'mouseup', Box.dragStop, 'remove');
  440.         Box.setLabels('000');
  441.         Box.saveValues();
  442.     },
  443.     //Text display
  444.     updateStat: function(msg, clear){
  445.         if(clear) this.con.stat.innerHTML = '';
  446.         this.con.stat.innerHTML += msg;
  447.     },     
  448.     updateMsg: function(details){
  449.         if(!details){
  450.             if(!Box.lastdetails) return;
  451.             else details = Box.lastdetails;
  452.         }else Box.lastdetails = details;
  453.         details.page = details.page?details.page:'0';
  454.         if(Box.isMini)
  455.         this.con.msg.innerHTML = [
  456.             'Pg ', details.page,
  457.             '/', details.lastpage,         
  458.             ' Th ', details.threadpos,
  459.             '/', details.threadtotal
  460.         ].join('');
  461.         else
  462.         this.con.msg.innerHTML = [
  463.             'Page: <b>', details.page,
  464.             '</b>/', details.lastpage,
  465.             '<br>Thread: <b>', details.threadpos,
  466.             '</b>/', details.threadtotal
  467.         ].join('');
  468.        
  469.         if(!details) return;
  470.         var suff = 'th';
  471.         if(details.threadpos == 1) suff = 'st';
  472.         if(details.threadpos == 2) suff = 'nd';
  473.         if(details.threadpos == 3) suff = 'rd';
  474.         var tcm = this.con.msg;
  475.         tcm.temptitle = [
  476.             Thread.id,
  477.             ' is the ', details.threadpos, suff,
  478.             ' of ', details.threadtotal,
  479.             ' thread', ((details.threadtotal>1)?'s':''),
  480.             ' on page ', details.page,
  481.             ' of ', (details.lastpage?
  482.                 ('all '+ (parseInt(details.lastpage)+1) + ' pages'):
  483.                 'a page'),
  484.             ' on ', Frontpage.board, '.',
  485.         ].join('');
  486.         if(Box.showTitles) tcm.title = tcm.temptitle;
  487.     },
  488.     //Searching
  489.     forceUpdate: function(){
  490.         Box.updateStat('', true);
  491.         Box.searchProcess(2);
  492.     }, 
  493.     searchProcess: function(stage){
  494.         switch(stage){
  495.             case 0:
  496.                 var count = Box.interval;
  497.                 function countDown(){
  498.                     //if(!Box.isAuto) return;
  499.                     if(!count)
  500.                         Box.searchProcess(1);
  501.                     else {
  502.                         Box.updateStat([
  503.                             'Updating in ',
  504.                             count, 'sec', (count>1?'s':'')].join(''),
  505.                             true);
  506.                         count--;
  507.                         clearTimeout(Box.toh);
  508.                         Box.toh = window.setTimeout(countDown, 1000);
  509.                     }
  510.                 }
  511.                 countDown();
  512.                 break;
  513.             case 1:
  514.                 Box.updateStat('Checking frontpage... ', true);
  515.                 Frontpage.check(true, function(res){
  516.                     Box.updateStat(res.statusText);
  517.                     switch(res.status){
  518.                         case 200: //Frontpage changed. Do next stage
  519.                             Box.updateStat('<br>');
  520.                             Box.searchProcess(2);
  521.                             break;
  522.                         case 304: //No change on frontpage. Restart.
  523.                             if(Box.isAuto){
  524.                                 window.setTimeout(function(){
  525.                                     Box.searchProcess(0);
  526.                                 }, 1500);   //Show status message for 1.5sec
  527.                             }
  528.                             break;
  529.                         default: Box.toggleAuto('off');
  530.                     }
  531.                 });
  532.                 break;
  533.             case 2:
  534.                 Box.updateStat('Checking thread... ');
  535.                 Thread.check(function(res){
  536.                     Box.updateStat(res.statusText);
  537.                     if(res.status == 200){ //Thread still up. Do next stage.
  538.                         Box.updateStat('<br>');
  539.                         Box.searchProcess(3);
  540.                     }else Box.toggleAuto('off');
  541.                 });
  542.                 break;
  543.             case 3:
  544.                 Box.updateStat('Finding thread\'s page... ');
  545.                 clearTimeout(Box.toh);
  546.                 findThread(Box.pagelastfound, function(details){
  547.                     if(details){
  548.                         Box.updateStat('', true); //Clear status message
  549.                         Box.updateMsg(details);
  550.                         Box.pagelastfound = details.page;
  551.                         if(Box.isAuto) Box.searchProcess(0);
  552.                     }else{
  553.                         Box.updateStat('Can\'t find thread');
  554.                         if(!Frontpage.is_f){
  555.                             Box.updateStat('<br>');
  556.                             Box.searchProcess(2);
  557.                         }else{
  558.                             Box.updateStat('<br>(Marked for deletion?)');
  559.                             Box.toggleAuto('off');
  560.                         }                          
  561.                     }
  562.                 });
  563.         }
  564.     }
  565. }//Box
  566. function findThread(lastfound, callfunc){      
  567.     var nextpage = lastfound;
  568.     var lastpage = 15; 
  569.     if(Frontpage.is_f){
  570.         lastpage = 0;
  571.         searchPages();     
  572.     }  
  573.     else
  574.         xhr(Frontpage.url, function(res){
  575.             var pages = res.responseText.match(Frontpage.rx_pages);
  576.             lastpage = pages.length? (/>(\d+)</.exec(pages[pages.length - 1])[1]) : 0;
  577.             searchPages();
  578.         });
  579.     /*function getLastpage(res){
  580.         if(!res){
  581.             xhr(Frontpage.url+lastpage, getLastpage, 'head');
  582.         }else{
  583.             if(res.status == 200 || !lastpage){
  584.                 searchPages();
  585.             }else{
  586.                 lastpage--;
  587.                 getLastpage(null);
  588.     }}}*/
  589.     function searchPages(res){     
  590.         if(res && res.status == 200){          
  591.             var threadnos = res.responseText.match(Frontpage.rx_threadnos);        
  592.             for(var i = 0; i < threadnos.length; i++){             
  593.                 if(Thread.rx_id.test(threadnos[i])){
  594.                     var details = {
  595.                         page: res.url.replace(Frontpage.url, ''),
  596.                         lastpage: lastpage,
  597.                         threadpos: (i+1),
  598.                         threadtotal: threadnos.length
  599.                     }
  600.                     callfunc(details);
  601.                     return;
  602.                 }
  603.             }          
  604.             if(nextpage >= lastpage) nextpage = 0;
  605.             else nextpage++;
  606.             if(nextpage == lastfound || !lastpage){
  607.                 callfunc(null);
  608.                 return;
  609.             }
  610.         }      
  611.         xhr(Frontpage.url+(nextpage?nextpage:''), searchPages);
  612.         //xhr(Frontpage.url+nextpage, searchPages);
  613.     }
  614. }
  615. function clearSettings(){
  616.     GM_deleteValue('_isAuto');
  617.     GM_deleteValue('_isMini');
  618.     GM_deleteValue('_isPinned');
  619.     GM_deleteValue('_interval');
  620.     GM_deleteValue('_offset_left');
  621.     GM_deleteValue('_offset_top');
  622.     GM_deleteValue('_offset_right');
  623.     GM_deleteValue('_offset_bottom');
  624.     GM_deleteValue('_showTitles');
  625.     //GM_deleteValue('_records');
  626.     try{
  627.     var ui = document.getElementById(Box.uid);
  628.     ui.parentNode.removeChild(ui);
  629.     }catch(e){console.log(e);}
  630.     init();
  631. }
  632. function toggleTitles(off){
  633.     var bc = Box.con;
  634.     var show = (typeof off === 'boolean')? off : !Box.showTitles;
  635.     for(i in bc){
  636.         var title = bc[i].temptitle;
  637.         if( title ) bc[i].title = show?title:'';
  638.     }
  639.     Box.showTitles = show;
  640.     GM_setValue('_showTitles', show);
  641.     alert(Box.uid+':\nTitles/hover messages '+(show?'enabled':'disabled'));
  642. }
  643. try{
  644. GM_registerMenuCommand(
  645.     'ThreadPageFinder: Reset/restore settings',
  646.     clearSettings, 'R');
  647. GM_registerMenuCommand(
  648.     'ThreadPageFinder: Enable/disable titles (hover messages)',
  649.     toggleTitles, 'E');
  650. }catch(e){console.log(e);}
  651. //Utilities
  652. if(GM_setValue === undefined){
  653.     GM_setValue = function(key, val){
  654.         val = (typeof val)[0] + val;
  655.         localStorage.setItem(Box.uid+key, val);
  656.     }
  657.     GM_getValue = function(key, defval){
  658.         var val = localStorage.getItem(Box.uid+key);
  659.         if(!val) return defval;
  660.         var type = val[0];
  661.         val = val.substring(1);
  662.         if(type == 'b') return val == 'true';
  663.         if(type == 'n') return parseInt(val);
  664.         return val;
  665.     }
  666.     GM_deleteValue = function(key){
  667.         localStorage.removeItem(Box.uid+key);
  668.     }
  669. }
  670. function listen(item, type, func, remove){
  671.     if(remove) item.removeEventListener(type, func, false);
  672.     else item.addEventListener(type, func, false);
  673. }
  674. function xhr(url, callfunc, type, lastdate){   
  675.     type = type || 'get';
  676.     var xhr = new XMLHttpRequest();
  677.     xhr.url = url;  //For page checking.
  678.     xhr.onreadystatechange = function(){       
  679.         if(xhr.readyState == 4)
  680.             callfunc(xhr);
  681.     }
  682.     xhr.open(type, url, true);
  683.     if(lastdate)
  684.         xhr.setRequestHeader('If-Modified-Since', lastdate);
  685.     xhr.send();
  686. }
  687. //Begin
  688. function init(){
  689.     Box.init();
  690.     Thread.init();
  691.     Frontpage.init();
  692.    
  693.     Box.searchProcess(3);
  694. }
  695. if (document.addEventListener)
  696.     document.addEventListener('DOMContentLoaded', init, false);
  697. else window.addEventListener('load', init, false);
  698. //
  699. })();
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement