はてなキーワード: .Bookとは
数日前に puppeteer で自動で PDF にする試みを書いたブログがホッテントリに入ってるのを見た
bg.js
const username = "" const api_key = "" chrome.runtime.onMessage.addListener((message, sender, sendResponse) => { if(message.bookmark){ bookmark(message.bookmark) } }) async function bookmark(url){ fetch("http://b.hatena.ne.jp/atom/post", { method: "POST", referrer: "no-referrer", headers: { Accept: "application/x.atom+xml, application/xml, text/xml, */*", "X-WSSE": await createCredential(), }, body: ` <entry xmlns="http://purl.org/atom/ns#"> <link rel="related" type="text/html" href="${url}" /> </entry> `.replace(/\t/g, ""), }).then(e => {console.log(e)}) } async function createCredential(){ const non = Math.random().toString(36).substr(2) const now = new Date().toISOString() const buf = new TextEncoder().encode(non + now + api_key) const u8a = new Uint8Array(await crypto.subtle.digest("SHA-1", buf)) const str = Array.from(u8a, e => String.fromCharCode(e)).join("") const b64 = btoa(str) return `UsernameToken Username="${username}", PasswordDigest="${b64}", Nonce="${btoa(non)}", Created="${now}"` }
username と api_key を埋めてバックグラウンドで動かす
page.js
chrome.runtime.sendMessage({ bookmark: location.href })
ページ内で動かすコード
こういう感じ http://i.imgur.com/LCbUGwe.png
// ==UserScript== // @name metaBKM // @include http://b.hatena.ne.jp/entry/* // @version 1 // @grant none // ==/UserScript== (function(){ function make(){ var list = document.querySelectorAll('#public-bookmarks .bookmark-list > li'); for(var i = 0;i < list.length;i++){ var commentLink = list[i].querySelector('.user-comment-link'); if(!commentLink) {continue;} var bkmImg = 'http://b.hatena.ne.jp/entry/image/' + commentLink.href; var img = document.createElement('img'); var a = document.createElement('a'); img.setAttribute('src',bkmImg); a.setAttribute('href','http://b.hatena.ne.jp/entry/' + commentLink.href.replace(/.*?\/\//,'')); a.appendChild(img); var parentElm = list[i].querySelector('span'); parentElm.insertBefore(a, parentElm.children[2]); } } function check(){ if(document.querySelector('.commentlist-loading')){ return false; } else { return true; } } var timer = setInterval(function(){ if(check()) { console.log(check()); make(); clearInterval(timer); } }, 1000); })();
・コメントが3行なのを一行に戻す。
・コメントがない行を消す
.nocomment{display:none;}
.bookmark-list span.comment { display: inline; }
.bookmark-list img.profile-image { width:18px; height:18px; }
■参考
http://hatena.g.hatena.ne.jp/hatenabookmark/20110405/1301981564
http://hibari.2ch.net/test/read.cgi/esite/1300432939/23-26
23 :名無しさん@お腹いっぱい。:2011/04/06(水) 11:48:38.71
/*サイドバー非表示*/
#container .curvebox-body { padding:20px; }
#sidebar { display:none; }
.bookmark-list li { padding-left: 20px; }
.bookmark-list img.profile-image { width:18px; height:18px; }
.bookmark-list span.comment { display: inline; }
/*ブクマ用フォーム非表示*/
#add-bookmark-container { display:none; }
/*人気コメント非表示*/
#scored-bokkmarks { display:none; }
https://gist.github.com/903132 を組み合わせて
ブクマ追加は[B!]アイコンからにするとこれまでに近い表示に。
26 :名無しさん@お腹いっぱい。:2011/04/06(水) 11:59:27.60
#scored-bookmarks { display:none; }
http://b.hatena.ne.jp/entry/hatena.g.hatena.ne.jp/hatenabookmark/20110405/1301981564
https://addons.mozilla.org/ja/firefox/addon/stylish/
見た目だけ変えてみたぞ。
あんまりいいもんじゃないと思うけど、サイドバーがなくなったらどんな感じになるか体験してみるといいんじゃないかな。
まあどんなもんかやってみて。叩き台、印象の変化の確認。
あとおまけでスター順の部分は消しておいた。#scored-bookmarksってあるだろ、そこじゃ。
@namespace url(http://www.w3.org/1999/xhtml); @-moz-document url-prefix("http://b.hatena.ne.jp/entry/") { #container .curvebox-body { padding-right:20px !important; } #main, #sidebar { width:100% !important; float:none !important; } #sidebar { margin-left:0 !important; } #scored-bookmarks{ display:none !important; } }
http://b.hatena.ne.jp/entry/lifehack2ch.livedoor.biz/archives/51229298.html
うりゃ!
@namespace url(http://www.w3.org/1999/xhtml); @-moz-document url-prefix("http://b.hatena.ne.jp/entry/") { #container .curvebox-body { padding-right:20px !important; } #main, #sidebar { width:100% !important; float:none !important; } #sidebar { margin-left:0 !important; } #scored-bookmarks{ display:none !important; } .comment { display:inline !important; } .bookmark-list .profile-image { width:16px!important; height:16px!important; margin-left:-24px!important; } .user-navigator.user-navigator-large { width:34px!important; height:20px!important; } .bookmark-list li {padding-left:32px!important;} }
すべて、ゴリゴリとプログラムを作りこんでは、ネット上にサービスを公開する形でサイトを公開している。
ブログとかで色々な情報発信・・・は、十何年前に自分にはできない・・とあきらめたからだ。
(一日に、1個の投稿をする・・など自分にはできない。)
サイトのアイデアを思いついたら、短期間集中して作りこみを行い、完成したら公開、このスタイルが自分には一番合っている。
公開したサイトが、役に立ちそうかどうかの判断は、ブックマークしていただいた件数を見て判断している。
しかし、はてぶの新着には、一度も表示されたことが無い。
なぜか、サイトへの訪問者が少ない&ブックマークしてもらえる時期が短期間ではないからしょうがないのだけれでも・・。
(新規登録~短期間で複数のブックマークされないと新着には上がらない)
しょうがないといえばしょうがないな・・・。
twitterでも、サイトをつぶやいてみた、でも訪問者少なかった(フォロアーがロボット収集されたフォロアーだからしょうがないか)
今までのところ
はてぶ・・4件(内1件自分)
www.mixclips.org・・mixclips・・1件
はてぶ 見てると、一日で、何十~何千のブックマークされるページがあるけど、すごいな・・。
さて、6月20日に公開してから、20日間過ぎたけど、はたしてこのサイトに未来はあるのでしょうか・・?
でも、一回公開しちゃったら、利用する方がいる間はなかなかサービス止めれないしな・・・。
一度でいいから、はてぶの新着 トップページに 載ってみたい。
ニッチなサービスだし、需要が少ないことはわかってはいるのだけれでも・・。
サイト作っていて、一番の励ましは、アクセスしかないんだよな・・。
さ、気分一新、本業の3k職である開発に戻ろう・・。
おそらく一昨日の激しいMOJIBAKE不具合の発生原因となった修正によると思われる、キーワードがアンカー文字列にあるとそこからキーワードリンクにされてしまう、という別の不具合が発生している。
+[http://anond.hatelabo.jp/:title=はてな匿名ダイアリー] +<a href="http://anond.hatelabo.jp/">はてな匿名ダイアリー</a> +[http://anond.hatelabo.jp/:title=はてな匿名ダイアリー] +[http://anond.hatelabo.jp/:title=これがはてな匿名ダイアリーの姿] +[http://anond.hatelabo.jp/:title]
5番目のパターンは、多くの文字の数値文字参照化と取得した文字との関係で起こっている現象であろうと、たとえば「YouTube - Broadcast Yourself([http://www.youtube.com/:title])」等から推察できる。
+http://www.hatelabo.jp/ +http://anond.hatelabo.jp/ +[http://www.hatelabo.jp/:title=http://www.hatelabo.jp/] +[http://anond.hatelabo.jp/:title=http://anond.hatelabo.jp/] +[http://anond.hatelabo.jp/:title=http://www.hatelabo.jp/] +[http://www.hatelabo.jp/:title=http://anond.hatelabo.jp/]
例えばwwwとこのエントリー内に書いてありキーワードリンクが発生している条件では、上記の内容が下記のようなリンクになる。
この時、ASCII文字によるanondもキーワードである事に注意。
これは若干異なるものの、以下のように連続した英数字からなる文字列の場合は途中でキーワードリンクにならないが、他の場所でキーワードリンクとなってる文字列の場合はキーワードリンクとなる従来の仕様の影響かもしれない。
このほか従来からのpタグ(下記参照)に加え、&や>(ASCII文字による&と>)等の不具合も出ている。
<p>
しかし、この修正でhttp://anond.hatelabo.jp/20070129012129と同一の内容であっても、多くのキーワードが正常にリンクされるようになった。
OK
C# $10 (T_T) *ist D +ANIMA yes,mama ok -196℃ .book c/w :active ave;new アンリ・カルティエ=ブレッソン ?B @CHaT [TV] ^H _no PE`Z ||リ・_・`川
AirH" AirH" 女子高生 GIRL'S-HIGH 女子高生 GIRL'S-HIGH MÄR MÄR (*゚∀゚)ノ パキャッ (*゚∀゚)ノ パキャッ
文字参照に変換されるため双方上と同様に
P&G
含むキーワードを見つけられず
% \ { } ~
キーワード関連
また、近い問題としてhttp://anond.hatelabo.jp/20070328234724もあげておく。修正されていた。
結論としてエスケープは面倒臭
o 21 !K7
22 AirH"
o 22 AirH"
22 AirH&quot;
o 23 C#
o 24 $10
26 R&B
o 26 R&B
27 B'z
27 B'z
o 28 (T_T)
o 29 (T_T)
o 2a *ist D
o 2c yes,mama ok
o 2e .book
x 2f c/w
o 3a :active
3c のどごし<生>
3c のどごし<生>
3e のどごし<生>
3e のどごし<生>
x 3f ?B
o 40 @CHaT
o 5b [TV]
5c \
o 5d [TV]
^H
o 5f _no
o 60 PE`Z
7b {
o 7c ||リ・_・`川
7d }
7e ~
MÄR
o MÄR
(*゚∀゚)ノ パキャッ
P&G
P&G
結局概要表示機能追加した。unsafeWindow使いまくり。大丈夫かいな。
// ==UserScript== // @name Hatena Bookmark Tree Expander // @namespace http://anond.hatelabo.jp/ // @include http://b.hatena.ne.jp/entry/* // ==/UserScript== // <div class="info"> // <ul id="similar_entries" class="bookmarklist"> // <li></li> // </ul> // </div> // <div class="info"> // <ul id="referred_entries" class="bookmarklist"> // <li id="referred-entry-\d+"></li> // </ul> // </div> // <div class="info"> // <ul id="relation_diary" class="bookmarklist"> // <li id="diary-{id}-\d+"></li> // </ul> // </div> (function() { function main() { loadBookmarkCommentViewer(); similar.prototype.rootAppend(); referred.prototype.rootAppend(); } function HBTM(target) { this.target = target; this.targetXPath = "//ul[@id='"+target+"']/li"; this.targetRegExp = new RegExp('<ul id="'+target+'"(.|\\s)*?</ul>'); } HBTM.prototype = { openIcon: '<img width="15" height="15" class="icon" style="opacity: 0.6" src="http://anond.hatelabo.jp/images/common/open.gif"/>', closeIcon: '<img width="15" height="15" class="icon" style="opacity: 0.6" src="http://anond.hatelabo.jp/images/common/close.gif"/>', loadingIcon: '<img width="13" height="13" class="icon" src="http://anond.hatelabo.jp/images/common/loading.gif"/>', commentIcon: function(url) { return '<img class="hatena-bcomment-view-icon" src="http://r.hatena.ne.jp/images/popup.gif" onclick="iconImageClickHandler(this, \''+url+'\', event);">' }, create: function() { this.comment = document.createElement("span"); this.comment.innerHTML = this.commentIcon($X("string(descendant::a/@href)", this.node).value()); this.open = document.createElement("a"); this.open.href = "javascript:void(0)"; this.open.innerHTML = this.openIcon; this.close = document.createElement("a"); this.close.href = "javascript:void(0)"; this.close.innerHTML = this.closeIcon; this.close.style.display = "none"; this.loading = document.createElement("span"); this.loading.innerHTML = this.loadingIcon; this.loading.style.display = "none"; this.node.appendChild(this.comment); this.node.appendChild(document.createTextNode(" ")); this.node.appendChild(this.open); this.node.appendChild(this.close); this.node.appendChild(this.loading); this.open.addEventListener("click", bind(this.openAct, this), false); this.close.addEventListener("click", bind(this.closeAct, this), false); }, openAct: function() { this.open.style.display = "none"; if (this.tree) { this.tree.style.display = "block"; this.close.style.display = "inline"; } else { this.loading.style.display = "inline"; this.load(); } }, closeAct: function() { if (this.tree) { this.tree.style.display = "none"; this.close.style.display = "none"; this.open.style.display = "inline"; } }, load: function() { var url = $X("string(descendant::a[starts-with(@href, '/entry/')]/@href)", this.node).value(); GM_xmlhttpRequest({ method: "GET", url: "http://b.hatena.ne.jp"+url, onload: bind(this.loadCallback, this) }); }, loadCallback: function(result) { var match = result.responseText.match(this.targetRegExp); if (match) { var sandbox = document.createElement("div"); sandbox.innerHTML = match[0].replace(this.target,""); this.tree = sandbox.firstChild; } else { this.tree = document.createElement("ul"); } this.append(); this.loading.style.display = "none"; this.close.style.display = "inline"; }, append: function() { this.tree.style.backgroundColor = "transparent"; this.tree.style.listStyleType = "circle"; this.node.appendChild(this.tree); $X("li", this.tree).each(function(n) { var a = $X("a",n).node(); var c = $X("count(//li/a[@href='"+a.href+"'])").value(); if (c > 1) n.parentNode.removeChild(n); }); $X("li", this.tree).each(bind(function(node){new this.constructor(node)}, this)); }, rootAppend: function() { $X(this.targetXPath).each(bind(function(node){new this.constructor(node)}, this)); } }; function similar(node) { this.node = node; this.create(); } similar.prototype = new HBTM("similar_entries"); similar.prototype.constructor = similar; function referred(node) { this.node = node; this.create(); } referred.prototype = new HBTM("referred_entries"); referred.prototype.constructor = referred; function loadBookmarkCommentViewer() { var head = document.getElementsByTagName("head")[0]; var script = document.createElement("script"); script.type = "text/javascript"; script.src = "http://b.hatena.ne.jp/js/BookmarkCommentViewerAllInOne.1.2.js"; head.appendChild(script); var css = document.createElement("link"); css.rel="stylesheet"; css.href="http://d.hatena.ne.jp/css/base.css"; css.type="text/css"; css.media="all"; head.insertBefore(css, head.firstChild); window.addEventListener("load",function(){ var BCV = unsafeWindow.BookmarkCommentViewer; BCV.options['screenshot'] = true; var asyncCommnetView = BCV.asyncCommnetView; BCV.asyncCommnetView = function(url, onCompleteCallback) { var div = asyncCommnetView(url, function(){ onCompleteCallback.apply(this, arguments); new unsafeWindow.Ten.XHR("http://b.hatena.ne.jp/entry/rss/"+url, {}, function(result) { if (! result.responseText.match(/<description>(.*?)<\/description>/)) return; if (! RegExp.$1) return; // var desc = document.createTextNode("desc: "+RegExp.$1); var desc = document.createElement("li"); desc.appendChild(document.createTextNode("desc: "+RegExp.$1)); div.lastChild.insertBefore(desc,div.lastChild.getElementsByTagName("li")[0]); }); }); return div; }; BCV.asyncCommnetView.origin = asyncCommnetView; }, false); } function bind(f,o) {return function() {return f.apply(o, arguments)}} function $X(xpath, context) { if (!(this instanceof $X)) return new $X(xpath, context); this.xpath = xpath; this.context = context || document; } $X.prototype = { evaluate: function() { var result = document.evaluate(this.xpath, this.context, null, this.type, null); switch (result.resultType) { case XPathResult.STRING_TYPE : return result.stringValue; case XPathResult.NUMBER_TYPE : return result.numberValue; case XPathResult.BOOLEAN_TYPE: return result.booleanValue; case XPathResult.FIRST_ORDERED_NODE_TYPE: return result.singleNodeValue; } return result; }, node: function() { this.type = XPathResult.FIRST_ORDERED_NODE_TYPE; return this.evaluate(); }, value: function() { this.type = XPathResult.ANY_TYPE; return this.evaluate(); }, each: function(func) { this.type = XPathResult.ORDERED_NODE_SNAPSHOT_TYPE; var result = this.evaluate(); for (var i=0; i<result.snapshotLength; i++) func(result.snapshotItem(i)); } }; main(); })();