メタブ表示
by
lieutar
2016-08-15 [2016/08/15 20:22:44]
メタブ表示
@@ -1,5 +1,5 @@
/*
- * @titleブクマカのメタブ表示
+ * @title ブクマカのメタブ表示
* @description my bookmarklet
* @include http://b.hatena.ne.jp/entry/*
* @license MIT License
@@ -9,104 +9,225 @@
/*
* CONSTANTS
*/
- var DEBUG = true;
- var HBBP_URL = "http://b.hatena.ne.jp/js/bookmark_blogparts.js";
+ var DEBUG = true;
+ var HBBP_URL = "http://b.hatena.ne.jp/js/bookmark_blogparts.js";
+ var HATEB_DOMAIN = "http://b.hatena.ne.jp";
+ var API_DOMAIN = "//b.hatena.ne.jp";
+ var ICON_DOMAIN = "http://cdn1.www.st-hatena.com/users/";
+ var CSS = [
+ '.metab-container {',
+ '}',
+ '.metab-container > .metab-count{',
+ ' font-size: 10px;',
+ ' font-weight: 900;',
+ ' color: #F00;',
+ ' background-color: #FCC;',
+ ' display: inline-block;',
+ ' text-decoration: none;',
+ ' line-height: 12px;',
+ ' padding: 2px;',
+ '}',
+ '.metab-container > ul{',
+ ' display: block;',
+ ' margin: 0px;',
+ ' padding: 0px;',
+ '}',
+ '.metab-container > ul > li{',
+ ' width: auto;',
+ ' margin: 0px;',
+ ' padding: 0px;',
+ ' display: block;',
+ ' list-style: none;',
+ '}',
+ '.metab-container > ul > li > a.username{',
+ ' display: inline-block;',
+ ' margin: 0px 11px;',
+ '}',
+ '.metab-container > ul > li > span.comment{',
+ ' font-size: 11px;',
+ '}',
+ ''].join("\n");
+
//////////////////////////////
+ var doc = document;
+ var win = window;
+ var loc = location;
+
- var p = function() {
+ var p = function p() {
if ( !DEBUG ) return;
console.log.apply(console, arguments);
};
- var forEach = function(a,f){
+ var forEach = function forEach(a,f){
if(!a) return;
for (var i=0,l=a.length;i<l;i++){
if(f(a[i]) === false) break;
}
};
+ var gensym = (function(){
+ var rnd = function(){return Math.floor(Math.random() * (1<<30)).toString(16);};
+ var cnt = 0;
+ var prefix = 'sym_' + Date.now().toString(16) + '_' + rnd() + '_';
+ return function gensym(){ return prefix + (cnt++).toString(16); };
+ })();
+
+ var receiver = function(cb){
+ var name = gensym();
+ var func = function(){
+ delete win[name];
+ cb.apply(this, arguments);
+ };
+ win[name] = func;
+ return encodeURIComponent( name );
+ };
+
+
//////////////////////////////
- var targets = {};
+ var users = {};
- var insert = function(container, url){
- var h = HBBlogParts;
- var sel = 'a[href="'+targets[url]+'"]';
- forEach( document.querySelectorAll('ul.bookmark-list'), function(li){
- var target = li.querySelector(sel);
- if(!target) return;
- var parent = target.parentNode;
- parent.appendChild(container);
- });};
-
- var catchJsonMetab = function(entry){
- var h = HBBlogParts;
- if ( !entry ){
- //p('No Bookmarks');
- }else{
- var container = new h.BookmarkContainer(entry);
- if( h.isPermalinkPage() ) {
- container.commentLimit = h.permalinkCommentLimit;
- } else {
- container.commentLimit = h.listPageCommentLimit;
+
+ /*/
+ hoge:(
+ {"count":2,
+ "bookmarks":[
+ {"timestamp":"2016/06/24 18:41:59",
+ "comment":"","user":"aflat_1000dai4","tags":["meta bookmark"]},
+ {"timestamp":"2014/11/27 23:31:08",
+ "comment":"","user":"kcolmun",
+ "tags":["\u30e1\u30bf\u30d6\u30c3\u30af\u30de\u30fc\u30af"]}],
+ "url":"http://b.hatena.ne.jp/guru_guru/",
+ "eid":234900219,
+ "title":"\u306f\u3066\u306a\u30d6\u30c3\u30af\u30de\u30fc\u30af - guru_guru \u306e\u30d6\u30c3\u30af\u30de\u30fc\u30af",
+ "screenshot":"http://screenshot.hatena.ne.jp/images/200x150/7/7/5/1/8/4cdd713947a7e5c74bf0b8244024e6ea7ae.jpg",
+ "entry_url":"http://b.hatena.ne.jp/entry/b.hatena.ne.jp/guru_guru/"}
+ )
+ //*/
+
+
+ var htmlifyComment = function(comment){
+ var node = doc.createElement('span');
+ node.className = 'comment';
+ node.appendChild(doc.createTextNode(comment));
+ return node;
+ };
+
+ var toHTML = function(entry, user){
+ var slot = users[user];
+ var node = slot.html || null;
+ if(!node){
+ node = doc.createElement('div');
+ if(entry){
+ node.className = 'metab-container';
+ var count = doc.createElement('a');
+ count.className = 'metab-count';
+ count.href = entry.url;
+ count.target = "_blank";
+ count.appendChild(doc.createTextNode(String(entry.count) + " users"));
+ node.appendChild(count);
+ if((entry.bookmarks || []).length > 0){
+ var ul = doc.createElement('ul');
+ forEach(entry.bookmarks, function(bm){
+ var li = doc.createElement('li');
+ var a = doc.createElement('a');
+ a.href = HATEB_DOMAIN + '/' + bm.user + '/';
+ a.target = '_blank';
+ a.title = bm.user;
+ var un = a.cloneNode(true);
+ a.className = 'profile-icon';
+ un.className = 'username';
+ var icon = doc.createElement('img');
+ icon.src =
+ ICON_DOMAIN + '/' + bm.user.substring(0,2) + '/' + bm.user +
+ '/profile_l.gif';
+ icon.alt = bm.user;
+ a.appendChild(icon);
+ li.appendChild(a);
+ un.appendChild(doc.createTextNode(bm.user));
+ li.appendChild(un);
+
+
+ var tags = bm.tags || [];
+ if(tags.lengh > 0){
+ var tagSpan = doc.createElement('span');
+ tagSpan.className = 'tags';
+ forEach(tags , function(tagName){
+ var tagLink = doc.createElement('a');
+ tagLink.className = 'user-tag';
+ tagLink.href = HATEB_DOMAIN + '/' + bm.user + '/' + tagName;
+ tagLink.appendChild(doc.createTextNode(tagName));
+ tagSpan.appendChild(tagLink);});
+ li.appendChild(tagSpan);}
+
+ li.appendChild(htmlifyComment(bm.comment));
+
+ var meta = doc.createElement('div');
+ meta.className = 'user-comment-meta';
+ var tspan = doc.createElement('span');
+ tspan.className = 'timestamp';
+ meta.appendChild(tspan);
+ tspan.appendChild(doc.createTextNode(bm.timestamp));
+ li.appendChild(meta);
+ ul.appendChild(li);
+ });
+ node.appendChild(ul);
+ }
}
- var url = entry.url;
- insert(container.toHTML(h.Design),url);
- h.setStyles();
- h.shownPermalinks[url] = 1;
+ slot.html = node;
}
- h.catchCount++;
- if( h.catchCount >= h.Entries.length ) h.showEmptyEntries();
+ var retval = node.cloneNode(true);
+ return retval;
};
- var showBookmarkComment = function(uri){
- var h = HBBlogParts;
- var apiEndPoint = h.API_DOMAIN + '/entry/jsonlite/?';
- var request = apiEndPoint + 'url=' + encodeURIComponent(uri) +
- '&callback=HBBlogParts.CatchJsonMetab';
- var scriptTag = Ten.Element('script',{ src: request, type: 'text/javascript'});
- document.body.appendChild(scriptTag);
+ var received = function(user, entry){
+ var slot = users[user];
+ slot.entry = entry || false;
+ slot.cont.forEach(function(c){c(entry, user);});
};
-
-
- var showBlogPart = function(n){
- var h = HBBlogParts;
- var uri = n.href;
- if(targets[uri]) return;
- targets[uri] = n.getAttribute('href');
- showBookmarkComment(uri);
+ var reserve = function(user, cont){
+ p(user);
+ var slot = ( users[user] || (users[user] = {entry: null,cont:[],req: false} ));
+ if(slot.entry !== null){
+ cont(slot.entry, user);
+ return;
+ }
+ slot.cont.push(cont || function(){});
+ if(slot.req) return;
+ slot.req = true;
+ var uri = HATEB_DOMAIN + '/' + user + '/';
+ var apiEndPoint = API_DOMAIN + '/entry/jsonlite/?';
+ var request = apiEndPoint + 'url=' + encodeURIComponent(uri) +
+ '&callback=' + receiver(function(entry){ received(user, entry);});
+ var scriptTag = doc.createElement('script');
+ scriptTag.src = request;
+ scriptTag.type = 'text/javascript';
+ doc.body.appendChild(scriptTag);
};
var main = function(){
- var h = HBBlogParts;
- h.debug = DEBUG;
- h.CatchJsonMetab = catchJsonMetab;
var entries = [];
- forEach(document.querySelectorAll('a.profile-icon'), showBlogPart);};
+ var style = doc.createElement('style');
+ style.type = 'text/css';
+ style.appendChild(doc.createTextNode(CSS));
+ doc.querySelector('head').appendChild(style);
+ forEach(doc.querySelectorAll('a.profile-icon'), function(n){
+ var user = n.href.match(/([^\/]+)\/$/)[1];
+ reserve(user, function(entry, user){
+ n.parentNode.appendChild(toHTML(entry, user));});});};
-
- /*
- * START
- */
+ ////
if((function(pn){
if(pn.match(/^\/entry\/\d+\/comment\//)) return true;
return false;
- })(String(location.pathname))) return;
-
-
- if( typeof HBBlogParts == 'undefined' ){
- var mainjs = document.createElement('script');
- mainjs.src = HBBP_URL;
- document.querySelector('head').appendChild(mainjs);}
-
- (function(){
- if(typeof HBBlogParts == 'undefined'){
- setTimeout(arguments.callee,20);}else{main();}})();
+ })(String(loc.pathname))) return;
+ main();
})();
/*
* @title ブクマカのメタブ表示
* @description my bookmarklet
* @include http://b.hatena.ne.jp/entry/*
* @license MIT License
* @require
*/
(function(){
/*
* CONSTANTS
*/
var DEBUG = true;
var HBBP_URL = "http://b.hatena.ne.jp/js/bookmark_blogparts.js";
var HATEB_DOMAIN = "http://b.hatena.ne.jp";
var API_DOMAIN = "//b.hatena.ne.jp";
var ICON_DOMAIN = "http://cdn1.www.st-hatena.com/users/";
var CSS = [
'.metab-container {',
'}',
'.metab-container > .metab-count{',
' font-size: 10px;',
' font-weight: 900;',
' color: #F00;',
' background-color: #FCC;',
' display: inline-block;',
' text-decoration: none;',
' line-height: 12px;',
' padding: 2px;',
'}',
'.metab-container > ul{',
' display: block;',
' margin: 0px;',
' padding: 0px;',
'}',
'.metab-container > ul > li{',
' width: auto;',
' margin: 0px;',
' padding: 0px;',
' display: block;',
' list-style: none;',
'}',
'.metab-container > ul > li > a.username{',
' display: inline-block;',
' margin: 0px 11px;',
'}',
'.metab-container > ul > li > span.comment{',
' font-size: 11px;',
'}',
''].join("\n");
//////////////////////////////
var doc = document;
var win = window;
var loc = location;
var p = function p() {
if ( !DEBUG ) return;
console.log.apply(console, arguments);
};
var forEach = function forEach(a,f){
if(!a) return;
for (var i=0,l=a.length;i<l;i++){
if(f(a[i]) === false) break;
}
};
var gensym = (function(){
var rnd = function(){return Math.floor(Math.random() * (1<<30)).toString(16);};
var cnt = 0;
var prefix = 'sym_' + Date.now().toString(16) + '_' + rnd() + '_';
return function gensym(){ return prefix + (cnt++).toString(16); };
})();
var receiver = function(cb){
var name = gensym();
var func = function(){
delete win[name];
cb.apply(this, arguments);
};
win[name] = func;
return encodeURIComponent( name );
};
//////////////////////////////
var users = {};
/*/
hoge:(
{"count":2,
"bookmarks":[
{"timestamp":"2016/06/24 18:41:59",
"comment":"","user":"aflat_1000dai4","tags":["meta bookmark"]},
{"timestamp":"2014/11/27 23:31:08",
"comment":"","user":"kcolmun",
"tags":["\u30e1\u30bf\u30d6\u30c3\u30af\u30de\u30fc\u30af"]}],
"url":"http://b.hatena.ne.jp/guru_guru/",
"eid":234900219,
"title":"\u306f\u3066\u306a\u30d6\u30c3\u30af\u30de\u30fc\u30af - guru_guru \u306e\u30d6\u30c3\u30af\u30de\u30fc\u30af",
"screenshot":"http://screenshot.hatena.ne.jp/images/200x150/7/7/5/1/8/4cdd713947a7e5c74bf0b8244024e6ea7ae.jpg",
"entry_url":"http://b.hatena.ne.jp/entry/b.hatena.ne.jp/guru_guru/"}
)
//*/
var htmlifyComment = function(comment){
var node = doc.createElement('span');
node.className = 'comment';
node.appendChild(doc.createTextNode(comment));
return node;
};
var toHTML = function(entry, user){
var slot = users[user];
var node = slot.html || null;
if(!node){
node = doc.createElement('div');
if(entry){
node.className = 'metab-container';
var count = doc.createElement('a');
count.className = 'metab-count';
count.href = entry.url;
count.target = "_blank";
count.appendChild(doc.createTextNode(String(entry.count) + " users"));
node.appendChild(count);
if((entry.bookmarks || []).length > 0){
var ul = doc.createElement('ul');
forEach(entry.bookmarks, function(bm){
var li = doc.createElement('li');
var a = doc.createElement('a');
a.href = HATEB_DOMAIN + '/' + bm.user + '/';
a.target = '_blank';
a.title = bm.user;
var un = a.cloneNode(true);
a.className = 'profile-icon';
un.className = 'username';
var icon = doc.createElement('img');
icon.src =
ICON_DOMAIN + '/' + bm.user.substring(0,2) + '/' + bm.user +
'/profile_l.gif';
icon.alt = bm.user;
a.appendChild(icon);
li.appendChild(a);
un.appendChild(doc.createTextNode(bm.user));
li.appendChild(un);
var tags = bm.tags || [];
if(tags.lengh > 0){
var tagSpan = doc.createElement('span');
tagSpan.className = 'tags';
forEach(tags , function(tagName){
var tagLink = doc.createElement('a');
tagLink.className = 'user-tag';
tagLink.href = HATEB_DOMAIN + '/' + bm.user + '/' + tagName;
tagLink.appendChild(doc.createTextNode(tagName));
tagSpan.appendChild(tagLink);});
li.appendChild(tagSpan);}
li.appendChild(htmlifyComment(bm.comment));
var meta = doc.createElement('div');
meta.className = 'user-comment-meta';
var tspan = doc.createElement('span');
tspan.className = 'timestamp';
meta.appendChild(tspan);
tspan.appendChild(doc.createTextNode(bm.timestamp));
li.appendChild(meta);
ul.appendChild(li);
});
node.appendChild(ul);
}
}
slot.html = node;
}
var retval = node.cloneNode(true);
return retval;
};
var received = function(user, entry){
var slot = users[user];
slot.entry = entry || false;
slot.cont.forEach(function(c){c(entry, user);});
};
var reserve = function(user, cont){
p(user);
var slot = ( users[user] || (users[user] = {entry: null,cont:[],req: false} ));
if(slot.entry !== null){
cont(slot.entry, user);
return;
}
slot.cont.push(cont || function(){});
if(slot.req) return;
slot.req = true;
var uri = HATEB_DOMAIN + '/' + user + '/';
var apiEndPoint = API_DOMAIN + '/entry/jsonlite/?';
var request = apiEndPoint + 'url=' + encodeURIComponent(uri) +
'&callback=' + receiver(function(entry){ received(user, entry);});
var scriptTag = doc.createElement('script');
scriptTag.src = request;
scriptTag.type = 'text/javascript';
doc.body.appendChild(scriptTag);
};
var main = function(){
var entries = [];
var style = doc.createElement('style');
style.type = 'text/css';
style.appendChild(doc.createTextNode(CSS));
doc.querySelector('head').appendChild(style);
forEach(doc.querySelectorAll('a.profile-icon'), function(n){
var user = n.href.match(/([^\/]+)\/$/)[1];
reserve(user, function(entry, user){
n.parentNode.appendChild(toHTML(entry, user));});});};
////
if((function(pn){
if(pn.match(/^\/entry\/\d+\/comment\//)) return true;
return false;
})(String(loc.pathname))) return;
main();
})();
// Local Variables:
// mode: hatena-let
// End:
- Permalink
- このページへの個別リンクです。
- RAW
- 書かれたコードへの直接のリンクです。
- Packed
- 文字列が圧縮された書かれたコードへのリンクです。
- Userscript
- Greasemonkey 等で利用する場合の .user.js へのリンクです。
- Loader
- @require やソースコードが長い場合に多段ロードする Loader コミのコードへのリンクです。
- Metadata
- コード中にコメントで @xxx と書かれたメタデータの JSON です。