// ==UserScript== // @name LDR all-in-one Hatena extension // @namespace http://d.hatena.ne.jp/janus_wel/ // @description add various features with services provided by Hatena, to LDR / Fastladder // @include http://reader.livedoor.com/reader/* // @include http://fastladder.com/reader/* // @version 0.62 // @author janus_wel // @require http://github.com/januswel/jslibrary/raw/master/HTMLTemplate.js // @resource LOCALE_JSON ldr_all-in-one_hatena_extension_locale.json // @resource CSS ldr_all-in-one_hatena_extension.css // @resource HATEBU_COMMENT_TMPL ldr_all-in-one_hatena_extension_hatebu_comment.tmpl // ==/UserScript== /* * Last Change: 2009/11/13 * fix displayHatenaBookmarkComment by @azu_re * * ACKNOWLEDGMENT * this script is based on: * - http://la.ma.la/blog/diary_200610182325.htm * - http://la.ma.la/blog/diary_200707121316.htm * - http://d.hatena.ne.jp/KGA/20070908/1189223454 * - ( http://d.hatena.ne.jp/hatenastar/20070707 ) * - ( http://michilu.com/blog/posts/123/ ) * - http://zeromemory.sblo.jp/article/1230111.html * - http://d.hatena.ne.jp/aki77/20060601/1149184418 * */ ( function () { // settings --- // change below keybinds as you like const KEY_ADD_HATENA_STAR = 'S'; const KEY_HATENA_BOOKMARK_COMMENT = 'C'; const KEY_TOGGLE_COMMENT_FILTER = 'F'; // global constants --- const LOCALE = getLocale(document.location.href); // main --- window.addEventListener( 'load', function () { // add style GM_addStyle(GM_getResourceText('CSS')); // register features sumofHatenaBookmark(); numofHatenaBookmark(); // sumofHatenaStar(); // not work // addHatenaStar(); displayHatenaBookmarkComment(); }, false ); // feature definition --- // assumption const w = unsafeWindow || window; with (w) { // display the sum of bookmarked on the feed by はてなブックマーク function sumofHatenaBookmark() { channel_widgets.add( 'sum_of_HatenaBookmark', function (feed) { var link = feed.channel.link; var hatenaBookmark = { url: 'http://b.hatena.ne.jp/entrylist?url=' + link, counter: 'http://b.hatena.ne.jp/bc/' + link, }; return ; }, LOCALE.SUMOF_HATENA_BOOKMARK_DESC ); } // display the number of bookmarked on the entry by はてなブックマーク function numofHatenaBookmark() { entry_widgets.add( 'number_of_HatenaBookmark', function (feed, item) { var link = item.link.replace(/#/g,'%23'); var hatenaBookmark = { url: 'http://b.hatena.ne.jp/entry/' + link, counter: 'http://b.hatena.ne.jp/entry/image/' + link, }; return ; }, LOCALE.NUMOF_HATENA_BOOKMARK_DESC ); } // display the sum of はてなスター on the feed /* not work function sumofHatenaStar() { function _onload(r) { // nothing to do, if data is not exist if (r.status !== 200) return; // use "call" to avoid below error // function eval must be called directly, // and not by way of a function of another name // refer: http://d.hatena.ne.jp/brazil/20060821/1156164845 var s = JSON.parse(r.responseText) // wait for nodes that inserted by channel_widgets.add ( below ) // probably, interval will finish by first timing // (speed to operate DOM vs. to connect Hatena server) var id = this.id; var count = 0; const TIMEOUT_COUNT = 30; var t = setInterval( function () { var node = $(id); if (node) { clearInterval(t); node.textContent = s.star_count; return; } if (++count >= TIMEOUT_COUNT) clearInterval(t); }, 100); } channel_widgets.add( 'sum_of_HatenaStar', function (feed) { var hatenaStar = { url: 'http://s.hatena.ne.jp/blog.json/' + feed.channel.link, id: 'hs-' + feed.subscribe_id, }; // get wrapped function and run immediately wrapSecurely(function () { GM_xmlhttpRequest({ method: 'GET', url: hatenaStar.url, onload: bind(_onload, hatenaStar), }); })(); return - ; }, LOCALE.SUMOF_HATENA_STAR_DESC ); } */ // display and add はてなスター to entry. /* not work function addHatenaStar() { includeHatenaStar(); var t = setInterval( function() { if (Hatena) { clearInterval(t); initHatenaStar(); } }, 100 ); function includeHatenaStar() { var s = document.createElement('script'); s.type = 'text/javascript'; s.charset = 'UTF-8'; s.src = 'http://s.hatena.ne.jp/js/HatenaStar.js'; document.getElementsByTagName('head')[0].appendChild(s); } function initHatenaStar() { var s = Hatena.Star; s.EntryLoader.headerTagAndClassName = ['h2', 'item_title']; Keybind.add(KEY_ADD_HATENA_STAR, function(){ // the error "not enough argument" occur var stars = new s.EntryLoader(); }); } } */ function displayHatenaBookmarkComment() { // prepare HTML Template const ht = HTMLTemplateFactory(GM_getResourceText('HATEBU_COMMENT_TMPL')); // display Hatena Bookmark comments Keybind.add( KEY_HATENA_BOOKMARK_COMMENT, function () { var item = get_active_item(true); if (!item) return; var url = 'http://b.hatena.ne.jp/entry/json/' + item.link; orderToNakaNoHito('loading'); wrapSecurely(function () { GM_xmlhttpRequest({ method: 'GET', url: url, onload: bind(_onload, item), }); })(); } ); // order naka-no-hito function orderToNakaNoHito(state) { switch (state) { case 'loading': $('loadicon').src = '/img/icon/loading.gif'; message(LOCALE.HATEBU_COMMENT_LOADING); break; case 'complete': var n = 1 + Math.floor(Math.rand(3)); $('loadicon').src = '/img/icon/rest' + n + '.gif'; message(LOCALE.HATEBU_COMMENT_COMPLETE); break; default: break; } } function _onload(r) { var itemNode = $('item_body_' + this.id); if (!itemNode) return; // if no bookmarks, r will be "null" ( Hatena return string "(null)" ) var bookmarksNode = (r.status !== 200) ? buildBookmarksNode(null) : buildBookmarksNode(JSON.parse(r.responseText)); // remove inserted elements previously var l = itemNode.lastChild; if (l.className === 'hatebu_container') l.parentNode.removeChild(l); // remove unnecessary breaks and spaces, and insert !! itemNode.innerHTML += bookmarksNode.toXMLString().replace(/\n\s+/g, ''); orderToNakaNoHito('complete'); } // just pack data function buildBookmarksNode(hatena) { var noData = !hatena || !hatena.bookmarks || (hatena.bookmarks.length <= 0); if (noData) return ht.output({ title: LOCALE.HATEBU_COMMENT_TITLE, noData: noData, noDataMessage: LOCALE.HATEBU_COMMENT_NODATA, }); // summary of the entry var bookmarks = hatena.bookmarks; var numofAll = parseInt(hatena.count, 10); var numofPublic = bookmarks.length; var numofPrivate = numofAll - numofPublic; var numofComment = numofPublic; // each of bookmark data var bookmarkList = []; for (var i=0, bl=bookmarks.length ; i