またニコニコ動画見てるグリモンをSeaHorseに移植したけど、割と非推奨

非推奨の理由

  • CSRFの危険性がある(特定URLを踏まされただけでTwitterで発言してしまう)
  • またニコニコ動画見てるをするたびにタブを一つ開いてしまう
  • ポップアップブロックの許可URLを設定しないとそもそも動かない

この辺を分かった上でどうしても使いたい人だけ使うようにしてください。

作った経緯

ぷーるさんが「またニコニコ動画見てる」とTwitterに投稿するリンクを作成するGMスクリプトバージョン0.2を作ったので、
それを移植しようと、iframeを使用したクロスドメインPOSTGM_xmlhttpRequestの代わりにして出来ないかと思ってやってみたものの、
リファラの問題で挫折し、
その後、id:os0xによる=またOperaでニコニコ動画見てるで、
元サイトとPOST先(ニコニコ動画Twitter)両方でuser.jsを読み込ませて
データの受け渡しとPOSTを実現する方法を見て、
これならiframeを使ってPOSTできるというかベタ移植できるんじゃねなどと思ったというのが経緯です。

結果

結果としては、色々なところでつまづき、ぜんぜんベタ移植できませんでした。
以下、つまづく原因となったSeaHorseOperaのuser.jsの差異

  1. user.jsのファイルはShift-JISで読み込まれるっぽい。
    • user.jsが日本語コメントが入ったUTF-8のファイルだと動かない。(割とどうでもいいけど備忘録として)
  2. ページのレスポンスコードが200番以外の場合、実行されないっぽい。
  3. iframeでは実行されない
    • なのでwindow.openで別タブを開く羽目に

3から芋づる式に発生した問題として、

となってしまいました。
SeaHorseをSleipnirScriptとして動かした場合に使えるGM_xmlhttpRequestの代替手段があるそうなので、
そっちを試してもよかったのですが、出来るだけ少ない改変で移植したい、
あわよくばOperaSleipnirで共用できるようにしたいなどとも思っていたので、
こっちの方法で挑戦してみましたが、
ぜんぜん共用どころじゃないので次はそっちでやってみようかと思います。

またニコニコ動画見てる for SeaHorse

// ==UserScript==
// @name      mata nicovideo
// @namespace http://d.hatena.ne.jp/monjudoh/
// @include   http://www.nicovideo.jp/watch/*
// @include   http://twitter.com/statuses/update?ua=mataniconico#*
// @author    monjudoh
// @version   0.1
// ==/UserScript==

(function(){
	if (location.host == 'www.nicovideo.jp') {
		Number.prototype.z = function(len){
			var s = '0'.fill(len) + this.toString();
			return s.substr(s.length - len);
		};
		String.prototype.fill = function(len){
			var result = '';
			for(var i = 0; i < len; i++) result += this;
			return result;
		};

		var h1 = document.getElementsByTagName('h1')[0];
		if(!h1) return;
		var span = document.createElement('span');
		h1.parentNode.insertBefore(span, h1);
		
		var a = document.createElement('a');
		a.appendChild(document.createTextNode('[\u307e\u305f\u898b\u3066\u308b]'));
		a.href = 'javascript:void(0);';
		a.attachEvent('onclick',
			function(){
				var srcElem = window.event.srcElement;
				srcElem.parentNode.removeChild(srcElem);
				
				var text = document.createElement('input');
				text.type = 'text';
				text.value = '';
				text.size = 20;
				text.setAttribute('maxlength', 10);
				
				var a = document.createElement('a');
				a.appendChild(document.createTextNode('[\u307e\u305f\u898b\u3066\u308b!]'));
				a.href = 'javascript:void(0);';
				a.attachEvent('onclick',
					function(){
						var len = document.getElementById('flvplayer').GetVariable('ContentLength');
						if(isNaN(len)){
							setTimeout(arguments.callee,1000);
							return;
						}
						var lmin = Math.floor(len / 60);
						var lsec = len % 60;
						var url = [
							'http://twitter.com/statuses/update?ua=mataniconico#'
							,encodeURIComponent([
								'\u307e\u305f\u30cb\u30b3\u30cb\u30b3\u52d5\u753b\u898b\u3066\u308b : '
								,document.title.replace(/[^\-]*-/,'')
								,location.href
								,['(',lmin.z(2) ,':',lsec.z(2),')'].join('')
								,(0 < text.value.length) ? text.value : ''
												].join(' '))].join('');
						window.open(url);
						var srcElem = window.event.srcElement;
						srcElem.parentNode.parentNode.removeChild(srcElem.parentNode);
					});
				span.appendChild(a);
				span.appendChild(text);
				text.focus();
			});
		span.appendChild(a);
	} else if (location.host == 'twitter.com') {
			document.body.innerHTML = '';
			var span = document.createElement('span');
			span.innerHTML = 'wait...';
			document.body.appendChild(span);
			var url = 'http://twitter.com/statuses/update.json';
			var x= new ActiveXObject('Microsoft.XMLHTTP');
			x.open('POST',url,true);
			x.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
			x.onreadystatechange = function() {
				if(x.readyState == 4 && x.status == 200){
					span.innerHTML = 'complete';
				}
			};
			x.send('status=' + location.hash.substring(1));
	}
})();