livedoor Reader でフィード一覧を絞り込み表示 [更新:20061115]
[20070223] 再アップデート版をファイルとして公開しました。id:reinyannyan:20070223:p1 をご覧下さい。
id:reinyannyan:20061006:p1 で実験的に作ったフィード一覧絞込みスクリプトを改善しました。フォルダ単位でのフィルタリングの他に、任意の JavaScript 式を条件として与えられるようになっています。また、"!" 以外にも
- !+
- !-
- !#
のコマンドを追加しました。
未読フィードが大量にある時に、今読みたいものを確実に効率よく読めるように、と考えて作りました。
特に、フィード一覧の表示数の上限を設定していて、未読フィードがそれよりもたくさん存在する場合に、絞込みを行うことで望みのフィードを漏れなく表示することが (ほぼ確実に) 可能になります。
使用例:
:! +news +tech [CR] // フォルダ "news" と "tech" のフィードを表示 :!+ news tech [CR] // 同上 :! -news [CR] // フォルダ "news" のフィードを消去 :! +tech #{ rate >= 4 } [CR] // "tech" フォルダのうち、レートが 4 以上のフィードを表示 :! [CR] // 元に戻す
Tips:
- "+" と "-" の条件で指定するフォルダ名は、内部的に正規表現として扱われます (例えば "-." は「未分類」の意味になります)
- 絞込み条件は一度に複数指定できます; 適用順は "+" "-" "#" です
- "+" の条件では、取得された全ての購読を対象に絞込みが行われます
- "+" 以外の条件では、現在 (直前) の絞込み状態に対して絞込みが行われます
- "rate" 以外のフィード情報:
- "unread_count" (未読数)
- "subscribers_count" (購読者数)
- "modified_on" (最終更新時刻 (Unix time))
- "subscribe_id" (フィード ID)
- "link" (サイトURL)
- "feedlink" (フィードURL)
- "folder" (フォルダ名)
- "title" (タイトル)
- "icon" (画像URL)
フォルダを活用していない方でも、「レートの高いものだけ」とか、「未読数の多いものだけ」など自在に絞り込むことで、迅速で効率的な未読処理が可能になるのではと思います。
// ==UserScript== // @name LDR Subscription Filter // @namespace http://d.hatena.ne.jp/reinyannyan/20061013/p1 // @include http://reader.livedoor.com/reader/* // ==/UserScript== (function(){with(unsafeWindow){ var fmodel; // model with custom filter applied var silent = false; function args2str(args) { return Array.from(args).join(" "); } function joinp(ary, sep) { return sep+ary.join(sep); } function show(data, desc) { // Preserve the current state of the list (for further subtraction) fmodel = data; if (silent) return desc; subs.view.clear(); subs.view.setClass(Config.view_mode); subs.view.print(SF[Config.view_mode](data)); $("subs_container").scrollLeft = 0; State.now_reading && set_focus(State.now_reading); subs.update_order(); update("right_bottom_navi", "right_top_navi"); message("Filtered subs:"+(desc||"")); } register_hook("after_subs_load", function() { fmodel = null; }); register_command("!|filter", function() { var OKs = [], NGs = [], EXs = []; args2str(arguments).replace(/([-+#])((?:{.+?}|\S+))/g, function(_, sign, v) { (sign == "+" && OKs || sign == "-" && NGs || EXs).push(v); }); if (!(NGs.length || OKs.length || EXs.length)) return show(subs.model); var applied = []; silent = true; try { OKs.length && applied.push(vi["!+"].apply(null, OKs)); NGs.length && applied.push(vi["!-"].apply(null, NGs)); EXs.length && applied.push(vi["!#"].apply(null, EXs)); } catch (e) { // User might have given incorrect #{} expression } finally { silent = false; } fmodel && show(fmodel, applied); }); register_command("!+", function() { var fs = Array.from(arguments); if (!fs.length) return; var _model = new Subscribe.Model; _model.load(subs.model.list.filter(function(v){ return fs.some(function(x){return v.folder.match(x)}); })); return show(_model, joinp(fs," +")); }); register_command("!-", function() { var fs = Array.from(arguments); if (!fs.length) return; var _model = new Subscribe.Model; // Perform subtraction from the current data set _model.load((fmodel||subs.model).list.filter(function(v){ return !fs.some(function(x){return v.folder.match(x)}); })); return show(_model, joinp(fs," -")); }); register_command("!#", function() { var fs = []; var ex = args2str(arguments); ex.replace(/{\s*(.+?)\s*}/g, function(_, v){ fs.push(v); }); if (!fs.length) fs.push(ex); var _model = new Subscribe.Model; _model.load((fmodel||subs.model).list.filter(function(v){ return fs.every/*some*/(function(x){with(v){return eval(x)}}); })); return show(_model, joinp(fs," #")); }); }})();
(いつもながら、プレーンな IE で動かしているものに with(unsafeWindow) を被せただけです。不具合がありましたらお知らせください)
追記 [20061017]:
複数タイプの条件を与えた場合の表示処理を迅速化しました。