/* ほぼ、マウス前提なので、Vimperatorらしからぬプラグインですが... 短縮URLはアイテムを選択すると展開されるはず、 あと、画像っぽいURLも展開する(まだ出来るものが少ない) ToDo: YouTubeとかも展開出来るとイイね! == Settings == g:twittperator_plugin_twlist_win = 1 $RUNTIMEDIR/plugin/twittperator に入れている場合は設定してください。 g:twittperator_screen_name = "" g:twlist_max_rows = num 表示するアイテム数 (default: 50) :js liberator.globalVariables.twlist_track_words = [words] 通常は g:twittperator_track_words = "words" で OK だが、 vimp,vimperator など一つのタブにまとめたい時に、 ["vimp,vimperator", "firefox", "javascript"] などとする 当然ながら g:twittperator_track_words の値は必須 == Command == :showtwin ウィンドウの表示/非表示 ToDo: 表示位置と幅、高さを維持したい == Tips == :js plugins.twlistWin.addTrack (word) 新たな word を検索対象にする :js plugins.twlistWin.win.TrackTabs.remove(word) word を検索対象としているタブを削除 Todo: コマンド or オプションで追加削除出来るようにしろ! */ XML.ignoreProcessingInstructions = false; let winXML = <> .toXMLString(); function setStyleSheet() { styles.addSheet(true, "twlist-styles", "data:*", <> tab { max-width: 150px !important; } #twlist-tabs > tab[selected=true] { max-width: 300px !important; } #twlist-command { background-color: white; } .twlist-item-content { -moz-user-select: -moz-all; border-bottom: solid thin silver; } .twlist-item-content[selected=true] { background-color: rgb(240,240,240) !important; color: -moz-fieldtext !important; } .twlist-item-mentioned { background-color: #F0FFFF; } .twlist-rt-mark { color: white; font-weight: bold; background-color: gray; padding: 2px 5px; margin: 0; -moz-border-radius: 4px; } .twlist-reply, .twlist-retweet, .twlist-fav { color: white; font-weight: bold; background-color: gray; padding: 2px; margin:0; -moz-border-radius: 2px; } .twlist-fav { color: yellow; } .twlist-text { margin: 2px 1em; } .twlist-text>label { margin: 1px 2px 2px 2px !important; } .twlist-screenname { font-weight: bold; } .twlist-link { color: -moz-hyperlinktext; } .twlist-link:hover { chrome://browser/content/browser.xul cursor: pointer !important; } .twlist-hash { color: DarkGreen !important; } .twlist-image { max-height: 300px; border:thin solid; } ]]>.toString()); } function addTrack(word){ if (!win) return; win.TrackTabs.add(word); let words = trackWords.split(","), flag = false; word.split(",").forEach(function(w) { if (words.indexOf(w) == -1){ words.push(w); flag = true; } }); if (flag) { plugins.twittperator.TrackingStream.start({track: words.join(",")}); } } function getItemXML(msg) { XML.prettyPrinting = true; XML.ignoreWhitespace = true; let xml; if ("direct_message" in msg) { xml = {formatText(msg.direct_message.text.replace(/[\01-\10\14\16-\37]/g,""))} ; } else if ("retweeted_status" in msg) { xml = {formatText(msg.retweeted_status.text.replace(/[\01-\10\14\16-\37]/g,""))} ; } else { xml = {formatText(msg.text.replace(/[\01-\10\14\16-\37]/g,""))} ; } return xml; } let listener = { userStream: function userStreamListener(msg, raw) { if (!win) return; if ((msg.text && msg.user) || ("direct_message" in msg)) { win.add(msg); } }, trackStream: function trackStreamListener(msg, raw){ if (!win) return; if (msg.text && msg.user){ win.add(msg, true); } } } function onLoad () { let gv = liberator.globalVariables; __context__.__defineGetter__("maxRows", function() gv.twlist_max_rows || 50); __context__.__defineGetter__("trackWords", function() gv.twittperator_track_words || ""); __context__.__defineGetter__("twlistTrack", function() gv.twlist_track_words); __context__.__defineGetter__("win", function() services.get("windowMediator").getMostRecentWindow("twittperator:twlist")); __context__.screenName = gv.twittperator_screen_name ? new RegExp("\\b@" + gv.twittperator_screen_name +"\\b") : null; setStyleSheet(); plugins.twittperator.ChirpUserStream.addListener(listener.userStream); if (trackWords) plugins.twittperator.TrackingStream.addListener(listener.trackStream); commands.addUserCommand(["showtwin"], "popup/hide twittperator window", function(arg){ if (!win) { open() } else { win.close(); } },{ bang: true }, true); plugins.twlistWin = __context__; } function open(){ let URL = "data:application/vnd.mozilla.xul+xml;base64," + btoa(winXML); openDialog(URL, null, "chrome,resizable=yes", liberator, __context__ ); } function onClose(){ } function onUnload () { if (win) win.close(); plugins.twittperator.ChirpUserStream.removeListener(listener.userStream); plugins.twittperator.TrackingStream.removeListener(listener.trackStream); } function getMedia (uri, elm, callback) { var media = { anchor: uri.spec }; if (/\.gif$|\.jpe?g$|\.pi?ng$/.test(uri.path)){ media.image = uri.spec; } else { switch (uri.host) { case "twitpic.com": media.image = "http://twitpic.com/show/thumb" + uri.path + ".jpg"; break; case "movapic.com": media.image = "http://image.movapic.com/pic/m_" + uri.path.substr(uri.path.lastIndexOf("/")+1) + ".jpeg"; break; case "gyazo.com": media.image = uri.spec; break; case "tweetphoto.com": media.image = "http://TweetPhotoAPI.com/api/TPAPI.svc/imagefromurl?size=thumbnail&url=" + uri.spec; break; case "twittgoo.com": util.httpGet(uri.spec + "/?format=atom", function(xhr){ media.image = xhr.responseXML.getElementsByTagName("icon")[0].textContent; callback(elm, media); }); return; case "yfrog.com": { let x = new XMLHttpRequest; x.open("HEAD", uri.spec + ".th.jpg", true); x.onreadystatechange = function(){ if (x.readyState == 4) { media.image = x.channel.URI.spec; callback(elm, media); } } x.send(null); } case "plixi.com": util.httpGet("http://api.plixi.com/api/tpapi.svc/photos/" + uri.path.substr(uri.path.lastIndexOf("/")+1), function(xhr){ media.image = xhr.responseXML.getElementsByTagName("ThumbnailUrl")[0].textContent; callback(elm, media); }); return; case "www.youtube.com": { let query = uri.path.substr(1).split("?")[1]; if (!query) break; let hash = query.split("&").filter(function(param) param.indexOf("v=")==0)[0]; if (!hash) break; media.image = "http://i.ytimg.com/vi/" + hash + "/1.jpg"; break; } case "f.hatena.ne.jp": { let [, userid, date] = uri.path.split("/"); media.image = ["http://img.f.hatena.ne.jp/images/fotolife/", userid.charAt(0), "/", userid, "/", date.substr(0, 8), "/", date, "_m.jpg"].join(""); break; } case "photomemo.jp": { let [, user, num] = uri.path.split("/"); util.httpGet(uri.prePath + "/" + user + "/rss.xml", function(xhr){ let items = xhr.responseXML.querySelectorAll("item"); for (let i=0, item; item = items[i]; i++){ if (item.querySelector("link").textContent == uri.spec) { media.image = item.querySelector("content").getAttribute("url"); callback(elm, media); return; } } }); return; } case "www.flickr.com": { let [,,user, id, id2, setId] = uri.path.split("/"); let imgReg; if (id == "sets" && id2) { imgReg = /; while((m=reg.exec(str))){ buf = str.substring(i, m.index); if (buf) x.appendChild(buf); let classValue = "twlist-link", href = ""; switch (m[0].charAt(0)){ case "@": classValue += " twlist-user"; href = "http://twitter.com/" + m[0].substr(1); break; case "#": classValue += " twlist-hash"; href = "http://twitter.com/search?q=%23" + m[0].substr(1); break; default: classValue += " twlist-url"; href = m[0]; } x.appendChild({m[0]}); i=reg.lastIndex; } buf = str.substr(i); if (buf) x.appendChild(buf); return x; } function onClick (evt) { if (evt.button == 2) return; evt.preventDefault(); evt.stopPropagation(); let where = (evt.ctrlKey || evt.button == 1) ? liberator.NEW_TAB : liberator.CURRENT_TAB; let url = evt.target.getAttribute("href"); liberator.open(url, {where: where}); } function onReply (elm, isDirectMessage) { let item = elm.parentNode.parentNode; let label = item.getAttribute("searchlabel"); let cmd = "tw " + (isDirectMessage ? "D @" : "@") + label + " "; commandline.open(":", cmd, modes.EX); window.focus(); } function onRetweet(elm){ let id = elm.parentNode.parentNode.value; plugins.twittperator.OAuth.post("http://api.twitter.com/1/statuses/retweet/" + id + ".json", null, function(text){ }); } function onFav (elm) { let id = elm.parentNode.parentNode.value; let fav = elm.value; if (fav == "\u2605") { plugins.twittperator.OAuth.post("http://api.twitter.com/1/favorites/destroy/" + id + ".json", null, function(text){ elm.value = "\u2606"; }); } else { plugins.twittperator.OAuth.post("http://api.twitter.com/1/favorites/create/" + id + ".json", null, function(text){ elm.value = "\u2605"; }); } } function onKeyDown(event){ switch (event.keyCode){ case event.DOM_VK_RETURN: case event.DOM_VK_ENTER: let txt = event.target.value; if (txt){ if (/^@\w+#\d+$/.test(txt.trim())) return; liberator.execute('tw ' + txt, null, true); event.target.value = ""; event.target.blur(); } break; } } onLoad(); // vim: sw=2 ts=2 et filetype=javascript: