// ==UserScript==
// @name             HatebRelated
// @namespace        http://espion.just-size.jp/archives/05/136155838.html
// @include          http://b.hatena.ne.jp/add?*
// @include          http://b.hatena.ne.jp/*/add?*
// ==/UserScript==

// Copyright (c) 2006, Kyosuke Takayama <support@mc.neweb.ne.jp>
// Distributed under the MIT license
// http://www.opensource.org/licenses/mit-license.php
// http://www.opensource.jp/licenses/mit-license.html

function main() {
   var url = getUrl();
   if(url == '') return;

   var base = 'http://b.hatena.ne.jp/entrylist?mode=rss&sort=hot&threshold=3&url=';
   var request = base + url;

   var list = new Rss2List({
      rss: request,
      num: 20,
      callback: makeList
   });
   list.parse();
}

function getUrl() {
   const map = new RegExp(/.hatena.ne.jp|blog.livedoor.jp/i)

   window.location.href.match(/\&url=(.+)&?/);
   var url  = decodeURIComponent(RegExp.$1);
   var list = url.split('/');
   var result  = list[0] + '//' + list[2] + '/';

   if(/\~/.test(list[3]) || map.test(list[2]))
      result += list[3];

   return result;
}

function makeList(list) {
   var div = document.createElement('div');

   with(div.style) {
      margin  = '3px';
      padding = '5px';
      border  = '2px solid #999999';
      textAlign = 'left';
   }

   if(list.constructor == String) {
      div.appendChild(document.createTextNode(list));
      document.body.appendChild(div);
      return;
   }

   var item;
   var w = '';

   list.forEach(function(item) {
      var link = item('link').replace('#', '%23');
      w += '<li>'+
      '<a target="_blank" href="' + item('link') + '">' + item('title') + '</a> - '+
      '<a target="_blank" href="http://b.hatena.ne.jp/entry/'+link+'">' +
      '<img src="http://b.hatena.ne.jp/entry/image/normal/'+link+'" border="0">'+
      '</a>' +
      '</li>';
   });

   var ol = document.createElement('ol');
   ol.innerHTML = w;

   div.appendChild(ol);
   document.body.appendChild(div);
}

var Class = {
   create: function() {
      var newClass = function() {
         this.initialize.apply(this, arguments);
      }
      newClass.prototype.initialize = function() {}
      return newClass;
   }
};

Function.prototype.extend = function(newClass) {
   var proto = this.prototype;
   for(var property in newClass)
      proto[property] = newClass[property];
}

Function.extend({
   bind: function(base) {
      var self = this;
      return function() {
         self.apply(base, arguments);
      }
   }
});

var FEEDParser = Class.create();

FEEDParser.extend({
   initialize: function(data) {
      this.feeds = data;
      this.count = 0;
      this.items = [];
   },

   parse: function() {
      try {
         var wrap   = new XPCNativeWrapper(window, 'DOMParser()');
         var parser = new wrap.DOMParser();
         this.head  = parser.parseFromString(this.feeds, 'application/xhtml+xml');
         this.items = this.head.getElementsByTagName('item');
      } catch(e) {
         throw 'parse error';
      }
   },

   header: function(param) {
      return this.head.getElementsByTagName(param);
   },

   reset: function() {
      this.count = 0;
   },

   next: function() {
      var item = this.items[this.count];
      if(!item) return undefined;

      var ret = function(param) {
         var l = item.getElementsByTagName(param);
         if(l[0]) return l[0].firstChild.nodeValue;
      }

      this.count++;

      return ret;
   }
});

var Rss2List = Class.create();

Rss2List.extend({
   initialize: function(arg) {
      this.num = arg.num || 20;
      this.url = arg.rss;
      this.callback = arg.callback;
   },

   parse: function() {
      GM_xmlhttpRequest({
         method:  'GET',
         url:     this.url,
         onload:  this.onSuccess.bind(this),
         onerror: this.onError.bind(this)
      });
   },

   onSuccess: function(resp) {
      if(!resp.responseText)
         return this.onError();

      this.nodes = new FEEDParser(resp.responseText);
      try {
         this.nodes.parse();
      } catch(e) {
         this.onError();
         return;
      }
      this.create();
   },

   onError: function() {
      this.callback('Load Error');
   },

   create: function() {
      this.nodes.reset();

      var item;
      var i = 0;
      var list = new Array();

      while(item = this.nodes.next()) {
         list.push(item);
         if(i++ && i >= this.num) break;
      }

      if(list.length) {
         this.callback(list);
      } else {
         this.callback('Not Found...');
      }
   }
});

main();


