// ==UserScript==
// @name          F+?B
// @namespace     http://a-h.parfe.jp/einfach/
// @description   show ?B count in FeedBringer
// @include       http://feedbringer.net/feed
// ==/UserScript==

(function() {
	function waitHbCount() {
		if (unsafeWindow.hbCountLoad != true) {
			window.setTimeout(waitHbCount, 100);
		} else {
			enableTooltips();
		}
	}
	
	var maxHeight = 400;
	var tstyle = 'div.tooltip { width: 350px; overflow-y:auto; border: none; background-color: #fff; text-align: left; padding: 0;}.caption {   font-size: 90%;   padding:5px;}span.timestamp {  font-size: 90%;}div.bookmarklist{  border: solid 1px #666;}div.bookmarklist ul {  border-top: 1px solid #5279E7;  background-color: #edf1fd;  list-style-type: none;  padding: 5px;  margin: 0px;  list-style-type: circle;  list-style-position: inside;  font-size: 90%;  line-height: 150%;}div.bookmarklist ul li img{vertical-align:middle;margin-right:2px;border:none;}}';
	var icon = "data:image/gif;base64,R0lGODlhDQAPAPeIAABQ6tvm%2FwpQ%2F0B2%2F%2BLq%2F2mU%2F8zb%2Fyxo%2F2uV%2F4Wo%2FwVQ9VOE%2F%2B7z%2F7zP%2F6zE%2F8va%2F1mI%2F8LT%2FyFg%2F2CO%2FxJV%2F7nN%2Fxxd%2F6a%2F%2Fz10%2F6nC%2F5Kx%2F6nB%2F6G8%2F7TJ%2F9zm%2F%2BDp%2F%2Fb5%2F5Cv%2F4ep%2F0d7%2F%2B3y%2FwRQ8cjY%2F566%2F8nZ%2Fw9T%2F1KD%2F2CN%2F%2Bbt%2Fy9r%2F7fM%2F4%2Bv%2F9%2Fo%2F0F3%2F9fi%2Fxpc%2F7jM%2FxZY%2F9Tg%2Fy1p%2F8TV%2F4us%2F2ya80h9%2F9Lf%2F5m2%2F%2BHq%2F8LU%2F3mj9Had%2Fypn%2F7bL%2F2qV%2F9jj%2F4qr%2F5i2%2F2KP%2F4uv9WOQ%2F8ra%2Fe%2Fz%2F4Cm%2BHCZ%2F0Z7%2F0%2BB%2F0l9%2F4ap%2F83b%2F42x9QtR%2F6O9%2Fzhx%2F7%2FR%2F%2FT3%2F4Km%2F3if%2F5W0%2F8HS%2FyRj%2F1yK%2F%2BTs%2F3uh%2F%2Brw%2F9rk%2Fzpy%2F8bX%2F6G%2B93yi%2F%2FP2%2F7TM%2Bc%2Fd%2Fx5e%2F3Ka%2F5Oy%2F63F%2Fx1e%2Fz92%2FwtQ%2F9Xi%2B4Gl%2F5q3%2F46u%2Fz51%2F%2BXs%2FzRu%2F8fX%2F1SF%2F6K8%2Fw1Z6g5T%2F%2FD0%2FwRQ8vv8%2F9rl%2F5%2B6%2FwRQ9AxR%2FwBQ6U2A%2F0d8%2F%2F%2F%2F%2FwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH%2FC05FVFNDQVBFMi4wAwEAAAAh%2BQQFAACIACwAAAAADQAPAAAIhAARCRxIsCAiHBiqKACgw2AOChQELDRT0ISXPjMk8jG4QMIBQiGWyBFIgIDAGHaE9BiYZUwADwIHwCETYCCIBwYMCFwAZYCDgQE65HkgsEAUJE9osJiiwYWDCAKLfNnhpMAWKRnadGAwcAOCCVrCcAlxQSfBAAlEnDmyR4zBt3DjyhUYEAAh%2BQQFAACIACwBAAEACwALAAAIegARIVKzoMWaNxiwCERE58qBGxYsCIjTBBGPEQcGSKiRQsAfAGmIDFCBR5ANIyUKAQCiZMWIDQuTUBEIAYKeDwtzBmEzocFCJj4EJkAgooAJEjAieJAB5sMcBBrqnHCD4kcAEIgqvEhwgUOFIWUILLxjJQOHBl3QCAwIACH5BAUAAIgALAEAAQALAAsAAAh5ABEhKlJgwYAYC1AIRLThSxQocOxI8JIDUSAEO5AMICPkQB8KOBJMcPLEQYAeKWZQwCBCSwEaC0MIEFDlTJgtLBYuUcDzCBcpUxbK4QMAwJ4QGTQEAJFFoBkdYi60cdHhwRg%2FCxEZ6OAgj4EABLIiYhDhgQEPYQUGBAAh%2BQQFAACIACwBAAEACwALAAAIfQARIfqQIAgEJUR4CERUYQ4CNhBWDBhBB9GdFwhETNAzQsWBK2qsJNBQoMGHDXgGHFCR4UIdEwtPSLjRggOHEyQW2qhhYU2DCm5gLDSSwsKbLkNQRGCCKEmJOAIwoCnzw4MPRFQAlBCABRGBADJyIgIAoMlCEGAYCASSRmBAACH5BAUAAIgALAEAAQALAAsAAAh7ABEhErPnyBkRCQIIRGTgQgguYbRMQLABEYMObTJI2VLAyY4vRSI4cKFhCgsaT5BEKfAgTweFAh0MgLLAgIEHIBYGIANngIcAY7Is7CHETgwCBPwgkrMkhIADEhYAYiCQjwIBM%2Fp4MbHQDICrFCjkWIhIB4BBVTDgEBgQACH5BAUAAIgALAEAAQALAAsAAAh7ABEhQtOlAYcMVu4IRESgzJAKHC4keFEBEYgAP1C4OVFHA4I5H8DI8BABBgkTBUQgSMCAhA8mCxtMYBNkoc0PeiBAEEglycINI1YoAQIAQAkjNgThUTGASBoAfwSkqCFhwIERPBA1iSPAgoUbB67QWYgFw5s1LRaoERgQACH5BAUAAIgALAEAAQALAAsAAAh6ABEhAkTAg4EHERgIFMiAQAADeRx0MLAQkZ8xDzq4aHNBjA4zArOACKAhQ4g9AADwkbNwihQuRxTIXLKQxZYwZ6oIEBBiIY0CWkRgoDBDQI8ADp44mZAAB4UUB4SQGYBkB4JAiHJ4kWAHDpQoXzYsRLEgxoAFBYoIDAgAIfkEBQAAiAAsAQABAAsACwAACH0AESFKA0QgAzAgBCJqAgCAQBIyAhBAhEVACQBUEPnw8KMMGgwC4pRIgohJBBRDuryxkMKIQhhuKjRYY6GGDYUkTnDg0OKGhBMKTdS5kEHFgQF4NnxoUEBDAitqrhwwdEjPBBEIXtxBRGfEgBUQ2CCYU0EhDyJKIARJ8EFgQAA7";
	var now;
	var element;

	function request(e, ele) {
		var url = getUrl(ele).replace('#','%2523');
		if (url == now) return;
		now = url;
		var position = [e.pageY, e.pageX];
		
		if (ele.tooltip.innerHTML != '') {
			showTooltip(position, ele);
			return;
		}
		
		var img = document.createElement('img');
		img.src = icon;
		img.style.verticalAlign = 'bottom';
		img.style.border = 'none';
		img.style.backgroundColor = '#fff';
		ele.appendChild(img);
		
		GM_xmlhttpRequest({
			method: 'GET',
			url   : 'http://r.hatena.ne.jp/entry/bcomment?entryurl=' + url + '&amp;flag=1',
			headers: {'User-Agent': 'Mozilla/4.0 (compatible) Greasemonkey',
					  'Content-type': 'application/x-www-form-urlencoded'},
			onload:function(response){
				var r = response.responseText;
				ele.removeChild(ele.lastChild);
				ele.tooltip.innerHTML = r;
				showTooltip(position, ele);
			}
		});
	}

	function getUrl(ele) {
		var index = ele.href.indexOf('entry/');
		return ele.href.substr(index + 6);
	}

	function enableTooltips() {
		addCss();
		element = document.createElement('span');
		element.style.position = 'absolute';
		document.getElementsByTagName('body')[0].appendChild(element);
		
		var links = document.evaluate('//a[@class="hbusers"]', document, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null);
		if (!links.snapshotLength) return;
		for (i = 0; i < links.snapshotLength; i++) {
			Prepare(links.snapshotItem(i));
		}
		
		document.addEventListener('click', function() {
			hideTooltip();
			now = null;
		}, false);
	}

	function Prepare(el){
		var tooltip = CreateEl('div', 'tooltip');
		setOpacity(tooltip);
		el.tooltip = tooltip;
		el.addEventListener('mouseover', function(e) {
			request(e, el);
		}, false);
	}

	function showTooltip(position, el){
		hideTooltip();
		element.appendChild(el.tooltip);
		element.style.top = (position[0] + 10) + 'px';
		element.style.left = (position[1] - 160) + 'px';
		
		if (el.tooltip.offsetHeight > maxHeight) {
			el.tooltip.style.height = maxHeight + 'px';
		}
	}

	function hideTooltip(e){
		if (element.childNodes.length > 0) element.removeChild(element.firstChild);
	}

	function setOpacity(el){
		el.style.filter = 'alpha(opacity:95)';
		el.style.KHTMLOpacity = '0.95';
		el.style.MozOpacity = '0.95';
		el.style.opacity = '0.95';
	}

	function CreateEl(t, c){
		var x = document.createElement(t);
		x.className = c;
		x.style.display = 'block';
		return(x);
	}

	function addCss(){
		var style = document.createElement('style');
		style.type = 'text/css';
		style.innerHTML = tstyle;
		document.getElementsByTagName('head')[0].appendChild(style);
	}

  function setBookmarkCount(link, count) {
    var a = document.createElement("a");
    a.setAttribute("href", "http://b.hatena.ne.jp/entry/"+link.href);
    a.appendChild(document.createTextNode(""+count+" user"+(count>1?"s":"")));
    a.className = "hbusers";  // 
    with (a.style) {
      fontSize = "0.9em";
      textDecoration = "none";
      if (count >= 5) {
        fontWeight = "bold";
        backgroundColor = "#fff0f0";
        color = "#f66";
      }
      if (count >= 10) {
        backgroundColor = "#ffcccc";
        color = "red";
      }
    }
    var point = link.nextSibling.nextSibling.nextSibling.nextSibling.nextSibling;
    link.parentNode.insertBefore(a, point);
    link.parentNode.insertBefore(document.createTextNode(" "), point);
  }
  function callXmlrpc(requestbody, url2link) {
    const endpoint = "http://b.hatena.ne.jp/xmlrpc";
    function onload(response) {
      var pattern = /<name>([^<]+)<\/name>\s*<value><int>(\d+)/g;
      var m;
      while (m = pattern.exec(response.responseText)) {
        var link = url2link[m[1]];
        if (link && m[2] > 0) setBookmarkCount(link, m[2]);
      }
      unsafeWindow.hbCountLoad = true;
      waitHbCount();
    }
    GM_xmlhttpRequest({method: "POST", url: endpoint, data: requestbody, onload: onload});
  }
unsafeWindow.FeedBringer.executeOnclick = function(element) {
    var uw = unsafeWindow;
    var $ = uw.$;

    element = $(element);
    if (element && element.onclick) {
        element.onclick();
    }

    var links = uw.document.evaluate('//a[@class="feed-entry-title"]', document, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null);
    if (!links.snapshotLength) return;
    var request = '<?xml version="1.0"?>\n<methodCall>\n<methodName>bookmark.getCount</methodName>\n<params>\n';
    var url2link = new Array(links.snapshotLength);
    String.prototype.htmlescape = function() {
      return this.replace(/&/, "&amp;").replace(/</g, "&lt;");
    }
    for (var i = 0; i < links.snapshotLength; ++i) {
      var link = links.snapshotItem(i);
      request += "<param><value><string>"+link.href.htmlescape()+"</string></value></param>\n";
      url2link[link.href] = link;
    }
    request += "</params>\n</methodCall>\n";
    callXmlrpc(request, url2link);
};

})();

