Index: /lang/javascript/userscripts/twitter.twitterstream.user.js
===================================================================
--- /lang/javascript/userscripts/twitter.twitterstream.user.js (revision 7838)
+++ /lang/javascript/userscripts/twitter.twitterstream.user.js (revision 7838)
@@ -0,0 +1,233 @@
+// ==UserScript==
+// @name           Twitter::TwitterStream
+// @namespace      http://www.mk-colors.org/ns/script
+// @include        http://twitter.com/home*
+// @description    タイムライン中のチェックしたポストを tumblr に会話として投稿
+// @todo           もっと親切にする。
+// ==/UserScript==
+
+(
+	function () {
+		var TwitterStream = {
+			_nodes : []
+		};
+
+		// settings
+		TwitterStream.POST_TITLE = "Twitter Chatting";
+		TwitterStream.POST_TAGS  = "twitter" // comma-separated value
+		TwitterStream.POST_AS_PRIVATE = 1;
+
+		TwitterStream.$E = function (name, props, styles) {
+			var element = document.createElement(name);
+			for ( var name in props ) {
+				element.setAttribute(name, props[name]);
+			}
+			for ( var name in styles ) {
+				element.style[name] = styles[name];
+			}
+			return element;
+		}
+
+		TwitterStream.$D = function (parent, name, props, flag) {
+			var result = [];
+			try {
+				var elements = (parent || document).getElementsByTagName(name || '*');
+				var length   = elements.length;
+				for ( var i = 0; i < length; i++ ) {
+					var element = elements[i];
+					var toPush  = false;
+					if ( props instanceof Object ) {
+						for ( var name in props ) {
+							var value = props[name];
+							var attr  = name.match(/^(?:tag|class)Name$/) ? element[name] : element.getAttribute(name) ;
+							if (
+								attr &&
+								( typeof value == "string" && attr == value ) ||
+								( value instanceof RegExp  && value.test(attr) )
+							) {
+								toPush = true;
+							} else if ( flag == true ) {
+								toPush = false;
+								}
+							if ( toPush ) result.push(element);
+						}
+					} else {
+						result.push(element);
+					}
+				}
+			} catch (e) {
+			}
+			return result;
+		}
+
+		TwitterStream.getPostContent = function (element, icon) {
+			var date  = new Date( Date( TwitterStream.$D(element, "abbr", { className : "published" })[0].title.match(/(\d+)/g) ) );
+			var name  = TwitterStream.$D(element, 'strong')[0].innerHTML;
+			var entry = TwitterStream.$D(element, 'span', { className : /(?:^|\s*)entry\-content(?:\s|$)/ })[0].innerHTML;
+
+			name  = name.replace(/<\/?[^>]+>/gi, "");
+			entry = entry.replace(/^(?:\s|\n)*/, "").replace(/(?:\s|\n)*$/, "");
+			entry = entry.replace(/<\/?[^>]+>/gi, '');
+
+			TwitterStream._nodes.push(icon);
+
+			return {
+				name  : name,
+				date  : date,
+				entry : entry
+			};
+		}
+
+		TwitterStream.createPostBody = function (contents) {
+			var length = contents.length;
+			var body   = "";
+
+			if ( length < 1 ) return false;
+
+			contents.reverse();
+
+			for ( var i = 0; i < length; i++ ) {
+				var content = contents[i];
+				body += content.name + ": " + content.entry + " (" + content.date.toGMTString() + ")\n"; 
+			}
+
+			return body;
+		};
+
+		TwitterStream.createPostData = function (params) {
+			var queries = [];
+			for(var key in params)
+				queries.push(key + '='+ encodeURIComponent(params[key]));
+			return queries.join('&');
+		}
+
+		TwitterStream.getConfigById = function (id, result) {
+			var value = GM_getValue(id, false);
+			if ( !value || !result || result == "failed" ) {
+				value = prompt.call(window, 'enter "' + id + '" to the form.', value);
+				GM_setValue(id, value);
+			}
+			return value;
+		};
+
+		TwitterStream.showResult = function (response) {
+			
+		}
+
+		TwitterStream.executePost = function () {
+			var icons    = TwitterStream.$D(null, 'img', { src : "http://www.tumblr.com/images/favicon.gif" });
+			var length   = icons.length;
+			var contents = [];
+			for ( var i = 0; i < length; i++ ) {
+				var icon      = icons[i];
+				var parent    = icon.parentNode.parentNode;
+				var protected = TwitterStream.$D(parent, 'img', { src : /icon_red_lock\.gif(?:\?\d*)?$/ });
+
+				if ( icon.className == "twitter-stream-post-off" ) continue;
+
+				if ( protected.length > 0 ) {
+					icon.className = "twitter-stream-post-off";
+					continue;
+				}
+
+				contents.push(TwitterStream.getPostContent(parent, icon));
+			}
+
+			var body     = TwitterStream.createPostBody(contents);
+			var result   = GM_getValue('result', false);
+			var email    = TwitterStream.getConfigById('email', result);
+			var password = TwitterStream.getConfigById('password', result);
+
+			if ( body && TwitterStream._nodes.length > 0 ) {
+				var data = TwitterStream.createPostData({
+					title        : TwitterStream.POST_TITLE,
+					conversation : body,
+					date         : (new Date()).toGMTString(),
+					tags         : TwitterStream.POST_TAGS,
+					private      : TwitterStream.POST_AS_PRIVATE,
+					email        : email,
+					password     : password,
+					type         : "conversation",
+				});
+
+				GM_xmlhttpRequest({
+					method  : "POST",
+					url     : "http://www.tumblr.com/api/write",
+					data    : data,
+					headers : {
+						'Content-Type' : 'application/x-www-form-urlencoded'
+					},
+					onload  : function (response) {
+						var request = this;
+						if ( response.status == 201 ) {
+							GM_setValue("result", "suceeded");
+						} else {
+							if ( response.status == 403 ) {
+								GM_setValue("result", "failed");
+							}
+							alert(response.toSource());
+						}
+
+					},
+				});
+
+				while ( TwitterStream._nodes.length ) {
+					var icon = TwitterStream._nodes.shift();
+					icon.className = "twitter-stream-post-off";
+					icon.style.borderColor = "#ffffff";
+				}
+
+				return true;
+			}
+
+			return false;
+		};
+
+		TwitterStream.setPostContent = function (e) {
+			var event   = e;
+			var element = event.currentTarget;
+			if ( element.className == "twitter-stream-post-off" ) {
+				element.className = "twitter-stream-post-on";
+				element.style.borderColor = "#ff0000";
+			} else {
+				element.className = "twitter-stream-post-off";
+				element.style.borderColor = "#ffffff";
+			}
+		};
+
+		TwitterStream.executeFilter = function (docs) {
+			var docs  = docs ? docs[0] : document ;
+			var image = TwitterStream.$E("img", {
+				src    : "http://www.tumblr.com/images/favicon.gif",
+				alt    : "[T]",
+				width  : "13",
+				height : "13"
+			}, {
+				border : "3px solid #ffffff",
+				margin : "auto auto auto 5px"
+			});
+			var entries = TwitterStream.$D(docs, 'span', { className : /(?:^|\s*)entry\-content(?:\s|$)/ });
+			var length  = entries.length;
+
+			for ( var i = 0; i < length; i++ ) {
+				var entry = entries[i];
+				var icon  = image.cloneNode(false);
+				icon.className = "twitter-stream-post-off";
+				icon.addEventListener("click", TwitterStream.setPostContent, false);
+				entry.parentNode.insertBefore(icon, entry.parentNode.lastChild);
+			}
+		};
+
+		if ( window.AutoPagerize && window.AutoPagerize.addFilter ) {
+			setTimeout(
+				function () {
+					window.AutoPagerize.addFilter(TwitterStream.executeFilter);
+					TwitterStream.executeFilter();
+					GM_registerMenuCommand('TwitterStream - post', TwitterStream.executePost)
+				}
+				, 1000
+			);
+		}
+	}
+)();
+
