Movatterモバイル変換


[0]ホーム

URL:


はてラボはてな匿名ダイアリー
ようこそ ゲスト さんログインユーザー登録

「t-con」を含む日記RSS

はてなキーワード:t-conとは

2025-10-25

インプレス系の記事概要欄がはてブに反映されない件

気にしてるの私だけかもしれないけど、インプレス系(*.watch.impress.co.jp)の記事だけ、はてなブックマーク記事一覧で概要欄が空欄になってしまってるのが昔から気になっていたので、両社に要望してみた。

例:

はてなブックマーク -人気エントリー -テクノロジー

https://b.hatena.ne.jp/hotentry/it

(画面右上に3つ並んだビュー選択ボタンから、真ん中の概要付きビューを選ぶと影響が顕著)

(私はこのビューは使ってないけど、独自に当ててるスタイルシート概要欄の内容を活用している)

要望内容:

はてなブックマーク -はてなブックマークへのフィードバックhttps://b.hatena.ne.jp/-/feedback/hatena_bookmarkインプレス系のメディアにだけ、はてブホットエントリ一覧などのページで p.entrylist-contents-description が空欄になってしまうのが気になっていますインプレス記事のヘッダにmeta[property="og:description"]meta[name="twitter:description"]などは存在するのに、単純なmeta[name="description"]が存在していないことが原因でしょうか?存在しない場合は、meta[property="og:description"] などの妥当候補順次探しに行ってもいいのではないでしょうか。(別途、インプレスにも meta[name="description"] を用意するよう要望してみます)(そもそも、p.entrylist-contents-description が空欄になってしま理由がこれなのかどうかも自信がありません)

Permalink |記事への反応(0) | 23:41

このエントリーをはてなブックマークに追加ツイートシェア

2025-09-02

uBlockOrigin記事フィルターYahooニュースはてブYoutube

webサービスのほうでブロック機能を用意してほしい所ですが、実際のところ期待できないというのが正直なところです。

また、サービス毎にブラウザ拡張を用意するのも、それはそれで面倒だし複雑なので、uBlockOriginのマイフィルターブロックできるようにしてみました。

Firefox142での動作確認しています


NGワードURLあくまで参考です。



Yahooニュース記事

! 2025/00/00https://news.yahoo.co.jp

news.yahoo.co.jp##a:has-text(/堀江貴文|ホリエモン|西村博之|ひろゆき/)


はてなブックマーク記事

! 2025/00/00https://b.hatena.ne.jp/

b.hatena.ne.jp##.entrylist-contents:has-text(/堀江貴文|ホリエモン|西村博之|ひろゆき/)

b.hatena.ne.jp##.entrylist-contents:has(a:is([href*="anond.hatelabo.jp/"], [href*="togetter.com/"]))


Youtube

タイトルキーワード

! 2025/00/00https://www.youtube.com/

! [YouTube]TitleKeyword Filter

youtube.com##:is(ytd-rich-item-renderer, ytd-video-renderer, ytd-compact-video-renderer, ytd-grid-video-renderer, ytd-playlist-panel-video-renderer):has-text(/堀江貴文|ホリエモン|西村博之|ひろゆき/)

チャンネル

! [YouTube] Channel Filter

youtube.com##:is(ytd-rich-item-renderer, ytd-video-renderer, ytd-compact-video-renderer, ytd-grid-video-renderer):has(#channel-name:has-text(/堀江貴文|ホリエモン|西村博之|ひろゆき/))

Permalink |記事への反応(0) | 23:05

このエントリーをはてなブックマークに追加ツイートシェア

2025-07-02

anond:20250701235606

ありがと!さっそく2行追加するわ!

body#page-edit-confirm div.section a.keyword[href$="/dorawii"],

body#page-edit-confirm div.section a.keyword[href$="/PGP"],

Permalink |記事への反応(1) | 05:25

このエントリーをはてなブックマークに追加ツイートシェア

2025-02-16

anond:20250216152548

”⼆年少々前に、イギリス政府アダム・スミスコナー起訴しました。”

ちなみに22年前のunborn son.を「生まれぬ息子」と訳すのはいかがなものか。

 

英国退役軍人であるアダム・スミスコナー氏(51歳)は、2022年11月イングランド南部ボーンマス中絶クリニック近くで数分間黙祷を捧げた際、公共空間保護命令( PublicSpaces Protection OrderPSPO)に違反したとして起訴されました。

 ttps://adfinternational.org/en-gb/news/guilty-army-vet-convicted-for-praying-silently-near-abortion-facility

このPSPOは、2022年10月ボーンマスクライストチャーチプールBCP評議会によって導入され、中絶サービスに関連する問題について、抗議や賛否の表明を禁止するものでした。”

PSPOの全文はこちら ttps://www.bcpcouncil.gov.uk/Assets/Crime-safety-and-emergencies/PSPOs/Ophir-Road-and-surrounding-area-Public-Spaces-Protection-Order-PSPO.pdf

スミスコナー氏は、22年前に自身が関与した中絶で失った息子のために祈っていたと述べています

ttps://www.standard.co.uk/news/crime/bournemouth-christchurch-uk-parliament-army-british-b1188699.html

ttps://www.independent.co.uk/news/uk/crime/christian-bournemouth-christchurch-uk-parliament-army-b2631603.html

2024年10月16日、プール治安判事裁判所は彼に有罪判決を下し、執行猶予付きの判決と9,000ポンド(約170万円)の裁判費用の支払いを命じました。

https://www.christiantoday.co.jp/articles/34158/20241023/man-convicted-for-praying-silently-near-abortion-clinic.htm

クリスチャントゥデイ日本2024年10月23日

中絶クリニックの緩衝地帯黙祷ささげた男性有罪判決 英国

スミスコナーさんを弁護したキリスト教法曹団体「ADFインターナショナル英国支部英語)のジェレマイア・イグヌボル上級法律顧問は、「非常に大きな影響を持つ法的転換点」だとして、次のように述べた。

 

今日、ある男性有罪判決を受けましたが、それはイングランドの公の通りで彼が考えたこと、つまり神への祈りの内容を理由としたものでした。言論思想の自由という基本的自由をないがしろにするという点において、英国はこれ以上ないほど落ちぶれてしまいました。私たち判決をよく検討し、控訴するかどうかを検討しています人権は全ての人に与えられているものであり、中絶に対する考え方とは関係ありません」”

Human rights are forall people – no matter theirviewon abortion.”

()

Permalink |記事への反応(1) | 15:42

このエントリーをはてなブックマークに追加ツイートシェア

2025-01-13

最近知った言葉

海外ケモナー界隈のwikiに書いてあったんだが、PCD(Post-con depression)って言って、デカイベントの後にうつになることを言うらしい

https://en.wikifur.com/wiki/Post-con_depression

それ聞いて、「なんかシュガーソングとビターステップの2番Bメロ歌詞みたいやな……」と思った

囃子のその後で 昂ったままの人 泣き出してしまう人

多分同じだろう でも言葉にしようものなら稚拙が極まれ

https://www.uta-net.com/song/186190/

Permalink |記事への反応(0) | 21:11

このエントリーをはてなブックマークに追加ツイートシェア

2024-12-08

美味しいケーキランキング

【前置き】

はてな匿名で書く内容なのかというのはともかく、私が美味しいと思うケーキ屋・パティシエを書き出して、順に並べてみた。私は製菓料理について専門的な教育を受けたこともないし、生業としてフードライターをやっているわけでもない。仕事柄、堅い文章を書くことにはある程度慣れているけれど、エッセーのような柔らかい文章を書いた経験ほとんどない。

このランキングを作ってみようと思ったのは、怪我をして外を歩く気になれず暇だったからというのが一番の動機だけれど、ランキング作成過程で「あの時のあのケーキは本当においしかったな」と幸せな思い出を振り返ることができたし、「自分はこういうケーキを美味しいと思っているのか」という傾向を何となく知ることができて面白かった。

このランキングは、私の個人的な好みに基づいて、偏差値表のような形で作成している(もちろん偏差値のものは表していない。)。偏差値50を超えるケーキ基本的にどれも文句なく美味しいし、そこまで確固たる優劣があるとは思わない。特に偏差値60-65のレンジはその日の気分によって順番が変わるだろうと思う。比較的趣向が近い友人に意見を聞いても、結構な食い違いがあったので、本当にその人の好み次第ということなのだと思う。また、日頃からメモを取っているわけでもなく、思い出した順に書きだしただけなので、ランキングに載っていて当然なのに書き落としているものもたくさんあると思う。

そんな感じで免責みたいなものを書き連ねたところで、ランキングをご覧ください。

【美味しいケーキランキング

80: MaximeFrédéric (Le Tout-Paris, MaximeFrédéric chezLouis Vuitton) (Paris)

79: Matthieu Carlin (Butterfly Pâtisserieat Hôtel de Crillon) (Paris),François Perret (RitzParisLe Comptoir) (Paris)

78:

77:

76:

75: Mori Yoshida (Paris), Cedric Grolet (Paris)

74:

73: [xxxxxxxxxxxx] (京橋)

71:

70:LESS (恵比寿)

69: ASSEMBLAGES KAKIMOTO (京都), pàtisserie Tendresse (京都)

68:

67:

66: FOBS (蔵前),LesAlternatives (東小金井), Pâtisserie K-Vincent (神楽坂)

65:La Pâtisserie Cyril Lignac (Paris),Equal (幡ヶ谷),LECAFE DUBONBON (代々木八幡)

64: Libertable(赤坂), grains de vanille (京都), Ryoura (用賀), Dining33 Pâtisserie àla maison (麻布台),おかしうっちー (北参道)

63: Yann Couvreur Pâtisserie (Paris),La Pâtisserie Ryoco (高輪), Fleurs d’été (代々木上原), HarmonikaKyoto (京都),sweetsgarden YUJI AJIKI (神奈川),Sweet Rehab (NY)

62: PIERRE HERMÉPARIS,AUBON VIEUX TEMPS (尾山台),Paris S'éveille (自由が丘), AIGRE DOUCE (目白), CONFECT-CONCEPT (稲荷町),Paris S'éveille (自由が丘), AIGRE DOUCE (目白),

61: équilibre (不動前), Pâtisserie ease (日本橋),銀座和光 (銀座), PalaceHotelTokyo (大手町),その他美味しいホテル系, Asterisque (代々木上原), ates souhaits! (吉祥寺), N'importe quoi (京都)

60: Avranches Guesnay (春日), Taisuke Endo (学芸大学),Préférence (新中野), feuquiage (調布), PÂTISSERIE ASAKO IWAYANAGI (等々力)

[...]

55:千疋屋総本店,Henri Charpentier, その他デパ地下系・工場

[...]

50:LAWSON,Lady M (NY)

[...]

45: Lysee (NY)

[...]

40:Whole Foods Market

【いくつか補足】

パリには複数回行ったことがあるが、パリケーキは本当に美味しく感じた。もちろん遠路はるばる補正思い出補正もあるのだと思うけれど、単純に値段がとても高いので、惜しむことなく良い材料を使えているのではないかと思う。パティシエ社会的地位が高いらしいので、その結果パティシエが制約なしで好きなようにケーキを作れる、ということもあるのかもしれない。

MaximeFrédéricは有名人だし、本当にどのケーキ(あと、ややテーマ外だけれど、レストランデザートも)も美味しい。いつかホテルシグネチャーレストランにも行ってみたい。Matthieu CarlinやFrançois Perretは、少なくとも私のアンテナでは情報がたくさん入ってくる感じではないけれど、複数ケーキで感動した。

Cedric GroletはMaximeFrédéricよりも有名人で、逆張りしてみたくはなるのだけれど、フルーツの使い方が独創的で、まあ確かに美味しい。あの値段であれだけの人を集められるのは、SNS映えだけでは説明できないと思う。

[xxxxxxxxxxxx]は、フルーツ真摯に向き合っていることや高い洋菓子基礎力に裏打ちされていることが素人の私にも伝わってくるような気がする。接客は独特で毎回緊張するけれど、敬意をもって謙虚に臨めば、丁寧に遇してくれるし、嫌な思いをしたことはない。職人ってそういうものなのかな、と思っている。

LESSは、以前はnomaやINUAみたいな雰囲気実験的なケーキが多くて毎回面白かったのだけれど、最近はそれよりは分かりやすケーキが多くなった。もちろん、それらもとても美味しい。たまに昔のLESSを食べてみたくなるときもある。

タンドレスは、もともと酒やムースとかのイデミスギノ的なものがあまり得意ではない私でも、これは凄いと感じる何かがある。私では理解が及ばないというか、置いて行かれている感じもする。

FOBSは一般的にはすごく高く評価されている感じはしないものの(ゴーフレットはとても有名)、ここのショートケーキ特に美味しいと思う。卵や牛乳などの素材がシンプルによくまとまっている感じがする。判官贔屓的なものが入っているかもしれないけれど。

Alternativeは夏の焼き菓子イベントタルト類が全て美味しい。Equalチーズケーキは瑞々しくてチーズ香りがよく整っていて、これより美味しいチーズケーキはなかなかないと思う。「フランス菓子道」の真ん中・正当を通ってきたかはよく分からないけれど、個人的な好みに合っている。

Ryouraは街のケーキ範疇で、傑出して美味しい。うっちーシグネチャーショートケーキ生クリームミルク感は特徴的。

リョーコは(伝統的という意味ではなく)ちょっと古い感じがするけれど、分かりやすく美味しいと思う。セブンイレブンとのコラボレーションは。。カーヴァンソンやリベルターブルも私の中では同じような枠に入っているのだけれど、こちらの方が個人的な好みに合っている(何でだろう)。

étéをどう位置づけるかは難しかった。テンションの上がる見た目だし確かに美味しいのだけれど、洋菓子としての工夫・洗練を感じるかというと、そういうことを目指して作られたものでもないような気がする。

ピエールエルメのイスパハンは、なんだかんだといってやっぱり名作だと思う。ホテル系のちゃんと作られたケーキは、やや割高な感じはするものの、総じてしっかり美味しい。

easeは個人的な好みにはあまりハマらないけれど、美味しいし評価されていることもわかる。アステリスクアテスウェイ家族で食べるのにとてもよいと思う。ナンポルトクワリンゴタルトは一つの発明だと思う(別途元祖があるのかな)。パリヴェイユフランス菓子の正当という感じで間違いなく美味しいのだけれど、個人的に好きなケーキとは少し違う(パン焼き菓子はすごく好み)。

アメリカでウケているケーキは、個人的にはそこまでヒットしなかった。Sweet Rehabは見た目もきれいですごく高く評価されているけれど、高額すぎる点を措いても、評価に見合うほどではない気がする。

店名が大文字だったり小文字だったり「pàtisserie」が付いたり付かなかったりするのは、適当google検索した結果をそのまま引き写しているだけなので、正確ではないかもしれない。

こういう番付モノは、それ自体批評対象として「それは違う、こっちの方が上だ」等々とケチをつけることに楽しさがあると思う。コメントをいただけたら嬉しい。

追記1209】

記事を公開した後、思ってもいなかった程たくさんの方に見ていただいて、色々なコメントをいただいた。一つ一つどれもありがたいと思っている。

書き忘れていたお店を何個か思い出したので、適宜ランキングに追加してみた(Asako Iwayanagi,AUBON VIEUX TEMPS, CONFECT-CONCEPT, Dining33 Pâtisserie àla maison, équilibre, Libertable,sweetsgarden YUJI AJIKI, Patisserie PorteBonheur)。また、説明部分にもいくつか加筆をした。加筆するにあたっても、既に順番を書き換えた方がいいのではないかという気がしてくるから、やっぱりその時の気分次第の順に過ぎないんだなと分かった。

偏差値表のような形」というのが分かりにくいというコメントがあった。イメージしていた偏差値表は、例えばこんな感じのものだった。

https://www.syutoken-mosi.co.jp/application/hensachi/upload/dansi202412.pdf

もちろん、今回は母集団正規分布かもよく分からないし平均や分散を求めて何かしているわけではない。あくま偏差値「風」ということでご容赦いただきたい。今回は、偏差値50の重責をローソンに担ってもらった。個人的偏差値(風)60以下かなと思ったものは、角が立つの基本的には取り上げなかった(NYいくら角が立っても大丈夫。)。

神奈川千葉埼玉などの郊外大阪神戸のような別の都市圏はあまり開拓できていないので、いつか掘り下げてみたい。

中野のMORI YOSHIDAについては、どう取り上げるか迷った。例えば、パリで食べたババトロピックミルクが入ったスポイトのようなものが刺さっていて、それを注入して食べるのがとても美味しかった記憶がある。中野の方はそうはなっていなくて、少なくとも何らかの「違い」はあるのだと思う(見た目に明らかに分かるもの以外も多分。)。ただ、だからといって劣るとかいうわけでもないし、でもそうすると今度は、中野のMORI YOSHIDAとLESSに大きな差があるかのようになるけれど、本当にそうなのかというとよく分からない。突き詰めていくと、遠路はるばる補正思い出補正を数値化することにもつながりそうで、それは楽しい思い出のためにも止めておいた方がよいかなと思い、取り上げないことにしていた。

Permalink |記事への反応(15) | 17:08

このエントリーをはてなブックマークに追加ツイートシェア

2024-08-15

スターの多い順にブコメを並び替える

FANZAの検索結果から熟女を除外するブックマークレット がうまく動いたので、気を良くしてはてなブックマークコメント欄スター数順にソートするブックマークレット作りました

作った動機は、「注目コメントに入りきれなかったちょっといいコメント」をサクサク探したいから。結果として建設コメント順位付けモデル無効化していますが、あのアルゴリズムには特に不満は特にありません。

ブックマークレット

javascript: (async () => {
const wait =ms => newPromise(resolve => setTimeout(resolve,ms));
document.querySelector('.js-bookmarks-sort-tab[data-sort="recent"]').click();
window.scrollTo(0, document.body.scrollHeight);
await wait(1000);
window.scrollTo(0, 0);
await wait(1000);
const p = document.querySelector('.js-bookmarks-recent');
let l = Array.from(p.querySelectorAll('.entry-comment-contents'));
const g = e => {
let n = e.querySelectorAll('.hatena-star-star').length;
const c = e.querySelector('.hatena-star-inner-count');
return c ? n +Number(c.textContent) : n
};
l = l.filter(e => g(e) > 0);
l.sort((a, b) => g(b) - g(a));
p.replaceChildren(...l);
})();

ミニファイしたものコードに一部誤りがありましたので訂正しました(2024-08-1611:47)

javascript:(async()=>{const wait=ms=>newPromise(resolve=>setTimeout(resolve,ms));document.querySelector('.js-bookmarks-sort-tab[data-sort="recent"]').click();window.scrollTo(0,document.body.scrollHeight);await wait(1000);window.scrollTo(0,0);await wait(1000);const p=document.querySelector('.js-bookmarks-recent');let l=Array.from(p.querySelectorAll('.entry-comment-contents'));const g=e=>{let n=e.querySelectorAll('.hatena-star-star').length;const c=e.querySelector('.hatena-star-inner-count');return c?n+Number(c.textContent):n};l=l.filter(e=>g(e)>0);l.sort((a,b)=>g(b)-g(a));p.replaceChildren(...l)})()

使い方

FANZAの検索結果から熟女を除外するブックマークレット 参照

コード解説

コード説明にダサイところがあったら厳しく指摘して下さい。

javascript:

ブックマークレット必要な、URLの種類を示すスキーム名です。

(async () => {
// 処理
})();

ページに元々ある変数たちとバッティングしないように、まず無名関数ラップします。処理の中で await を使いたいので async宣言しています

const wait =ms => newPromise(resolve => setTimeout(resolve,ms));

処理の途中で待ち時間を設けるための関数です。便利。

document.querySelector('.js-bookmarks-sort-tab[data-sort="recent"]').click();
window.scrollTo(0, document.body.scrollHeight);
await wait(1000);

「新着コメント」タブをクリックし、ページの一番下までスクロールダウンしてから少し待つ動作です。新着コメントの後半部分(スクロールきっかけの遅延読み込みになっているところ)の読み込みをうながしています

window.scrollTo(0, 0);
await wait(1000);

ページの先頭に戻ってまた少し待ちます。合計2秒の待ち時間雰囲気で決めていますので、これでなければならない・これで過不足ないという値ではありません。単にコメントの読み込み完了を判定する処理を書くのがめんどうだっただけです。

const p = document.querySelector('.js-bookmarks-recent');

新着ブコメの親要素です。繰り返し呼び出すので名前をつけています

let l = Array.from(p.querySelectorAll('.entry-comment-contents'));

コメントをすべて配列に格納します。

const g = e => {
let n = e.querySelectorAll('.hatena-star-star').length;
const c = e.querySelector('.hatena-star-inner-count');
return c ? n +Number(c.textContent) : n
};

コメントはてなスター数をカウントして返す関数です。たくさんスターがついてる ★256★ みたいなやつの数字も足します。

l = l.filter(e => g(e) > 0);

ソートする前に、無スターコメントを消去しています。してもしなくてもいいことですが。

l.sort((a, b) => g(b) - g(a));

残ったコメントスター数で降順ソートします。.querySelectorAll() で収集した要素を配列に入れ直したのは、この .sort()メソッドを使いたいからです(.querySelectorAll() が返す配列風の NodeListオブジェクトは、配列共通メソッドもいくつかあるものの、大半は使えないのです)。

p.replaceChildren(...l);

親要素の内容を、並び替えの終わったコメントそっくり入れ替えて、処理完了です。画面を見ると新着コメントの中身が「スターのついたコメントのみ・スターの多い順」に並んでいます。元に戻す方法はないので、原状回復にはリロードします。ソート状態を示すフラグを立てておいてスターソート⇔日付ソートをかわりばんこに行うようにすればできそうだなと思ったけど実装しません。連打スターを省く処理を追加してUU数でソートできればもっと厳正なランキングになるなーと今思いつきましたがそれも実装しません。

Permalink |記事への反応(1) | 21:55

このエントリーをはてなブックマークに追加ツイートシェア

2024-02-11

anond:20240210212445

じゃあワイも無責任はてなCSS貼っとくわ

パソコン画面右上のアイコンで選ぶ表示スタイルを一番右の「ヘッドライン」表示にしといてな

/*ヘッドライン表示を切り詰める *//* #container指定CSS優先度を上げる必要がある */body[data-entrylist-layout="headline"] #container .entrylist-main{padding-right: 0 !important;}body[data-entrylist-layout="headline"] #container .entrylist-contents{padding-left: 0 !important;}body[data-entrylist-layout="headline"] #container .entrylist-contents-users{  position: static !important;}body[data-entrylist-layout="headline"] #container .entrylist-contents-users{top: 14px !important;}/*ヘッドライン表示にサムネイルを追加 */body[data-entrylist-layout="headline"] #container .entrylist-contents-main{  display: grid;  grid-template:    "usersbodytitle"  28px    "bookmarkbody domain" 20px    / 60px 120px 1fr;}body[data-entrylist-layout="headline"] #container .entrylist-contents-users{  grid-area: users;}body[data-entrylist-layout="headline"] #container .entrylist-contents-users aspan{margin-right: 0;}body[data-entrylist-layout="headline"] #container .following-bookmarks-container{  grid-area:bookmark;  position:absolute;  left: 20px;  bottom: 2.5px;}body[data-entrylist-layout="headline"] #container .entrylist-contents-body{  grid-area:body;}body[data-entrylist-layout="headline"] #container .entrylist-contents-title{  grid-area:title;  z-index: 99;}body[data-entrylist-layout="headline"] #container .entrylist-contents-title > a{margin-left: -120px;padding-left: 120px;margin-bottom: -28px;padding-bottom: 28px;  width: 890px;white-space: nowrap;  display: block;}body[data-entrylist-layout="headline"] #container .entrylist-contents-body{  display: block !important;}body[data-entrylist-layout="headline"] #container .entrylist-contents-thumb{  position: static;}body[data-entrylist-layout="headline"] #container .entrylist-contents-thumbspan{  width: 100px;  height: 50px;}body[data-entrylist-layout="headline"] #container .entrylist-contents-thumb{background: #f0f0f0;  width: 100px;  height: 50px;background-position:50%;background-size: cover;border-radius: 4px;}/* 2行目に、総合ではドメイン(domain),サイト内一覧ではカテゴリと時刻(meta),マウスバーはいずれも概要文(description) */body[data-entrylist-layout="headline"] #container .entrylist-contents-domain,body[data-entrylist-layout="headline"] #container .entrylist-contents-meta,body[data-entrylist-layout="headline"] #container .entrylist-contents-description{  grid-area: domain;  display: block;  opacity: 0;padding: 0 !important;}body[data-entrylist-layout="headline"] #container .entrylist-contents-meta > li{  vertical-align:top;}html[data-stable-request-url^="https://b.hatena.ne.jp/entrylist/"]body[data-entrylist-layout="headline"] #container .entrylist-contents-domain,html[data-stable-request-url^="https://b.hatena.ne.jp/site/"]body[data-entrylist-layout="headline"] #container .entrylist-contents-meta{  opacity: 1;}body[data-entrylist-layout="headline"] #container .entrylist-contents:hover .entrylist-contents-domain img.favicon +span,body[data-entrylist-layout="headline"] #container .entrylist-contents:hover .entrylist-contents-meta{  opacity: 0;}body[data-entrylist-layout="headline"] #container .entrylist-contents-description{  opacity: 0;  position:absolute;top:calc(40px - 3px);  left:calc(180px + 16px + .5em);  height: 20px;line-height: 20px;color: #999;min-height:auto !important;padding-right: 0 !important;  width: 890px;white-space: nowrap;overflow: hidden;text-overflow: ellipsis;}html[data-stable-request-url^="https://b.hatena.ne.jp/site/"]body[data-entrylist-layout="headline"] #container .entrylist-contents:hover .entrylist-contents-domain,body[data-entrylist-layout="headline"] #container .entrylist-contents:hover .entrylist-contents-description{  opacity: 1;}/*増田調整 */body[data-entrylist-layout="headline"] #container a[href^="/entry/s/anond.hatelabo.jp/"] .entrylist-contents-thumb{background-image:url('https://cdn-ak-scissors.b.st-hatena.com/image/square/b1638cdb5807a4788e4ba3c1109a984166e095fc/height=288;version=1;width=512/https%3A%2F%2Fanond.hatelabo.jp%2Fimages%2Fog-image-1500.gif');}/*マウスバー時にサムネも反応させる見た目調整 */.entrylist-contents-title:hover ~ .entrylist-contents-body .entrylist-contents-thumb{  opacity: .90;}

Permalink |記事への反応(0) | 09:03

このエントリーをはてなブックマークに追加ツイートシェア

2024-01-28

www.sunday-webry.com##.series-comment-contents

もうバカと関わりたくないからこれでいいや

似た表示js使ってるところなら同じようにまとめて消しさったほうがいいよ

Permalink |記事への反応(0) | 23:22

このエントリーをはてなブックマークに追加ツイートシェア

2023-12-29

はてぶで松本人志顔写真を出さないようにするグリースモンキー

松本人志以外も消える

// ==UserScript==// @name     hatebu-matsumoto// @version  1// @grant    none// @include     https://b.hatena.ne.jp/// ==/UserScript==var startTime =newDate().getTime();var t = setInterval(  () =>{const list =document.querySelectorAll(".entrylist-contents-thumb,.entrylist-issue-thumb");    list.forEach(x => x.style.opacity ="0");if (newDate().getTime() - startTime>10000){      clearInterval(t);}},10);

document.cssRulesを加工するかMutationObserverを使えよ。 これだと一瞬松本の顔が映るだろ

サンキューJS詳しくないから助かる

Permalink |記事への反応(1) | 20:43

このエントリーをはてなブックマークに追加ツイートシェア

2023-07-23

素早くブクマされた増田を強調 簡易セルクマ検知ユーザースクリプト

https://b.hatena.ne.jp/site/anond.hatelabo.jp

で動くスクリプトでたとえば投稿10分以内にブクマされページに乗ったら「1user」が「1userセルクマ 1とか5(何分後にブクマされたか)」になる。もしマイナスなら誤判定なので無視して。

時間を置いたセルクマには効かないし普通ファーストブクマカがどれぐらいの頻度で確認してるかしらないけど5分以内や1分以内もポロポロあるのでまあ目安に。

増田URLと一覧の時刻表示差分を取ってます

増田じゃpre記法でも記号が変換されるみたいだから作業

.forEach(div => {

('.entrylist-contents-title> a')

if(diffSec>

とかの

<>

<>

に変えてね

他にも見落としあるかも

誤判定が減るから非公開ファーストブクマを判定できたらいいんだけどね。

// ==UserScript==// @name         hatebu masuda selkmark// @namespacehttp://tampermonkey.net/// @version      0.1// @description特定時間以内にブクマされた増田を強調する// @authorYou// @matchhttps://b.hatena.ne.jp/site/anond.hatelabo.jp*// @grant        none// ==/UserScript==(function() {  'use strict';const threshold = 60 *10 // 何秒以内かconst domain = 'https://anond.hatelabo.jp/'constdateTemplate = '202301020304' // 時分までurl時刻表記constdateTest = newRegExp('\\d{' +dateTemplate.length + '}')  document.querySelectorAll('div.entrylist-contents').forEach(div =&gt; {const masuda = div.querySelector('.entrylist-contents-title&gt; a')constdateStr = masuda.href.substring(domain.length +dateTemplate.length, domain.length)    if (!dateTest.test(dateStr)) {      //キーワードとかconsole.log('not diary',dateStr)      return    }    // newDateできるように変換    //https://amateur-engineer.com/javascript-date-yyyymmddhhmm/const year = parseInt(dateStr.substring(0, 4))const month = parseInt(dateStr.substring(4, 6))const day = parseInt(dateStr.substring(6, 8))const hour = parseInt(dateStr.substring(8,10))constmin = parseInt(dateStr.substring(10,12))constdate = newDate(year, month - 1, day, hour,min)const bukumaDate = newDate(div.querySelector('.entrylist-contents-date').textContent) // 2023/01/23 00:00const diffSec = (bukumaDate -date) /1000 //ms tosec    if (diffSec&gt; threshold) {      return    }    //ブクマuserconstuser = div.querySelector('span.entrylist-contents-users a').lastChilduser.textContent += 'セルクマ ' + (diffSec / 60)    // 古い記事マイナスになる でも2015年ぐらいの記事までかな?新着はセーフ臭い    /*    if(diffSec &lt; 0) {user.textContent += ' 異常差分:' + diffSec    }    */  })})();

Permalink |記事への反応(3) | 12:02

このエントリーをはてなブックマークに追加ツイートシェア

2023-02-15

リスト登録したユーザーはてブコメントを薄く表示するgreasemonkey

非表示機能で完全に無視したいって程でもないんだよな〜っていう。

タイプ別色分け機能とかこういうののはてなスター版とかも欲しい。面倒だから誰か書いて。

// ==UserScript==// @name     hatebu_comment_usuku_hyouji// @version  1// @grant    none// @include     https://b.hatena.ne.jp/entry/*// ==/UserScript==const userIdList = [  'hoge',  'piyo',  ...];setInterval(() =&gt; {  document.querySelectorAll('.entry-comment-contents').forEach((element, i) =&gt; {    if (userIdList.includes(element.dataset.userName)) {      element.style.opacity = '0.3';    }  });}, 3000);

Permalink |記事への反応(0) | 21:14

このエントリーをはてなブックマークに追加ツイートシェア

2022-08-06

はてブトップくそ重いのは

ページには表示されないのに各ブクマ概要

class="entrylist-contents-description"

が含まれてるから

Permalink |記事への反応(0) | 23:46

このエントリーをはてなブックマークに追加ツイートシェア

2022-01-01

anond:20220101145248

正直動けばいいと思うので、現状でも問題ないと思うけれどちょっとだけ気になった点。

$$使ってる時点で、デベロッパーツール前提なのは分かるけど、javascriptで動かしたいのか、デベロッパーツールで動かしたいのか、どっちつかずな書き方になっている。

$$('.hatena-star-inner-count').map(a =&gt; a.click());let data = {};Array.from($$('.entry-comment-contents')).forEach(x =&gt; {const userName = x.querySelector('.entry-comment-username a').href.split('/')[3];const comment = x.querySelector('.entry-comment-text').innerText;conststars = Array.from(x.querySelectorAll('.list-star-container a.hatena-star-star')).map(y =&gt; y.href.split('/')[3]);data[userName] = [comment,stars];});console.info(Object.entries(data).map(x =&gt; { return ['|', `b:id:${x[0]}`, '|', x[1][0], '|', x[1][1].join(','), '|'].join(' '); }).join("&#92;n"));

デペロッパツールだけで動くだけでいいなら、3行目のArray.fromがなくても動く。多分、forEachをmapに書き換えても動く。個人的にはforEachに統一したいけど、そこは好みレベル問題だと思う。

$$('.hatena-star-inner-count').map(a =&gt; a.click());let data = {};$$('.entry-comment-contents').forEach(x =&gt; {const userName = x.querySelector('.entry-comment-username a').href.split('/')[3];const comment = x.querySelector('.entry-comment-text').innerText;conststars = Array.from(x.querySelectorAll('.list-star-container a.hatena-star-star')).map(y =&gt; y.href.split('/')[3]);data[userName] = [comment,stars];});console.info(Object.entries(data).map(x =&gt; { return ['|', `b:id:${x[0]}`, '|', x[1][0], '|', x[1][1].join(','), '|'].join(' '); }).join("&#92;n"));

逆に、javascriptで動かしたいなら1行目と3行目はquerySelectorAllに書き換えれる。

document.querySelectorAll('.hatena-star-inner-count').forEach((a)=&gt;{a.click()});let data = {};document.querySelectorAll('.entry-comment-contents').forEach(x =&gt; {const userName = x.querySelector('.entry-comment-username a').href.split('/')[3];const comment = x.querySelector('.entry-comment-text').innerText;conststars = Array.from(x.querySelectorAll('.list-star-container a.hatena-star-star')).map(y =&gt; y.href.split('/')[3]);data[userName] = [comment,stars];});console.info(Object.entries(data).map(x =&gt; { return ['|', `b:id:${x[0]}`, '|', x[1][0], '|', x[1][1].join(','), '|'].join(' '); }).join("&#92;n"));

これも好みの問題だけど、途中のconst宣言は一回しか使ってないので、宣言せずにそのまんま入れてもいいんじゃないかと思った。

document.querySelectorAll('.hatena-star-inner-count').forEach((a)=&gt;{a.click()});let data = {};document.querySelectorAll('.entry-comment-contents').forEach(x =&gt; {data[x.querySelector('.entry-comment-username a').href.split('/')[3]] = [x.querySelector('.entry-comment-text').innerText, Array.from(x.querySelectorAll('.list-star-container a.hatena-star-star')).map(y =&gt; y.href.split('/')[3])];});console.info(Object.entries(data).map(x =&gt; { return ['|', `b:id:${x[0]}`, '|', x[1][0], '|', x[1][1].join(','), '|'].join(' '); }).join("&amp;#92;n"));|&lt;&lt;

Permalink |記事への反応(0) | 22:33

このエントリーをはてなブックマークに追加ツイートシェア

2021-08-03

ブコメの熊がウザいので、削除するブックマークレット作った

javascript:document.querySelectorAll(".entry-comment-contents").forEach(function(e){if(e.innerText.indexOf('🐻')!=-1||e.innerText.indexOf('ʕ•̫͡•ʔ')!=-1){e.remove()}})

ブックマークレットクリックが面倒な人は、GreasemonkeyかTampermonkeyで。

他のパターンコメント削除したい人は『||e.innerText.indexOf('削除したいコメントに含まれ文字列')!=-1』を修正なり、追加なりでどうぞ。

何か要望があれば、はてブコメント(ただし熊系は消してます)か言及でどうぞ。気が向いたら対応します。

なんか漏れてるのがある。文字列の方は、もっと短くした方が良さそう。ただ、これでも漏れてるのがありそうで、もし多様されそうなら対策調査か、はてブユーザー非表示機能を使おう。一応、サンプルの提供感謝

javascript:document.querySelectorAll(".entry-comment-contents").forEach(function(e){if(e.innerText.indexOf('🐻')!=-1||e.innerText.indexOf('•̫͡')!=-1){e.remove()}})

id:kako-junクマで後半を埋めてるコメントで、前半は残したいので、正規表現にして後置のクマだけ消してほしい

こんなんでどうだろう。『正規表現にして後置のクマ』が面倒なので、『1文字目に熊がある場合削除対象外』で。あと『クマだけ消す』も不十分だと思うので、『replace(/a|b|c|d/g, '')』のabcdの箇所を必要に応じて修正して。

javascript:document.querySelectorAll(".entry-comment-text").forEach(function(e){if(2&lt;e.innerText.indexOf('🐻')||2&lt;e.innerText.indexOf('•̫͡')){e.innerHTML=e.innerHTML.replace(/🐻|ʕ|•|̫͡|̫•|ʔ/g, '');}})

ただ、増田仕様で『<>(大なり小なり)の半角』が使えないので、上記の&lt;は<の半角に適宜変換してください。

id:kako-jun 氏が、自身で作られてました。

https://b.hatena.ne.jp/entry/4706344345181168386/comment/kako-jun

Permalink |記事への反応(10) | 01:20

このエントリーをはてなブックマークに追加ツイートシェア

2021-05-08

anond:20210504151428

uBlock系のコンテンツブロッカーを使っているならマイフィルターの設定に

b.hatena.ne.jp##.entrylist-contents-tags

を加えるとエントリーリスト中のタグ表示が消せるし

b.hatena.ne.jp##.entry-tags

を加えるとエントリー個別ページの右上にまとめて出るタグ表示が消せるようだ

Permalink |記事への反応(0) | 06:37

このエントリーをはてなブックマークに追加ツイートシェア

2021-02-10

はてなブックマーク一行スクレイピング

実行すると、各記事

{

 title:記事タイトル,

 url:記事URL,

 users:ブクマ数,

 tags:[タグ]

}

形式に変換し、500ブクマ以上でフィルタし、ブクマ数降順で返す。


#一行版

curl -s https://b.hatena.ne.jp/hotentry/it | pup --charsetutf-8 'div.entrylist-contents-mainjson{}' | jq -r '[.[] | {title: (.. |select(.class? == "entrylist-contents-title") | .children[].title),url: (.. |select(.class? == "entrylist-contents-title")) | .children[].href, users: (.. |select(.class? == "entrylist-contents-users") | .children[].children[].text | tonumber), tags: ([.. |select(.class? == "entrylist-contents-tags") | .children[]?.children[]?.text])}] | unique |map(select(.users >= 500)) | sort_by(.users) | reverse'


#変数

title='title: (.. |select(.class? == "entrylist-contents-title") | .children[].title)'users='users: (.. |select(.class? == "entrylist-contents-users") | .children[].children[].text | tonumber)'url='url: (.. |select(.class? == "entrylist-contents-title")) | .children[].href'tags='tags: ([.. |select(.class? == "entrylist-contents-tags") | .children[]?.children[]?.text])'target='https://b.hatena.ne.jp/'hotentry='hotentry/it'curl -s $target$hotentry | ¥pup --charsetutf-8 'div.entrylist-contents-mainjson{}' | ¥jq -r "[.[] | {${title}, ${url}, ${users}, ${tags}}] | unique |map(select(.users >= 500)) | sort_by(.users) | reverse"

Permalink |記事への反応(0) | 20:57

このエントリーをはてなブックマークに追加ツイートシェア

2018-05-23

[はてブ]uBlockOriginを使って特定ブコメを隠す方法メモ

anond:20180523215832 のついで。

コメントタグ特定単語を含むブックマークコメントブロックする方法

同じくuBlockOriginのMy Filtersを使う。

コメントタグに「死ねばいいのに」という文章が含まれブコメを隠したい場合

hatena.ne.jp##.entry-comment-contents:has-text(死ねばいいのに)

特定IDブコメブロックする方法(不完全)

「Dummy_ID」によるブコメブロックしたい場合、同じくMy Filtersで、

hatena.ne.jp##.entry-comment-contents:has(a[href*="Dummy_ID"])

を追加すれば消えるのだけど、これだとDummy_IDスターを付けられたブコメまで消えてしまう。もうちょっと調べればなんとかなりそう。

Permalink |記事への反応(2) | 23:50

このエントリーをはてなブックマークに追加ツイートシェア

2017-11-24

はてなブックマークCSSデザイン統一について

ここのところ思い出したかのように時々リニューアルが行われてるはてなブックマークデザインだけどさ。

少し前にリニューアルされたお気に入りページは、#left-container #center-container #right-container って、要するにdivタグidを振り分けて3ペインデザインを実現しているんだけれども、先日リニューアルされたユーザーブックマーク一覧ページは .left-container .center-container .right-container って、divタグclassを振り分けて3ペインデザインを実現しているのね。

こういう全体で1度しか使わないデザイン上の区切り指定するのにidを振るかclassを振るかってのは正直好みの問題でもあって、header,footer的なものidから3ペインidだろとか、優先順位とか管理やすいかclassでもいいだろとか宗教問題にもなりそうではあるんだけれど、同じ会社が作っている同じサービスほとんど同じページ表示に別の形式での記述がされているのはデザイナー間での事前定義と言うか意思疎通がされていないってことでもあってかなりマズいことじゃないのかな。

何かリニューアルするたびに「まともに仕事できないのかはてなデザイナーは」って揶揄されるけど、実際はてなデザイナーチーム、チーム内で大変なことになってるんじゃないか経営陣その辺ちゃんと把握してるか?

Permalink |記事への反応(0) | 10:32

このエントリーをはてなブックマークに追加ツイートシェア

2017-07-06

はてブの新ユーザページ用ユーザスタイルシートを書いた

ずっと旧ページ使ってて、どうにも窮屈な感じがしたので。

.wrapper-container-inner{box-sizing:border-box;width:100%;padding:20px20px0;background-image:none;}#right-container{display:none;}#center-container{box-sizing:border-box;padding:00020px;width:calc(100% -180px);}

カラムは消した。

あくまで広くしただけ。

幅が広すぎる!って場合最後の width:calc(100% - 180px); にある100%の値を調整すればいい。

にしても、まさかレイアウトでfloat使ってるとは思わなかった。

いろいろ見ててCSSレガシーすぎて大変なんだろうなー、と思った。

Permalink |記事への反応(1) | 15:34

このエントリーをはてなブックマークに追加ツイートシェア

2017-07-04

https://anond.hatelabo.jp/20170703143955

なんでPC 画面がワイド化してんのに、ブコメ表示部がこんなに幅狭いんだよ……。というわけで、お気に入りページのサイドバーサムネイル消して表示幅を広げるユーザースタイルシート

.wrapper-container-inner{width:90%;}#center-container{width:100%;}#left-container,#right-container,.entry-image-block{display:none;}.wrapper-container-inner.left-column-line{background-image:none;}.entry-title,.entry-blockblockquote,.entry-data,.user-comment-meta,.starContainer{display:inline;}.profile-image{width:1.2em!important;height:1.2em!important;}

サイドバー区切りの縦線を消せてないけど、とりあえず。

縦線の消し方をブコメで教わりました。ありがとうございます! >id:ikihaji_kun

追記

要約文を消してさらに縦を圧縮するなら、以下を追加すればよいですね。

ガッツリ消す
.entry-blockblockquote{display:none;}
あとで読む」あたりは残す
.entry-summary{display:none}

Permalink |記事への反応(2) | 00:37

このエントリーをはてなブックマークに追加ツイートシェア

2009-03-08

XAMPPMySQL文字化け

バージョン2.5

phpとかデータベースをutf8に統一した上で

my.cnfに以下の内容を書き込む。

[client]

default-character-set = utf8

[mysqld]

skip-character-set-client-handshake

default-character-set = utf8

character-set-server = utf8

collation-server = utf8_general_ci

init-connect =SET NAMES utf8

[mysqldump]

default-character-set = utf8

[mysql]

default-character-set = utf8

Permalink |記事への反応(0) | 03:59

このエントリーをはてなブックマークに追加ツイートシェア

2008-09-13

これはひどい

http://kago.in/portal/index.php?url=<>

Warning: file_get_contents(http://api.pathtraq.com/pages?url=&lt;&gt;&amp;m=popular) [function.file-get-contents]: failed toopen stream:HTTP request failed!HTTP/1.1 400 Bad Request in /virtual/kago/public_html/portal/index.php on line 25Warning: file_get_contents(http://api.search.yahoo.co.jp/ImageSearchService/V1/imageSearch?appid=_DG85xqxg66_I.XOwI8HXsFIoVCrj7wuyv4HstVVzMq.Eq5NFShOxteUK6FlXyPB9BFCYw--&amp;query=&lt;&gt;&amp;results=50) [function.file-get-contents]: failed toopen stream:HTTP request failed!HTTP/1.1 400 Bad Request in /virtual/kago/public_html/portal/index.php on line 32Warning: file_get_contents(http://www.2chsearch.net/api/list?q=&lt;&gt;&amp;mode=html) [function.file-get-contents]: failed toopen stream:HTTP request failed!HTTP/1.1 500Internal Server Error in /virtual/kago/public_html/portal/index.php on line 42

Permalink |記事への反応(0) | 13:57

このエントリーをはてなブックマークに追加ツイートシェア

2008-02-19

はてなブックマーク2ちゃんねるっぽくするユーザースタイルシート

インスパイヤ元 -http://anond.hatelabo.jp/20080219145538

@-moz-document domain("b.hatena.ne.jp"){ul#bookmarked_user{font-size:105%;}#bookmarked_userli{list-style-type:decimal;}#bookmarked_userli:before{    content:'\FF1A';}#bookmarked_user.timestamp:before{    content:'\756A\7D44\306E\9014\4E2D\3067\3059\304C\306F\3066\306A\3067\3059\FF1A';font-size: 110%;font-weight: bold;color:#008000;}#bookmarked_userimg.hatena-id-icon,#bookmarked_user.user-tag,#bookmarked_user.hatena-star-comment-container,#bookmarked_user.hatena-star-star-container{display:none;}#bookmarked_usera[href*='bookmark-']:before{    content:'ID:';}#bookmarked_usera[href*='bookmark-']:link,#bookmarked_usera[href*='bookmark-']:hover{color: black;text-decoration: none;}#bookmarked_usera[href*='bookmark-']:hover{color:blue;text-decoration: underline;}#bookmarked_userspan.comment{display:block;padding:8px1em;margin-left:1.5em;}}

曜日の表記と「2008年02月19日」を「2008/02/19」にしたかったが、方法が分からなかった。あ、あと投稿時間も。Greasemonkey じゃないと無理か?

追記

転載・改変は自由なので、再利用したいとかここを変えた方がより良い、という方は好きに使って結構です。

追記2

はてブちゃんねる

はてなブックマーク2ちゃんねる風に見せるサービスktkr

「はてブちゃんねる」を作った - mayokara memo

Permalink |記事への反応(1) | 17:13

このエントリーをはてなブックマークに追加ツイートシェア

2007-07-19

/* Ten */if (typeof(Ten) == 'undefined') {    Ten = {};}Ten.NAME = 'Ten';Ten.VERSION = 0.06;/* Ten.Class */Ten.Class = function(klass,prototype) {    if (klass && klass.initialize) {var c = klass.initialize;    } else if(klass && klass.base) {        var c = function() { return klass.base[0].apply(this, arguments) };    } else {var c = function() {};    }    c.prototype =prototype || {};    c.prototype.constructor = c;    Ten.Class.inherit(c, klass);    if (klass && klass.base) {        for (var i = 0;  i < klass.base.length; i++) {    var parent = klass.base[i];            if (i == 0) {                c.SUPER = parent;                c.prototype.SUPER = parent.prototype;            }            Ten.Class.inherit(c, parent);            Ten.Class.inherit(c.prototype, parent.prototype);        }    }    return c;}Ten.Class.inherit = function(child,parent) {    for (varprop in parent) {        if (typeof(child[prop]) != 'undefined' ||prop == 'initialize')continue;        child[prop] = parent[prop];    }}/*//Basic Ten Classes**//* Ten.JSONP */Ten.JSONP = new Ten.Class({    initialize: function(uri,obj,method) {        if (Ten.JSONP.Callbacks.length) {            setTimeout(function() {new Ten.JSONP(uri,obj,method)}, 500);            return;        }        var del =uri.match(/\?/) ? '&' : '?';uri += del + 'callback=Ten.JSONP.callback';        if (!uri.match(/timestamp=/)) {uri += '&' + encodeURI(new Date());        }        if (obj && method) Ten.JSONP.addCallback(obj,method);        this.script = document.createElement('script');        this.script.src =uri;        this.script.type = 'text/javascript';        document.getElementsByTagName('head')[0].appendChild(this.script);    },    addCallback: function(obj,method) {        Ten.JSONP.Callbacks.push({object: obj, method: method});    },    callback: function(args) {        // alert('callback called');        var cbs = Ten.JSONP.Callbacks;        for (var i = 0; i < cbs.length; i++) {            varcb = cbs[i];cb.object[cb.method].call(cb.object, args);        }        Ten.JSONP.Callbacks = [];    },    MaxBytes: 8000,    Callbacks: []});/* Ten.XHR */Ten.XHR = new Ten.Class({    initialize: function(uri,opts,obj,method) {        if (!uri) return;        this.request = Ten.XHR.getXMLHttpRequest();        this.callback = {object: obj, method: method};        var xhr = this;        var prc = this.processReqChange;        this.request.onreadystatechange = function() {            prc.apply(xhr, arguments);        }        var method = opts.method || 'GET';        this.request.open(method,uri, true);        if (method == 'POST') {            this.request.setRequestHeader('Content-Type',                                          'application/x-www-form-urlencoded');        }        var data = opts.data ? Ten.XHR.makePostData(opts.data) : null;        this.request.send(data);    },    getXMLHttpRequest: function() {        var xhr;        var tryThese = [            function () { return newXMLHttpRequest(); },            function () { return new ActiveXObject('Msxml2.XMLHTTP'); },            function () { return new ActiveXObject('Microsoft.XMLHTTP'); },            function () { return new ActiveXObject('Msxml2.XMLHTTP.4.0'); },        ];        for (var i = 0; i < tryThese.length; i++) {            var func = tryThese[i];            try {                xhr = func;                return func();            } catch (e) {                //alert(e);            }        }        return xhr;    },    makePostData: function(data) {        var pairs = [];        varregexp = /%20/g;        for (var k in data) {            var v = data[k].toString();            var pair = encodeURIComponent(k).replace(regexp,'+') + '=' +                encodeURIComponent(v).replace(regexp,'+');            pairs.push(pair);        }        return pairs.join('&');    }},{    processReqChange: function() {        var req = this.request;        if (req.readyState == 4) {            if (req.status == 200) {                varcb = this.callback;cb.object[cb.method].call(cb.object, req);            } else {                alert("There was a problem retrieving theXML data:\n" +                      req.statusText);            }        }    }});/* Ten.Observer */Ten.Observer = new Ten.Class({    initialize: function(element,event,obj,method) {        var func = obj;        if (typeof(method) == 'string') {            func = obj[method];        }        this.element = element;        this.event = event;        this.listener = function(event) {            return func.call(obj, new Ten.Event(event || window.event));        }        if (this.element.addEventListener) {            if (this.event.match(/^on(.+)$/)) {                this.event =RegExp.$1;            }            this.element.addEventListener(this.event, this.listener, false);        } else if (this.element.attachEvent) {            this.element.attachEvent(this.event, this.listener);        }    }},{    stop: function() {        if (this.element.removeEventListener) {            this.element.removeEventListener(this.event,this.listener,false);        } else if (this.element.detachEvent) {            this.element.detachEvent(this.event,this.listener);        }    }});/* Ten.Event */Ten.Event = new Ten.Class({    initialize: function(event) {        this.event = event;    },    keyMap: {        8:"backspace", 9:"tab", 13:"enter", 19:"pause", 27:"escape", 32:"space",        33:"pageup", 34:"pagedown", 35:"end", 36:"home", 37:"left", 38:"up",        39:"right", 40:"down", 44:"printscreen", 45:"insert", 46:"delete",        112:"f1", 113:"f2", 114:"f3", 115:"f4", 116:"f5", 117:"f6", 118:"f7",        119:"f8", 120:"f9", 121:"f10", 122:"f11", 123:"f12",        144:"numlock", 145:"scrolllock"    }},{    mousePosition: function() {        if (!this.event.clientX) return;        return Ten.Geometry.getMousePosition(this.event);    },    isKey: function(name) {        var ecode = this.event.keyCode;        if (!ecode) return;        var ename = Ten.Event.keyMap[ecode];        if (!ename) return;        return (ename ==name);    },    targetIsFormElements: function() {        var target = this.event.target;        if (!target) return;        var T = (target.tagName || '').toUpperCase();        return (T == 'INPUT' || T == 'SELECT' || T == 'OPTION' ||                T == 'BUTTON' || T == 'TEXTAREA');    },    stop: function() {        var e = this.event;        if (e.stopPropagation) {            e.stopPropagation();            e.preventDefault();        } else {            e.cancelBubble = true;            e.returnValue = false;        }    }});/* Ten.DOM */Ten.DOM = new Ten.Class({    getElementsByTagAndClassName: function(tagName, className, parent) {        if (typeof(parent) == 'undefined') {            parent = document;        }        var children = parent.getElementsByTagName(tagName);        if (className) {             var elements = [];            for (var i = 0; i < children.length; i++) {                var child = children[i];                var cls = child.className;                if (!cls) {continue;                }                var classNames = cls.split(' ');                for (var j = 0; j < classNames.length; j++) {                    if (classNames[j] == className) {                        elements.push(child);                        break;                    }                }            }            return elements;        } else {            return children;        }    },    removeEmptyTextNodes: function(element) {        var nodes = element.childNodes;        for (var i = 0; i < nodes.length; i++) {            var node = nodes[i];            if (node.nodeType == 3 && !/\S/.test(node.nodeValue)) {                node.parentNode.removeChild(node);            }        }    },    nextElement: function(elem) {        do {            elem = elem.nextSibling;        } while (elem && elem.nodeType != 1);        return elem;    },    prevElement: function(elem) {        do {            elem = elem.previousSibling;        } while (elem && elem.nodeType != 1);        return elem;    },    scrapeText: function(node) {        var rval = [];        (function (node) {            var cn = node.childNodes;            if (cn) {                for (var i = 0; i < cn.length; i++) {                    arguments.callee.call(this, cn[i]);                }            }            var nodeValue = node.nodeValue;            if (typeof(nodeValue) == 'string') {                rval.push(nodeValue);            }        })(node);        return rval.join('');    },    onLoadFunctions: [],    loaded: false,    timer: null,    addEventListener: function(event,func) {        if (event != 'load') return;        Ten.DOM.onLoadFunctions.push(func);        Ten.DOM.checkLoaded();    },    checkLoaded: function() {        var c = Ten.DOM;        if (c.loaded) return true;        if (document && document.getElementsByTagName &&            document.getElementById && document.body) {            if (c.timer) {                clearInterval(c.timer);                c.timer = null;            }            for (var i = 0; i < c.onLoadFunctions.length; i++) {                    c.onLoadFunctions[i]();            }            c.onLoadFunctions = [];            c.loaded = true;        } else {            c.timer = setInterval(c.checkLoaded, 13);        }    }});/* Ten.Style */Ten.Style = new Ten.Class({    applyStyle: function(elem, style) {        for (prop in style) {            elem.style[prop] = style[prop];        }    }});/* Ten.Geometry */Ten.Geometry = new Ten.Class({    initialize: function() {        if (Ten.Geometry._initialized) return;        var func = Ten.Geometry._functions;        var de = document.documentElement;        if (window.innerWidth) {            func.getWindowWidth = function() { return window.innerWidth; }            func.getWindowHeight = function() { return window.innerHeight; }            func.getXScroll = function() { return window.pageXOffset; }            func.getYScroll = function() { return window.pageYOffset; }        } else if (de && de.clientWidth) {            func.getWindowWidth = function() { return de.clientWidth; }            func.getWindowHeight = function() { return de.clientHeight; }            func.getXScroll = function() { return de.scrollLeft; }            func.getYScroll = function() { return de.scrollTop; }        } else if (document.body.clientWidth) {            func.getWindowWidth = function() { return document.body.clientWidth; }            func.getWindowHeight = function() { return document.body.clientHeight; }            func.getXScroll = function() { return document.body.scrollLeft; }            func.getYScroll = function() { return document.body.scrollTop; }        }        Ten.Geometry._initialized = true;    },    _initialized: false,    _functions: {},    getScroll: function() {        if (!Ten.Geometry._initialized) new Ten.Geometry;        return {            x: Ten.Geometry._functions.getXScroll(),            y: Ten.Geometry._functions.getYScroll()        };    },    getMousePosition: function(pos) {        //pos should have clientX, clientY sameas mouse event        if ((navigator.userAgent.indexOf('Safari') > -1) &&            (navigator.userAgent.indexOf('Version/') < 0)) {            return {                x:pos.clientX,                y:pos.clientY            };        } else {            var scroll = Ten.Geometry.getScroll();            return {                x:pos.clientX + scroll.x,                y:pos.clientY + scroll.y            };        }    },    getElementPosition: function(e) {        return {            x: e.offsetLeft,            y: e.offsetTop        };    },    getWindowSize: function() {        if (!Ten.Geometry._initialized) new Ten.Geometry;        return {            w: Ten.Geometry._functions.getWindowWidth(),            h: Ten.Geometry._functions.getWindowHeight()        };    }});/* Ten.Position */Ten.Position = new Ten.Class({    initialize: function(x,y) {        this.x = x;        this.y = y;    },    subtract: function(a,b) {        return new Ten.Position(a.x - b.x, a.y - b.y);    }});/*//require Ten.js**//* Ten.SubWindow */Ten.SubWindow = new Ten.Class({    initialize: function() {        var c = this.constructor;        if (c.singleton && c._cache) {            return c._cache;        }        var div = document.createElement('div');        Ten.Style.applyStyle(div, Ten.SubWindow._baseStyle);        Ten.Style.applyStyle(div, c.style);        this.window = div;        this.addContainerAndCloseButton();        document.body.appendChild(div);        if (c.draggable) {            this._draggable = new Ten.Draggable(div, this.handle);        }        if (c.singleton) c._cache = this;        return this;    },    _baseStyle: {color: '#000',        position: 'absolute',        display: 'none',        zIndex: 2,        left: 0,top: 0,        backgroundColor: '#fff',border: '1px solid #bbb'    },    style: {padding: '2px',        textAlign: 'center',        borderRadius: '6px',        MozBorderRadius: '6px',        width: '100px',        height: '100px'    },    handleStyle: {        position: 'absolute',top: '0px',        left: '0px',        backgroundColor: '#f3f3f3',        borderBottom: '1px solid #bbb',        width: '100%',        height: '30px'    },    containerStyle: {margin: '32px 0 0 0',padding: '0 10px'    },    // closeButton: 'close.gif',    closeButton: 'http://s.hatena.com/images/close.gif',    closeButtonStyle: {        position: 'absolute',top: '8px',        right: '10px',        cursor: 'pointer'    },    _baseScreenStyle: {        position: 'absolute',top: '0px',        left: '0px',        display: 'none',        zIndex: 1,overflow: 'hidden',        width: '100%',        height: '100%'    },    screenStyle: {},    showScreen: true,singleton: true,    draggable: true,    _cache: null},{screen: null,    windowObserver: null,    visible: false,    addContainerAndCloseButton: function() {        varwin = this.window;        var c = this.constructor;        var div = document.createElement('div');win.appendChild(div);        Ten.Style.applyStyle(div, c.containerStyle);        this.container = div;        if (c.handleStyle) {            var handle = document.createElement('div');            Ten.Style.applyStyle(handle, c.handleStyle);win.appendChild(handle);            this.handle = handle;        }        if (c.closeButton) {    var btn = document.createElement('img');            btn.src = c.closeButton;            btn.alt = 'close';            Ten.Style.applyStyle(btn, c.closeButtonStyle);win.appendChild(btn);            new Ten.Observer(btn, 'onclick', this, 'hide');            this.closeButton = btn;        }        if (c.showScreen) {            varscreen = document.createElement('div');            Ten.Style.applyStyle(screen, Ten.SubWindow._baseScreenStyle);            Ten.Style.applyStyle(screen, c.screenStyle);            document.body.appendChild(screen);            this.screen =screen;            new Ten.Observer(screen, 'onclick', this, 'hide');        }    },    show: function(pos) {pos = (pos.x &&pos.y) ?pos : {x:0, y:0};        with (this.window.style) {            display = 'block';            left =pos.x + 'px';top =pos.y + 'px';        }        if (this.screen) {            with (this.screen.style) {                display = 'block';                left = Ten.Geometry.getScroll().x + 'px';top = Ten.Geometry.getScroll().y + 'px';            }        }        this.windowObserver = new Ten.Observer(document.body, 'onkeypress', this, 'handleEscape');        this.visible = true;    },    handleEscape: function(e) {        if (!e.isKey('escape')) return;        this.hide();    },hide: function() {        if (this._draggable) this._draggable.endDrag();        this.window.style.display = 'none';        if (this.screen) this.screen.style.display = 'none';        if (this.windowObserver) this.windowObserver.stop();        this.visible = false;    }});/* Ten.Draggable */Ten.Draggable = new Ten.Class({    initialize: function(element,handle) {        this.element = element;        this.handle = handle || element;        this.startObserver = new Ten.Observer(this.handle, 'onmousedown', this, 'startDrag');        this.handlers = [];    }},{    startDrag: function(e) {        if (e.targetIsFormElements()) return;        this.delta = Ten.Position.subtract(            e.mousePosition(),            Ten.Geometry.getElementPosition(this.element)        );        this.handlers = [            new Ten.Observer(document, 'onmousemove', this, 'drag'),            new Ten.Observer(document, 'onmouseup', this, 'endDrag'),            new Ten.Observer(this.element, 'onlosecapture', this, 'endDrag')        ];        e.stop();    },    drag: function(e) {        varpos = Ten.Position.subtract(e.mousePosition(), this.delta);        Ten.Style.applyStyle(this.element, {            left:pos.x + 'px',top:pos.y + 'px'        });        e.stop();    },    endDrag: function(e) {        for (var i = 0; i < this.handlers.length; i++) {            this.handlers[i].stop();        }        if(e) e.stop();    }});/*Hatena */if (typeof(Hatena) == 'undefined') {Hatena = {};}/*Hatena.User */Hatena.User = new Ten.Class({    initialize: function(name) {        this.name =name;    },    getProfileIcon: function(name) {        if (!name)name = 'user';        var pre =name.match(/^[\w-]{2}/)[0];        var img = document.createElement('img');        img.src = 'http://www.hatena.ne.jp/users/' + pre + '/' +name + '/profile_s.gif';        img.alt =name;        img.setAttribute('class', 'profile-icon');        img.setAttribute('width','16px');        img.setAttribute('height','16px');        with (img.style) {margin = '0 3px';border = 'none';            verticalAlign = 'middle';        }        return img;    }}, {    profileIcon: function() {        returnHatena.User.getProfileIcon(this.name);    }});/*Hatena.Star */if (typeof(Hatena.Star) == 'undefined') {Hatena.Star = {};}/*//Hatena.Star.* classes //**/if (window.location && window.location.host.match(/hatena\.com/)) {Hatena.Star.BaseURL = 'http://s.hatena.com/';} else {Hatena.Star.BaseURL = 'http://s.hatena.ne.jp/';}Hatena.Star.Token = null;/*Hatena.Star.User */Hatena.Star.User = new Ten.Class({base:[Hatena.User],    initialize: function(name) {        if (Hatena.Star.User._cache[name]) {            returnHatena.Star.User._cache[name];        } else {            this.name =name;Hatena.Star.User._cache[name] = this;            return this;        }    },    _cache: {}},{    userPage: function() {        returnHatena.Star.BaseURL + this.name + '/';    }});/*Hatena.Star.Entry */Hatena.Star.Entry = new Ten.Class({    initialize: function(e) {        this.entry = e;        this.uri = e.uri;        this.title = e.title;        this.star_container = e.star_container;        this.comment_container = e.comment_container;        this.stars = [];        this.comments = [];    },    maxStarCount: 11},{    flushStars: function() {        this.stars = [];        this.star_container.innerHTML = '';    },    bindStarEntry: function(se) {        this.starEntry =se;        for (var i = 0; i <se.stars.length; i++) {            if (typeof(se.stars[i]) == 'number') {                this.stars.push(newHatena.Star.InnerCount(se.stars[i],this));            } else {                this.stars.push(newHatena.Star.Star(se.stars[i]));            }        }        if (se.comments && !this.comments.length) {            for (var i = 0; i <se.comments.length; i++) {                this.comments.push(newHatena.Star.Comment(se.comments[i]));            }        }        this.can_comment =se.can_comment;    },    setCanComment: function(v) {        this.can_comment = v;    },    showButtons: function() {        this.addAddButton();        this.addCommentButton();    },    addAddButton: function() {        if (this.star_container) {            this.addButton = newHatena.Star.AddButton(this);            this.star_container.appendChild(this.addButton);        }    },    addCommentButton: function() {        if (this.comment_container) {            this.commentButton = newHatena.Star.CommentButton(this);            this.comment_container.appendChild(this.commentButton.img);        }    },    showStars: function() {        var klass = this.constructor;        // if (this.stars.length > klass.maxStarCount) {        //     varic = newHatena.Star.InnerCount(this.stars.slice(1,this.stars.length));        //     this.star_container.appendChild(this.stars[0]);        //     this.star_container.appendChild(ic);        //     this.star_container.appendChild(this.stars[this.stars.length - 1]);        // } else {        for (var i = 0; i < this.stars.length; i++) {            this.star_container.appendChild(this.stars[i]);        }    },    showCommentButton: function() {        if (this.can_comment) {            this.commentButton.show();            if (this.comments.length) this.commentButton.activate();        } else {            // this.commentButton.hide();        }    },    addStar: function(star) {        this.stars.push(star);        this.star_container.appendChild(star);    },    addComment: function(com) {        if (!this.comments) this.comments = [];        if (this.comments.length == 0) {            this.commentButton.activate();        }        this.comments.push(com);    },    showCommentCount: function() {        this.comment_container.innerHTML += this.comments.length;    }});/*Hatena.Star.Button */Hatena.Star.Button = new Ten.Class({    createButton: function(args) {        var img = document.createElement('img');        img.src = args.src;        img.alt = img.title = args.alt;        with (img.style) {    cursor = 'pointer';margin = '0 3px';padding = '0';border = 'none';            verticalAlign = 'middle';        }        return img;    }});/*Hatena.Star.AddButton */Hatena.Star.AddButton = new Ten.Class({base: ['Hatena.Star.Button'],    initialize: function(entry) {        this.entry = entry;        this.lastPosition = null;        var img =Hatena.Star.Button.createButton({src:Hatena.Star.AddButton.ImgSrc,            alt: 'Add Star'        });        this.observer = new Ten.Observer(img,'onclick',this,'addStar');        this.img = img;        return img;    },    ImgSrc:Hatena.Star.BaseURL + 'images/add.gif'},{    addStar: function(e) {        this.lastPosition = e.mousePosition();        varuri =Hatena.Star.BaseURL + 'star.add.json?uri=' + encodeURIComponent(this.entry.uri) +            '&title=' + encodeURIComponent(this.entry.title);        if (Hatena.Star.Token) {uri += '&token=' +Hatena.Star.Token;        }        new Ten.JSONP(uri, this, 'receiveResult');    },    receiveResult: function(args) {        varname = args ? args.name : null;        if (name) {            this.entry.addStar(newHatena.Star.Star({name:name}));            //alert('Succeeded in Adding Star ' + args);        } else if (args.errors) {            varpos = this.lastPosition;pos.x -= 10;pos.y += 25;            var scroll = Ten.Geometry.getScroll();            var scr = newHatena.Star.AlertScreen();            var alert = args.errors[0];            scr.showAlert(alert,pos);        }    }});/*Hatena.Star.CommentButton */Hatena.Star.CommentButton = new Ten.Class({base: ['Hatena.Star.Button'],    initialize: function(entry) {        this.entry = entry;        this.lastPosition = null;        var img =Hatena.Star.Button.createButton({src:Hatena.Star.CommentButton.ImgSrc,            alt: 'Comments'        });        img.style.display = 'none';        this.observer = new Ten.Observer(img,'onclick',this,'showComments');        this.img = img;    },    ImgSrc:Hatena.Star.BaseURL + 'images/comment.gif',    ImgSrcActive:Hatena.Star.BaseURL + 'images/comment_active.gif'},{    showComments: function(e) {        if (!this.screen) this.screen = newHatena.Star.CommentScreen();        this.screen.bindEntry(this.entry);        varpos = e.mousePosition();pos.y += 25;        this.screen.showComments(this.entry,pos);    },hide: function() {        this.img.style.display = 'none';    },    show: function() {        this.img.style.display = 'inline';    },    activate: function() {        this.show();        this.img.src =Hatena.Star.CommentButton.ImgSrcActive;    }});/*Hatena.Star.Star */Hatena.Star.Star = new Ten.Class({    initialize: function(args) {        if (args.img) {            this.img = args.img;            this.name = this.img.getAttribute('alt');        } else {            this.name = args.name;            var img = document.createElement('img');            img.src =Hatena.Star.Star.ImgSrc;            img.alt = this.name;            with (img.style) {padding = '0';border = 'none';            }            this.img = img;        }new Ten.Observer(this.img,'onmouseover',this,'showName');new Ten.Observer(this.img,'onmouseout',this,'hideName');if (this.name) {            this.user = newHatena.Star.User(this.name);            this.img.style.cursor = 'pointer';            new Ten.Observer(this.img,'onclick',this,'goToUserPage');        }        if (args.count && args.count > 1) {            var c = document.createElement('span');            c.setAttribute('class', 'hatena-star-inner-count');            Ten.Style.applyStyle(c,Hatena.Star.InnerCount.style);            c.innerHTML = args.count;            var s = document.createElement('span');            s.appendChild(img);            s.appendChild(c);            return s;        } else {            return this.img;        }    },    ImgSrc:Hatena.Star.BaseURL + 'images/star.gif'},{    showName: function(e) {        if (!this.screen) this.screen = newHatena.Star.NameScreen();        varpos = e.mousePosition();pos.x += 10;pos.y += 25;        this.screen.showName(this.name,pos);    },    hideName: function() {        if (!this.screen) return;        this.screen.hide();    },    goToUserPage: function() {        window.location = this.user.userPage();    }});/*Hatena.Star.InnerCount */Hatena.Star.InnerCount = new Ten.Class({    initialize: function(count, e) {        this.count = count;        this.entry = e;        var c = document.createElement('span');        c.setAttribute('class', 'hatena-star-inner-count');        Ten.Style.applyStyle(c,Hatena.Star.InnerCount.style);        c.style.cursor = 'pointer';        c.innerHTML = count;        new Ten.Observer(c,'onclick',this,'showInnerStars');        this.container = c;        return c;    },    style: {color: '#f4b128',        fontWeight: 'bold',        fontSize: '80%',        fontFamily: '"arial", sans-serif',margin: '0 2px'    }},{    showInnerStars: function() {        varurl =Hatena.Star.BaseURL + 'entry.json?uri=' +        encodeURIComponent(this.entry.uri);        new Ten.JSONP(url, this, 'receiveStarEntry');    },    receiveStarEntry: function(res) {        varse = res.entries[0];        var e = this.entry;        if (encodeURIComponent(se.uri) != encodeURIComponent(e.uri)) return;        e.flushStars();        e.bindStarEntry(se);        e.addAddButton();        e.showStars();    }});/*Hatena.Star.Comment */Hatena.Star.Comment = new Ten.Class({    initialize: function(args) {        this.name = args.name;        this.body = args.body;    }},{    asElement: function() {        var div = document.createElement('div');        with (div.style) {margin = '0px 0';padding = '5px 0';            borderBottom = '1px solid #ddd';        }        varico =Hatena.User.getProfileIcon(this.name);        div.appendChild(ico);        var span = document.createElement('span');        with(span.style) {            fontSize = '90%';        }        span.innerHTML = this.body;        div.appendChild(span);        return div;    }});/*Hatena.Star.NameScreen */Hatena.Star.NameScreen = new Ten.Class({base: [Ten.SubWindow],    style: {padding: '2px',        textAlign: 'center'    },    containerStyle: {margin: 0,padding: 0    },    handleStyle: null,    showScreen: false,    closeButton: null,    draggable: false},{    showName: function(name,pos) {        this.container.innerHTML = '';        this.container.appendChild(Hatena.User.getProfileIcon(name));        this.container.appendChild(document.createTextNode(name));        this.show(pos);    }});/*Hatena.Star.AlertScreen */Hatena.Star.AlertScreen = new Ten.Class({base: [Ten.SubWindow],    style: {padding: '2px',        textAlign: 'center',        borderRadius: '6px',        MozBorderRadius: '6px',        width: '240px',        height: '120px'    },    handleStyle: {        position: 'absolute',top: '0px',        left: '0px',        backgroundColor: '#f3f3f3',        borderBottom: '1px solid #bbb',        width: '100%',        height: '30px',        borderRadius: '6px 6px 0 0',        MozBorderRadius: '6px 6px 0 0'    }},{    showAlert: function(msg,pos) {        this.container.innerHTML = msg;        varwin = Ten.Geometry.getWindowSize();        var scr = Ten.Geometry.getScroll();        var w = parseInt(this.constructor.style.width) + 20;        if (pos.x + w > scr.x +win.w)pos.x =win.w + scr.x - w;        this.show(pos);    }});/*Hatena.Star.CommentScreen */Hatena.Star.CommentScreen = new Ten.Class({base: [Ten.SubWindow],    initialize: function() {        var self = this.constructor.SUPER.call(this);        if (!self.commentsContainer) self.addCommentsContainer();        return self;    },    style: {        width: '280px',        height: '280px',        overflowY: 'auto',padding: '2px',        textAlign: 'center',        borderRadius: '6px',        MozBorderRadius: '6px'    },    handleStyle: {        position: 'absolute',top: '0px',        left: '0px',        backgroundColor: '#f3f3f3',        borderBottom: '1px solid #bbb',        width: '100%',        height: '30px',        borderRadius: '6px 6px 0 0',        MozBorderRadius: '6px 6px 0 0'    },    containerStyle: {margin: '32px 0 0 0',        textAlign: 'left',padding: '0 10px'    },    getLoadImage: function() {        var img = document.createElement('img');        img.src =Hatena.Star.BaseURL + 'images/load.gif';        img.setAttribute('alt', 'Loading');        with (img.style) {            verticalAlign = 'middle';margin = '0 2px';        }        return img;    }},{    addCommentsContainer: function() {        var div = document.createElement('div');        with (div.style) {            marginTop = '-3px';        }        this.container.appendChild(div);        this.commentsContainer = div;    },    showComments: function(e,pos) {        var comments = e.comments;        if (!comments) comments = [];        this.commentsContainer.innerHTML = '';        for (var i=0; i<comments.length; i++) {            this.commentsContainer.appendChild(comments[i].asElement());        }        if (e.starEntry && !e.can_comment) {            this.hideCommentForm();        } else {            this.addCommentForm();        }        varwin = Ten.Geometry.getWindowSize();        var scr = Ten.Geometry.getScroll();        var w = parseInt(this.constructor.style.width) + 20;        if (pos.x + w > scr.x +win.w)pos.x =win.w + scr.x - w;        this.show(pos);    },    bindEntry: function(e) {        this.entry = e;    },    sendComment: function(e) {        if (!e.isKey('enter')) return;        varbody = this.commentInput.value;        if (!body) return;        this.commentInput.disabled = 'true';        this.showLoadImage();        varurl =Hatena.Star.BaseURL + 'comment.add.json?body=' + encodeURIComponent(body) +            '&uri=' + encodeURIComponent(this.entry.uri) +            '&title=' + encodeURIComponent(this.entry.title);        new Ten.JSONP(url, this, 'receiveResult');    },    receiveResult: function(args) {        if (!args.name || !args.body) return;        this.commentInput.value = '';         this.commentInput.disabled = '';        this.hideLoadImage();        var com = newHatena.Star.Comment(args);        this.entry.addComment(com);        this.commentsContainer.appendChild(com.asElement());    },    showLoadImage: function() {        if (!this.loadImage) return;         this.loadImage.style.display = 'inline';    },    hideLoadImage: function() {        if (!this.loadImage) return;         this.loadImage.style.display = 'none';    },    hideCommentForm: function() {        if (!this.commentForm) return;        this.commentForm.style.display = 'none';    },    addCommentForm: function() {        if (this.commentForm) {            this.commentForm.style.display = 'block';            return;        }        var form = document.createElement('div');        this.container.appendChild(form);        this.commentForm = form;        with (form.style) {margin = '0px 0';padding = '5px 0';            // borderTop = '1px solid #ddd';        }        //if (Hatena.Visitor) {        //    form.appendChild(Hatena.Visitor.profileIcon());        //} else {        //    form.appendChild(Hatena.User.getProfileIcon());        //}        var input = document.createElement('input');        input.type = 'text';        with (input.style) {            width = '215px';border = '1px solid #bbb';padding = '3px';        }        form.appendChild(input);        this.commentInput = input;        var img = this.constructor.getLoadImage();        this.loadImage = img;        this.hideLoadImage();        form.appendChild(img);        new Ten.Observer(input,'onkeypress',this,'sendComment');    }});/*Hatena.Star.EntryLoader */Hatena.Star.EntryLoader = new Ten.Class({    initialize: function() {        var entries =Hatena.Star.EntryLoader.loadEntries();        this.entries = [];        for (var i = 0; i < entries.length; i++) {            var e = newHatena.Star.Entry(entries[i]);            e.showButtons();            this.entries.push(e);        }        this.getStarEntries();    },    createStarContainer: function() {        varsc = document.createElement('span');sc.setAttribute('class', 'hatena-star-star-container');sc.style.marginLeft = '1px';        returnsc;    },    createCommentContainer: function() {        varcc = document.createElement('span');cc.setAttribute('class', 'hatena-star-comment-container');cc.style.marginLeft = '1px';        returncc;    },    scrapeTitle: function(node) {        var rval = [];        (function (node) {            if (node.tagName == 'SPAN' &&                (node.className == 'sanchor' ||                 node.className == 'timestamp')) {                     return;            } else if (node.nodeType == 3 && !/\S/.test(node.nodeValue)) {                return;            }            var cn = node.childNodes;            if (cn) {                for (var i = 0; i < cn.length; i++) {                    arguments.callee.call(this, cn[i]);                }            }            var nodeValue = node.nodeValue;            if (typeof(nodeValue) == 'string') {                rval.push(nodeValue);            }        })(node);        return rval.join('');    },    headerTagAndClassName: ['h3',null],    getHeaders: function() {        var t =Hatena.Star.EntryLoader.headerTagAndClassName;        return Ten.DOM.getElementsByTagAndClassName(t[0],t[1],document);    },    loadEntries: function() {        var entries = [];        //var headers = document.getElementsByTagName('h3');        var c =Hatena.Star.EntryLoader;        var headers = c.getHeaders();        for (var i = 0; i < headers.length; i++) {            var header = headers[i];            var a = header.getElementsByTagName('a')[0];            if (!a)continue;            varuri = a.href;            var title = '';            // Ten.DOM.removeEmptyTextNodes(header);            var cns = header.childNodes;            title = c.scrapeTitle(header);            varcc = c.createCommentContainer();            header.appendChild(cc);            varsc = c.createStarContainer();            header.appendChild(sc);            entries.push({uri:uri,                title: title,                star_container:sc,                comment_container:cc            });        }        return entries;    }},{    getStarEntries: function() {        varurl =Hatena.Star.BaseURL + 'entries.json?';        for (var i = 0; i < this.entries.length; i++) {            if (url.length > Ten.JSONP.MaxBytes) {                new Ten.JSONP(url, this, 'receiveStarEntries');url =Hatena.Star.BaseURL + 'entries.json?';            }url += 'uri=' + encodeURIComponent(this.entries[i].uri) + '&';        }        new Ten.JSONP(url, this, 'receiveStarEntries');    },    receiveStarEntries: function(res) {        var entries = res.entries;        if (!entries) entries = [];        for (var i = 0; i < this.entries.length; i++) {            var e = this.entries[i];            for (var j = 0; j < entries.length; j++) {                varse = entries[j];                if (!se.uri)continue;                if (encodeURIComponent(se.uri) == encodeURIComponent(e.uri)) {                    e.bindStarEntry(se);                    entries.splice(j,1);                    break;                }            }            if (typeof(e.can_comment) == 'undefined') {                e.setCanComment(res.can_comment);            }            e.showStars();            e.showCommentButton();        }    }});/*Hatena.Star.WindowObserver */Hatena.Star.WindowObserver = new Ten.Class({    initialize: funct

Permalink |記事への反応(1) | 17:30

このエントリーをはてなブックマークに追加ツイートシェア

 
ログインユーザー登録
ようこそ ゲスト さん
Copyright (C) 2001-2025 hatena. All Rights Reserved.

[8]ページ先頭

©2009-2025 Movatter.jp