茂木さんは別に嫌いじゃないんだけど、茂木さんの連続つぶやきをまとめている人たちはできれば手分けしてやってほしいなと思ったので作った(思ったのは本当だけど、もちろんそれだけが作った理由ではない)。
必要な設定をした上で、Operaでuser.js用のフォルダに置いとけば、勝手に働くはず。自分用バージョンとちょっと違うので、ちゃんと試してないから あんまり自信ない。
茂木さんは別に嫌いじゃないんだけど、茂木さんの連続つぶやきをまとめている人たちはできれば手分けしてやってほしいなと思ったので作った(思ったのは本当だけど、もちろんそれだけが作った理由ではない)。
必要な設定をした上で、Operaでuser.js用のフォルダに置いとけば、勝手に働くはず。自分用バージョンとちょっと違うので、ちゃんと試してないから あんまり自信ない。
togetterのまとめのページで”残りを読む”ボタンをいちいち押すのがめんどくさいので作った。
大長編なまとめだと結構切ないことになりますが、ご了承ください。
Operaでuser.js用のフォルダに置いとけば、勝手に働きます。
togetterのまとめページで、オリジナルのtweet(要するにパーマリンク)へのリンクが素直じゃないので作った。
ついでに、個人的には名前のところもtogetter内のユーザページじゃなくてtwitter.comのユーザページに飛んで欲しいので、そういう処理もします。
javascript:(function(){t='https://twitter.com/';l=document.querySelectorAll('.status_right');for(i = 0;i<l.length;i++){u=l[i].querySelector('.status_name');n=u.textContent;u.href=t+n;s=l[i].querySelector('[onclick]');if(s){d=s.getAttribute('onclick');s.removeAttribute('onclick');d=d.replace(/^.*\"(.*)\".*$/,'$1');s.setAttribute('href',t+n+'/status/'+d);}}})()
http://togetter.com/li/~なページでアドレスバーに貼り付けるとかするとリンク先がいろいろ置き換わります。
Operaでuser.js用のフォルダに置いとけば、勝手に働きます。
http://mattz.xii.jp/sites/default/files/togetter-filter_100.js
http://mattz.xii.jp/sites/default/files/togetter-filter_100b1.js
user.jsそのものの使い方は省略します。
このuser.jsを有効な状態でTogetterの「注目のまとめ」などの一覧ページを開くと、各まとめのタイトルの左に[NGワード登録]というボタンが表示されま す。
これをクリックすると、入力用のダイアログが開きます。初期状態ではそのまとめのタイトルが既に入力済みの状態になっていますので、適宜編集して[OK]ボタンを押すと、そこで登録した単語(文字列)を含むまとめは、「NGタイトルにより非表示にされています(クリックで再表示)」という表示に置き換わります。
これをクリックすると、フィルタリング対象のまとめでも表示し、登録してしまったNGワードを削除することもできます。
なお、「,」半角のカンマはNGワードに使えません。
このuser.jsを有効な状態でTogetterの「注目のまとめ」などの一覧ページを開き、各まとめのまとめた人のアイコンをクリックすると、「このユーザの作 成したまとめを非表示にしますか?:○○」というダイアログが開きます。
[OK]を押すと、以後その人の作成したまとめは、一覧に表示されなくなります。復帰させたい場合は、その人のプロフィールページ(http://togetter.com/id/○○)に行くと、ページの左上の方に「このユーザのまとめは現在フィルタリング対象です。→[解除]」というメッセージが表示されますので、「解除」ボタンをクリックしてください。
このuser.jsを有効な状態でTogetterの何かのまとめを開き、コメント欄の誰かのアイコンをクリックすると、「このユーザのコメントを非表示にしますか ?:○○」というダイアログが開きます。
[OK]を押すと、以後その人のコメントは、どのまとめページにも表示されなくなります。復帰させたい場合は、その人のプロフィールページ(http://togetter.com/id/○○)に行くと、ページの左下の方に「このユーザのコメントは現在フィルタリング対象です。→[解除]」というメッセージが表示されますので、「解除」ボタンをクリックしてください。
このuser.jsを有効な状態でTogetterの何かのまとめを開き、誰かのつぶやき部分をクリックすると、
このような物が表示されます。
[Pick-up]を押すと、その人のtweetsだけを残して、他の人のtweetを非表示にします。
[Remove]を押すと、Pickupの逆でその人のtweetsを非表示にします。
色付きの■部分を押すと、その人のtweetsのフォントカラーをその色に、背景色をアイボリーに変更して、少し目立つようにします。
やめたいときは「Click (or press [ESC]) to close.」部分をclickするか、Ecsキーを押してください。
また、これらの抽出/非表示/強調はあくまで一時的なもので、ページを読み込み直すと元の状態に戻ります。
http://mattz.xii.jp/sites/default/files/togetter_421.js
2011/10/05:いくつか設定項目を追加しました。
http://mattz.xii.jp/sites/default/files/togetter_410.js
2011/06/10:いくつか設定項目を追加しました。
http://mattz.xii.jp/sites/default/files/togetter_401.js
2011/06/06:Togetterのhtmlが変更になったようで「最初から"もっと読む"」が効いていなかったので修正しました。
http://mattz.xii.jp/sites/default/files/togetter_400.js
多少修正して、とりあえず4.0.0としてはフィックスします。
http://mattz.xii.jp/sites/default/files/togetter_400b1.js
とりあえず版。Togetterさん、リニューアルで以前に比べればだいぶすっきりしましたけど、個人的にはまだ要らない(サービスとし て必要なのは分かりますが)要素が多いので、その辺をすっきりするだけです。まぁ、ほとんどの項目はuser.cssで消せるんですけどね。
フィルタリングしたりするのは、別ファイルに分けようかと検討中。
なんだっけ、でくぐったら「もしかして:」で検索ワードだしてきたらこわい
に触発された。力不足でクロスブラウザにはできなかった。
追記その5:「Opera9.6 から「安全でなくなった」 UserJavaScript があるけ どイコール「危険」というわけでもない話」を併せてお読みください。
拾う単語は、Yahoo!の急上昇ワードランキングから取得するようにした。Twitterの日本のTrendsから、とか、他の例えばランダム単語APIなんかでもいい。ただしその場合は若干スクリプトを変更する必要がある。Google TrendsのAPI欲しいんだけどないのかな?
あと、xmlをGETしてくるところは http://javascript.g.hatena.ne.jp/edvakf/20100329/1269881699 をほぼそのまま利用させてもらった。edvakfさんに感 謝。
追記その4:追記の1~3はそうはいってもやっぱり恥ずかしいのでhtmlのコメントとして隠した。とにかくコメント欄参照のこと。
// ==UserScript==
// @name nandakke.js
// @author mattz
// @namespace http://mattz.xii.jp
// @license public domain
// @description 「なんだっけ」でググると「もしかして:」を提示してくれるuser.js for Opera
// @published 2011-05-13
// @version 0.0.2
// @include http://www.google.com/search?*
// @include http://www.google.co.jp/search?*
// ==/UserScript==
(function(){
var _document = document;
var call = Function.prototype.call,
indexOf = Array.prototype.indexOf,
splice = Array.prototype.splice,
preventDefault = Event.prototype.preventDefault,
removeChild = Node.prototype.removeChild,
createElement = Document.prototype.createElement,
push = Array.prototype.push,
appendChild = Node.prototype.appendChild,
parseFromString = DOMParser.prototype.parseFromString,
getElementsByTagName = Document.prototype.getElementsByTagName,
parseInt = window.parseInt,
random = Math.random,
encodeURIComponent = window.encodeURIComponent,
setAttribute = Element.prototype.setAttribute,
getElementById = Document.prototype.getElementById,
split = String.prototype.split;
var scripts = [];
var callbacks = [];
opera.addEventListener('BeforeScript', function(e) {
indexOf.call = splice.call = preventDefault.call = removeChild.call = call;
var s = e.element;
var index = indexOf.call(scripts, s);
if (index >= 0) {
callbacks[index].call(null, s.text);
splice.call(scripts, index, 1);
splice.call(callbacks, index, 1);
preventDefault.call(e);
removeChild.call(s.parentNode, s);
}
}, false);
var xGet = function (url, callback) {
createElement.call = appendChild.call = push.call = call;
var s = createElement.call(_document, 'script');
s.src = url;
appendChild.call(_document.body, s);
push.call(scripts, s);
push.call(callbacks, callback);
}
var rand_word = function(xml) {
parseFromString.call = call = setAttribute.call = createElement.call = appendChild.call = getElementById.call = call;
var xmldom = new DOMParser();
xmldom.async = false;
var dom = parseFromString.call(xmldom, xml, "application/xml");
if (! dom) return false;
var is = getElementsByTagName.call(dom, 'item');
var r = parseInt(random() * 20);
var word = is[r].getElementsByTagName('title')[0].textContent;
var b = createElement.call(_document, 'b');
b.textContent = word;
var a = createElement.call(_document, 'a');
a.href = '/search?hl=ja&rls=ja&spell=1&q=' + encodeURIComponent(word);
setAttribute.call(a, 'class', 'spell');
appendChild.call(a, b);
var span = createElement.call(_document, 'span');
span.textContent = 'もしかして: ';
setAttribute.call(span, 'class', 'spell');
setAttribute.call(span, 'style', 'color:#cc0000');
var p = createElement.call(_document, 'p');
setAttribute.call(p, 'class', 'ssp');
appendChild.call(p, span);
appendChild.call(p, a);
appendChild.call(getElementById.call(_document, 'topstuff'), p);
}
var init = function() {
split.call = call;
var a = split.call(location.search, /[\?&]/);
for(var i = 0; i < a.length; i++) {
var q = split.call(a[i], /=/);
if ('q' == q[0] && '%E3%81%AA%E3%82%93%E3%81%A0%E3%81%A3%E3%81%91' == q[1]) {
xGet('http://searchranking.yahoo.co.jp/rss/burst_ranking-rss.xml', rand_word);
return false;
}
}
}
window.addEventListener('DOMContentLoaded', init, false);
})();
http://d.hatena.ne.jp/mono-hate/20110405/1302015546 を読んで、コメントもして、ついでなので作った。色々ツメが甘いけど、それはいつものことなので気にしないで公開する。後悔はしない。
自分の環境でしか確認してないので、他人様の環境ではちゃんと動かないかもしれませんが、そもそも「Googleの検索結果ページ」って一口に言っても人によって違うもの見てると思うし、あくまで僕の環境に最適化したものしか作る気はないです。ごめんなさい。
// ==UserScript==
// @name mod-google-search-result
// @author mattz
// @namespace http://mattz.xii.jp
// @license public domain
// @description add link to qdr=m3 and qdr=m6 on side-bar
// @published 2011-04-06
// @version 0.0.1
// @include http://www.google.com/search?*
// @include http://www.google.co.jp/search?*
// ==/UserScript==
(function(){
var create_qdr = function(m) {
var ml = document.createElement('li');
ml.setAttribute('class', 'tbou');
ml.id = 'qdr_m' + m;
var a = document.createElement('a');
a.href = location.href.replace(/[&\?](tbs|as_qdr)=[^&]*/, '') + '&as_qdr=m' + m;
a.appendChild(document.createTextNode(m + 'か月以内'));
ml.appendChild(a);
return ml;
}
var init_qdr = function() {
var std = document.querySelector('#qdr_m6');
if (! std) std = document.querySelector('#qdr_y');
if (! std) return false;
if (! document.querySelector('#qdr_m3')) {
std.parentNode.insertBefore(create_qdr(3), std);
}
if (! document.querySelector('#qdr_m6')) {
std.parentNode.insertBefore(create_qdr(6), std);
}
}
window.addEventListener('DOMContentLoaded', init_qdr, false);
})();
ちなみに見た目はこんな感じになります。
※リンクにdottedな下線が入っているのはuserCSSによるものです。
takefさんのLDRにブックマーク数を表示するスクリプトをここ半年くらい使っていたのだけど、「s」で読みすすめている分にはいいのだけど、「a」で戻ったりするとブックマーク数アイコンが二重に表示されて微妙に気持ち悪いので、ちょこっと改変。ついでなので、主に利用しているlivedoor clipも表示するように。
// ==UserScript==
// @include http://reader.livedoor.com/reader/*
// ==/UserScript==
(function () {
var entryurl = "http://b.hatena.ne.jp/entry/";
var apiurl = "http://b.hatena.ne.jp/entry/image/";
var entryurl2 = "http://clip.livedoor.com/page/";
var apiurl2 = "http://image.clip.livedoor.com/counter/";
register_hook('before_printfeed', function(feed) {
var items = feed['items'];
var len = items.length;
for (var i = 0; i < len; i++) {
var item = items[i];
var url = item['link'].replace('#', '%23');
if(! item['title'].match(/<a href=/)) {
item['title'] += '<a href="' + entryurl + url + '"><img src="' + apiurl + url + '"></a>';
item['title'] += '<a href="' + entryurl2 + url + '"><img src="' + apiurl2 + url + '"></a>';
}
}
});
})();
Operaにはfastforwardという素敵な機能があって、真っ当なつくりのページであればこれで事足りるのですが、世の中真っ当なつくりのページというのはなかなかございませんもので、このようなものを作りました。
もちろん、extreme-fast-forward.jsなんていうものが既にあるこ とは百も承知なのですが、oAutoPagerizeが好みではないもので、SITEINFOとか導入してませんし。
やってることは、rel='next'なlink要素がない場合は、ページ内のリンクから次っぽいリンクを見つけて(※)、そのリンク先URLをnextページとしてrel='next'なlink要素を付加するというものです。
※ちなみにa要素のinnerTextに「次」とか「つぎ」とか「Next」があればそのリンクは次のページへのリンクであろう、とか、a要素のinnerTextがなくて、a要素の中身が画像であってそのalt属性に「次」とか「つぎ」とか「Next」とかあるならそのリンクは次のページへのリンクであろう、みたいなやり方です。
副作用として次原隆二みたいなリンクに反応しちゃうことがありますが、まぁ大体うまくいっています。よろしければご利用下さい。
// ==UserScript==
// ==/UserScript==
(function (){
var makeNextrel = function(url) {
var n = document.createElement('link');
n.rel = 'Next';
n.href = url;
document.querySelector('head').appendChild(n);
return false;
}
var regexpnext = new RegExp(/(次|つぎ)( ?|[のへ])|next|[Nn][Ee][Xx][Tt])/i);
window.addEventListener(
'DOMContentLoaded',
function(){
var needsNext = true;
var links = document.querySelectorAll('link');
var i;
for(i = 0; i links.length; i++) {
if(links[i].rel.match(/next/i)) {
needsNext = false;
return false;
}
}
var ancs = document.querySelectorAll('a');
var len = ancs.length;
var linkto = '';
for(i = 0; i len; i++) {
if(ancs[i].href) {
linkto = ancs[i].href;
if(ancs[i].innerText.match(regexpnext)){
needsNext = makeNextrel(linkto);
} else if('IMG' == ancs[i].firstChild.tagName){
var f = ancs[i].firstChild;
if(f.getAttribute('alt') && f.getAttribute('alt').match(regexpnext)) {
needsNext = makeNextrel(ancs[i].href);
} else if(f.getAttribute('title') && f.getAttribute('title').match(regexpnext)) {
needsNext = makeNextrel(ancs[i].href);
}
}
}
if(!needsNext) {
break;
}
}
},false
);
})();
var regexpnext = new RegExp(/(次|つぎ)( ?|[のへ])|next|[Nn][Ee][Xx][Tt])/i);
のところをお好みの正規表現に変えてあげれば、これでうまく行かないページでもどうにかなるはずですが、正規表現なんか知らんという方はご相談下さい。
2011/5末のリニューアルに伴い、リンク削除。
自分で使っていて見つけた不具合の対応だの、気に入らないところの調整だの追加したい機能だのがちょこちょこと出てくるので、結構頻繁にバージョンアップしています。で、本日現在の最新版。
http://mattz.xii.jp/sites/default/files/togetter_3_0_4.js
ちなみにバージョン2系の更新履歴はこんな感じ。
// 2.0.0 b1 2010/09/15 リリース // 2.0.0 b2 2010/09/16 RT省略時のURLがリンクにならないのをとりあえず対応 // タイトルのNGワードフィルタ機能追加 // 2.0.0 b3 2010/09/16 まとめの時系列が逆転しているtweetにマークする機能追加 // 2.0.0 2010/09/22 まとめた人のIDでフィルタリングする機能追加 // 2.0.1 2010/10/01 リニューアル対応, // 設定キャンセルボタンの追加 // 2.0.2 2010/10/04 全体がRTであるtweet(意味があるというのもわかるが邪魔だ)を隠す機能を追加 // ついでにclip関係にバグがあったので修正 // 2.0.3 2010/10/05 サマリの省略方法の変更 // 2.0.4 2010/10/22 設定を開くボタンの表示位置を選べるようにした。 // 2.0.5 2010/11/29 はてなブックマークの変更に対応
「Togetter関連の諸々を一つにまとめてみました」で公開しているtogetter.jsですが、色々思うところあって、バージョン2を作りました。
http://mattz.xii.jp/sites/default/files/togetter_2_0_0.js
2010/10/01リニューアル対応版
http://mattz.xii.jp/sites/default/files/togetter_2_0_1.js
2010/10/04 バグ修正&機能追加
http://mattz.xii.jp/sites/default/files/togetter_2_0_2.js
あと、個人的には、下のようなuser cssと組み合わせるといいと思っています。色々非表示にしてますが、表示したい項目があったら、適宜修正してください。
div.list_body span[class]{ font-weight:normal !important; font-size:inherit !important; font-style:normal !important; color:inherit !important; } .favorite_box /* 誰がお気に入りしたかとか興味ない */ ,.hatena-star-star-container /* どれだけスターがついたかとか興味ない */ ,.tag_box /* どんなタグが付いているかにも興味ない */ ,.icon /* どれだけ気に入られてるかとか読まれてるかとか興味ない */ ,.ticket_img /* 新着かどうかとか興味ない */ ,.side_user_box /* 最近ログインしたユーザとか一番興味ない */ ,.blogparts_box /* BOTのつぶやきとか見る必要を感じない */ ,#footer /* フッタも要らね */ ,.twitter_button /* Tweetボタンイラネ */ ,.livedoor_button /* Clipボタンイラネ */ ,.delicious_button /* delciousボタンイラネ */ ,.hatena_button /* はてなブックマークボタンイラネ */ ,.followme_box /* フォローする気もない */ { display:none !important; } .info_description{ display:none; } a.info_title { background-image:none !important; /* 一覧画面のタイトルの下線だと思ったら画像かよ */ font-size:11pt !important; }
「まとめた人のIDによってフィルタリングする機能を追加」したバージョンを先ほど公開しました。
とりあえずこれでバージョン2としてはフィックスします。当面、バグ対応以外の修正は行いません。
つもりでしたが、機能追加しちゃいました。