携帯百景においてワンクリックでnice!をつけよう

2010/01/21 スクリプト更新しました。id:kiwofusi ありがとう!
2010/02/22 特定の写真一枚のページでも動くように更新しました。

JavaScriptは好きだけど、未だにきちんと理解してないAobaです。勉強せな。

さて、携帯百景においてワンクリックでnice!をつけるためだけに

を作りました。「早速インストールだ!」という方は上記リンクからどうぞ。

ソースは残念な感じなので、モダンなJavaScriptに直してTrackbackを頂けたら泣いて喜びます。もういっそ先にお礼を言っておきたい。まだ見ぬそこのJavaScriptギークなあなた!ありがとう!

(Version管理を考えたらCodeReposなどを使うべきか…?)

これを作ってしまった背景

携帯百景で、nice!を1個つけるために2クリックするのがつらかったんだ…」

Twitterユーザーにはおなじみの携帯百景は、かなりユーザー個々の日常に入り込むことに成功しています⇒投稿される写真の数が多い⇒ユーザー数も日々増えている⇒自分が見て「いいなー」と思う写真を撮るユーザーさんもすごい勢いで増えていく⇒自然とFollow数も増えてしまう。

つまり、日を追うごとにnice!をつけるのが大変になっていくのが携帯百景なのだ*1

そして、この情報津波時代、スピードの価値は益々高まっているのだ。

今後の展開予定

なお、携帯百景のサイトでLDRizeを使いたい場合は、ldrize.user.jsの32行目付近にあるSITEINFOの中に、携帯百景向けの設定を書き込んでください。具体的にはこんな感じになります。

const SITEINFO = [
{
name:      '携帯百景',
domain:    '^http://movapic.com/*',
paragraph: '//td[contains(concat(" ",@class," "), " image ")]',
link:      './a',
}
]

Movapic Oneclick Add Nice のソース

// ==UserScript==
// @name           Movapic OneClick Add Nice!
// @namespace      http://d.hatena.ne.jp/Aoba/
// @include        http://movapic.com/*
// @version        1.1
// @description    OneClick de add "nice!" at Movapic
// ==/UserScript==
(function(){
	// 携帯百景に実装されているAutoPagerに対応するためのドキュメント内容監視(こんなやり方しか思いつかなかった)
	var bodyCount = 0;
	var timerId = setInterval(function(){checkBody();}, 500);
	function checkBody() {
		var bodies = document.getElementsByClassName("autopagerize_page_element");
		var targetBody;
		if (bodyCount < bodies.length) {
			targetBody = bodies[bodies.length - 1];
			bodyCount = bodies.length;
		} else if (0 == bodyCount && 0 == bodies.length) {
			targetBody = document.getElementById("content");
			bodyCount = 1;
		}
		if (targetBody) {
			main(targetBody);
			if (window.Minibuffer) {
				// LDRizeを使う場合のみ意味がある処理
				window.setTimeout(function(){window.Minibuffer.execute('LDRize::paragraph-re-collect');}, 10);
			}
		}
	}
	
	function main(doc) {
		var stars = doc.getElementsByClassName('star');
		for(var i = 0, max = stars.length; i < max; i++) {
			var photoId = stars[i].getAttribute("id").match(/^star-(\d+)$/i);
			var photoNum = RegExp.$1;
			var nice = stars[i].getElementsByTagName("a");
			var f = closure(photoNum); // 引数の参照渡しをやめさせる。もっとスマートに実装できる気がする
			
			var elm = document.createElement("input");
			elm.id = "oneclick_add_nice_" + photoNum + "";
			elm.type = "button";
			elm.value = "add nice!";
			elm.addEventListener("click", f, false);
			insertAfter(elm, nice[0]);
		}
	}
	
	function addNice(photoNum) {
		GM_xmlhttpRequest({
			"method" : "POST", 
			"headers" : {"Content-type":"application/x-www-form-urlencoded"},
			"data" : "id=" + photoNum + "",
			"url" : "http://movapic.com/star/add",
			"onload" : function(){getNice(photoNum);}
		});
	}
	
	function getNice(photoNum) {
		GM_xmlhttpRequest({
			"method" : "GET", 
			"data" : "star-" + photoNum + "",
			"url" : "http://movapic.com/star/list/" + photoNum + "",
			"onload" : function(x){writeNice(photoNum, x.responseText)}
		});
	}
	
	function writeNice(photoNum, text){
		var targetDiv = document.getElementById("star-" + photoNum + "");
		targetDiv.innerHTML = text;
	}
	
	function closure(n){
		return function(){addNice(n)}
	}
	
	function insertAfter(newNode, node) {
		return node.parentNode.insertBefore(newNode, node.nextSibling);
	}
})();

余談

そのうち本家が1クリックnice!を実装してくださるような気もしなくもない。

*1:だったらFollowしなきゃいいじゃん…