// ==UserScript==
// @name        No Meta Redirect (for Opera 9)
// @version     2.10
// @date        2007-03-13
// @author      Mike Samokhvalov <mikivanch@gmail.com>
// @description Prevent "meta refresh" redirection 
// @download    http://www.puzzleclub.ru/files/no_meta_redirect.js
// ==/UserScript==

(function(){

  if(typeof(opera.version) != 'function' || opera.version() < 9)
    return;
    
  var blockFile = new Array(
    'exe','com','scr',
    'zip','rar','arj','gz','gzip','tgz','bz2','tar',
    'avi', 'mpeg', 'mpg', 'mp4', 'wmv','mov','rv',
    'mp3','flac','ape','wma','ra','ram',
    'doc','pdf','rtf','xls','ppt'
  );
  
  var skipFile = new Array();
    
  var hash = '#ujs_no_meta_redirect';
  var page = '404.html';
  var msgPrefix = 'ujs_no_meta_redirect_msg';
  var frameId = 'ujs_no_meta_redirect_frame';
  
  var bFrame = false;
  try
  {
    if(window.parent != window)
    {
      bFrame = true;
    }
  }
  catch(e)
  {
    bFrame = true;
  }   
  
  if(bFrame && window.location.hash.indexOf(hash) == 0)
  {
    var prevent = function(e) {
      e.preventDefault();
    };
    
    window.opera.addEventListener('BeforeEventListener.DOMContentLoaded', prevent, false);
    window.opera.addEventListener('BeforeEventListener.load', prevent, false);
    window.opera.addEventListener('BeforeEventListener.message', prevent, false);
    window.stop();    
    
    var url = window.location.hash.substr(hash.length);
    url = decodeURIComponent(url); 

    var xmlhttp = new XMLHttpRequest();
    xmlhttp.open("HEAD", url, true);      
    xmlhttp.onreadystatechange = function() {
      if(this.readyState == 4)
      {
        var hdr = this.getAllResponseHeaders();
        if(hdr)
        {
          var msg = msgPrefix + '\n' + url + '\n' + encodeURIComponent(hdr);
          window.parent.document.postMessage(msg);
        }
      }
    };
    xmlhttp.send();
        
  }
  else
  {     
    var getUrlInfo = function(url, protocol, host)
    {
      if(!url)
        return;
        
      if(protocol != 'http:')
      {
        showRedirectionInfo(url, 'Not an HTTP URL', '', '');
        return;
      }
        
      if(document.location.host != host) // external
      {
        showRedirectionInfo(url, '', '', '');
        var d = protocol + '//' + host + '/';
        var f = document.createElement('iframe');
        f.src = d + page + hash + encodeURIComponent(url);
        f.id = frameId;
        f.width = 0;
        f.height = 0;
        f.frameBorder = 'no';
        f.scrolling = 'no';
        document.documentElement.appendChild(f);
      }
      else    
      {
        var xmlhttp = new XMLHttpRequest();      
        xmlhttp.open("HEAD", url, true);      
        xmlhttp.onreadystatechange = function() {
          if(this.readyState == 4)
          {
            var size = this.getResponseHeader("Content-Length");               
            size = formatSize(size);
              
            var info = '', sep = '';  
            var date = this.getResponseHeader("Last-Modified");
            if(date)
            {
              info += date;
              sep = ' | ';
            }
              
            var type = this.getResponseHeader("Content-Type");
            if(type)
            {
              info += sep + type;
              sep = ' | ';
            }
              
            var hdr = this.getAllResponseHeaders();
            hdr = hdr.replace(/\r/g, '');
            hdr = hdr.replace(/\n/g, '\\n');
            hdr = hdr.replace(/\x22/g, '\\x22');
            hdr = hdr.replace(/\x27/g, '\\x27');
            
            showRedirectionInfo(url, size, info, hdr);
          }
        };
        xmlhttp.send();
      }
    };
    
    var showRedirectionInfo = function(url, size, info, hdr)
    {
      if(!document.body)
        return;        
        
      var html = '<table id="ujs_no_meta_redirect_tbl"><tr>';
      html += '<td id="ujs_no_meta_redirect_hdr">Meta&nbsp;Redirection</td>';
      html += '<td id="ujs_no_meta_redirect_cnt">';
      html += '<a href="' + url + '" title="' + info + '">' + url + '</a>';
      
      var param = '', sep = '';
      if(size)
      {
        param += size;  
        sep = ' | ';
      }
      
      if(hdr)
        param += sep + '<a href="javascript:void(0);" onMouseUp="alert(\'' + hdr + '\');">HTTP Headers</a>';
        
      if(param)  
        html += '&nbsp;&nbsp; ( ' + param + ' )';
        
      html += '</td></tr></table>';  
        
      var id = 'ujs_no_meta_redirect_panel';
      var panel = document.getElementById(id);
      if(panel)
        panel.innerHTML = html;
      else
      {      
        var css = (
          '#' + id + '{color: #000; background: d3e7c7; border: 1px solid #7ab758; margin: 0 0 10px 0 !important; padding: 0 !important; display: block;}'
          +'#ujs_no_meta_redirect_tbl{color: #000; background: transparent; border: none; border-collapse: collapse; padding: 0 !important; margin: 0 !important;}'
          +'#ujs_no_meta_redirect_tbl td{border: none; font-family: verdana, arial, helvetica, sans-serif; line-height: normal; text-align: left; vertical-align: middle; padding: 3px 10px;}'
          +'#ujs_no_meta_redirect_hdr{color: #fff; background: #7ab758; font-size: 14px; font-weight: bold;}'
          +'#ujs_no_meta_redirect_cnt{color: #000; background: #d3e7c7; font-size: 11px; width: 100%;}'
          +'#ujs_no_meta_redirect_cnt a:link, #ujs_no_meta_redirect_cnt a:visited{color: #cf0000; background: inherit; border: none; text-decoration: underline; display: inline;}'
          +'#ujs_no_meta_redirect_cnt a:active, #ujs_no_meta_redirect_cnt a:hover{color: #005000; background: inherit; border: none; text-decoration: underline; display: inline;}'
        );  
    
        var s = document.createElement('style');
        s.setAttribute('type', 'text/css');
    		s.setAttribute('style', 'display:none !important;');			
    		s.appendChild(document.createTextNode(css));
        document.documentElement.appendChild(s);
      
        var div = document.createElement("div");
        div.id = id;
        div.innerHTML = html;
        document.body.insertBefore(div, document.body.firstChild);
        document.body.style.margin = '0';
      }
    };
    
    var removeMetaRefresh = function()
    {    
      var bRedirect = false;
      var meta = document.getElementsByTagName('meta');
      if(meta.length > 0)
      {      
        var url = '', protocol = '', host = '';
        for(var i = 0; i < meta.length; i++)
        {
          var a = meta[i].getAttribute('http-equiv', false);
          if(a)
          {
            a = a.toLowerCase();
            if(a == 'refresh')
            {
              var c = meta[i].getAttribute('content', false);
              if(c)
              {
                c = c.replace(/^[\w\s;]*url=/i, '');
                var block = false;
                
                var anchor = document.createElement('a');                
                anchor.setAttribute('style', 'display:none !important;');		
                anchor.href = c;  
                document.documentElement.appendChild(anchor);    
                
                if(blockFilter && anchor.pathname.search(blockFilter) != -1)                
                  block = true;
      
                if(skipFilter && anchor.pathname.search(skipFilter) == -1)                
                  block = true;
                
                if(block)
                {
                  bRedirect = true;
                  if(!url)
                  {
                    url = anchor.href;
                    protocol = anchor.protocol;
                    host = anchor.host;
                  }
                  meta[i].setAttribute('http-equiv', '', false);
                  meta[i].setAttribute('content', '', false);
                }
                
                anchor.parentNode.removeChild(anchor);
              }
            }
          }
        }
        
        if(bRedirect)
        { 
          var html = document.documentElement.outerHTML;        
          document.open();         
          document.write(html + '</html>');
          getUrlInfo(url, protocol, host);
        }
      }
    };
    
    var formatSize = function(size)
    {
      if(!size)
        return 'unknown';
      
      var s = parseInt(size);
      if(isNaN(s))
        return 'unknown';
        
      if(s < 0x400)
        s += ' B';
      else
      {    
        var u = '';
        if(s < 0x100000)
        {
          s = s / 0x400;
          u = 'KB';
        }
        else if(s < 0x40000000)
        {
          s = s / 0x100000;
          u = 'MB';
        }
        else
        {
          s = s / 0x40000000;
          u = 'GB';
        }
        
        s = (Math.round(s * 100)) / 100;
        s += ' ' + u;
      }
      return s;
    };
    
    document.addEventListener('message', function(e){
      if(e.data && (e.data.indexOf(msgPrefix) == 0))
      { 
        var d = e.data.split('\n');
        if(d.length == 0)
        {
          return false;
        }      

        if(d[0] == msgPrefix)
        {
          var url = '', hdr = '';
          if(d.length > 1)
            url = d[1];
          if(d.length > 2)
            hdr = decodeURIComponent(d[2]);
            
          if(url && hdr)  
          {
            var size = hdr.match(/Content-Length:([^\r\n]+)/i);
            if(size && size.length > 1)
              size = size[1];
            else size = '';
              
            size = formatSize(size);
                
            var info = '', sep = '';  
            var date = hdr.match(/Last-Modified:([^\r\n]+)/i);
            if(date && date.length > 1)
            {
              info += date[1];
              sep = ' | ';
            }
              
            var type = hdr.match(/Content-Type:([^\r\n]+)/i);
            if(type && type.length > 1)
            {
              info += sep + type[1];
              sep = ' | ';
            }
            
            hdr = hdr.replace(/\r/g, '');
            hdr = hdr.replace(/\n/g, '\\n');
            hdr = hdr.replace(/\x22/g, '\\x22');
            hdr = hdr.replace(/\x27/g, '\\x27');
            
            showRedirectionInfo(url, size, info, hdr);
          }
          
          var frame = document.getElementById(frameId);
          if(frame)      
          {
            frame.parentNode.removeChild(frame);
          }
        }
      }
    }, false);
    
    var getFileFilter = function(files)
    {    
      if(!files)
        return null;

      var f = '', sep = '';
      for(var i in files)
      {
        f += sep + '\\.' + files[i] + '$';
        sep = '|';        
      }

      return new RegExp(f, "i");
    };
    
    var blockFilter = getFileFilter(blockFile);
    var skipFilter = getFileFilter(skipFile);    
    
    document.addEventListener('DOMContentLoaded', removeMetaRefresh, false);
  }
})();