透明人間

タイトルは釣りです。誰か開発してくれないかなあ。いや特に困ってはいないんですが。

「タイトルは釣りです」と本文に書いてあるエントリを非表示にするGreasemonkey - kokokubeta;


書いてみました。
AutoPagerizeに対応しています。
よろしければ、どうぞご利用ください。*1

追記

うひゃあ、日記に書いたら本当につくってくれる人がいた!うれしい。でもまだインストールの方法を理解できていない

はてなブックマーク - kokokubetaのブックマーク / 2008年12月15日

Greasemonkey を導入した Firefox で、InvisibleFisherman.user.js にアクセスすると、内容確認とインストールをおこなえます。ご参考まで!(追記ここまで)

// ==UserScript==
// @name           InvisibleFisherman
// @namespace      http://d.hatena.ne.jp/atkatanto/
// @include        http://*
// @include        https://*
// ==/UserScript==

var xpath1 = '//text()[contains(.,"タイトルは釣り")]/ancestor::*[local-name()="DIV" or local-name()="div"][1]';
var xpath2 =['//text()[substring(.,string-length(.)-3)="タイトル"]/../..', 
             '//text()[substring(.,string-length(.)-4)="タイトルは"]/../..',
             '//text()[starts-with(.,"釣り")]/../..'].join('|');
var xpath3 = 'ancestor::*[local-name()="DIV" or local-name()="div"][1]';

var patrol = function(i){
    var fisher = document.evaluate(xpath1, document, null, 7, null);
    for(i=0; i<fisher.snapshotLength; i++)
        fisher.snapshotItem(i).style.visibility = 'hidden';
    var suspect = document.evaluate(xpath2, document, null, 7, null);
    for(i=0; i<suspect.snapshotLength; i++)
        if(!!~suspect.snapshotItem(i).textContent.indexOf('タイトルは釣り'))
            document.evaluate(xpath3, suspect.snapshotItem(i), null, 9, null).singleNodeValue.style.visibility = 'hidden';
};
patrol();

var target;

GM_xmlhttpRequest({
    method : 'get',
    url    : 'http://wedata.net/databases/AutoPagerize/items.json',
    onload : function(res){
        if(res.status != 200) return;
        var info = [];
        try{
            info = eval(res.responseText).filter(function(v){
                return (new RegExp((v.data || 0).url || '^$')).test(location.href);
            }).map(function(v){
                return {
                    insertBefore : (v.data || 0).insertBefore,
                    pageElement  : (v.data || 0).pageElement
                };
            });
        }catch(e){}
        if(info.length == 0) return;
        if(info[0].insertBefore)
            target = (getFirstElementByXPath(info[0].insertBefore) || 0).parentNode;
        if(!target){
            var lastPageElement = getElementsByXPath(info[0].pageElement).pop();
            if (lastPageElement) target = lastPageElement.parentNode;
        }
        if(target)
            target.addEventListener('DOMNodeInserted', patrol, false);
    }
});

/*
 *  code and ideas from AutoPagerize
 *     [http://userscripts.org/scripts/show/8551]
 *  by swdyh [http://d.hatena.ne.jp/swdyh/] , and
 *     nanto_vi [http://nanto.asablo.jp/blog/]
 */

function getElementsByXPath(xpath, node) {
    var nodesSnapshot = getXPathResult(xpath, node,
        XPathResult.ORDERED_NODE_SNAPSHOT_TYPE)
    var data = []
    for (var i = 0; i < nodesSnapshot.snapshotLength; i++) {
        data.push(nodesSnapshot.snapshotItem(i))
    }
    return data
}

function getFirstElementByXPath(xpath, node) {
    var result = getXPathResult(xpath, node,
        XPathResult.FIRST_ORDERED_NODE_TYPE)
    return result.singleNodeValue
}

function getXPathResult(xpath, node, resultType) {
    var node = node || document
    var doc = node.ownerDocument || node
    var resolver = doc.createNSResolver(node.documentElement || node)
    // Use |node.lookupNamespaceURI('')| for Opera 9.5
    var defaultNS = node.lookupNamespaceURI(null)
    if (defaultNS) {
        const defaultPrefix = '__default__'
        xpath = addDefaultPrefix(xpath, defaultPrefix)
        var defaultResolver = resolver
        resolver = function (prefix) {
            return (prefix == defaultPrefix)
                ? defaultNS : defaultResolver.lookupNamespaceURI(prefix)
        }
    }
    return doc.evaluate(xpath, node, resolver, resultType, null)
}

function addDefaultPrefix(xpath, prefix) {
    const tokenPattern = /([A-Za-z_\u00c0-\ufffd][\w\-.\u00b7-\ufffd]*|\*)\s*(::?|\()?|(".*?"|'.*?'|\d+(?:\.\d*)?|\.(?:\.|\d+)?|[\)\]])|(\/\/?|!=|[<>]=?|[\(\[|,=+-])|([@$])/g
    const TERM = 1, OPERATOR = 2, MODIFIER = 3
    var tokenType = OPERATOR
    prefix += ':'
    function replacer(token, identifier, suffix, term, operator, modifier) {
        if (suffix) {
            tokenType =
                (suffix == ':' || (suffix == '::' &&
                 (identifier == 'attribute' || identifier == 'namespace')))
                ? MODIFIER : OPERATOR
        }
        else if (identifier) {
            if (tokenType == OPERATOR && identifier != '*') {
                token = prefix + token
            }
            tokenType = (tokenType == TERM) ? OPERATOR : TERM
        }
        else {
            tokenType = term ? TERM : operator ? OPERATOR : MODIFIER
        }
        return token
    }
    return xpath.replace(tokenPattern, replacer)
}

カイゼン

// ==UserScript==
// @name           InvisibleFisherman
// @namespace      http://d.hatena.ne.jp/atkatanto/
// @include        http://*
// @include        https://*
// ==/UserScript==

var xpath1 = '//text()[contains(.,"タイトルは釣り")]/ancestor::*[local-name()="DIV" or local-name()="div"][1]';
var xpath2 =['//text()[substring(.,string-length(.)-3)="タイトル"]/../..', 
             '//text()[substring(.,string-length(.)-4)="タイトルは"]/../..',
             '//text()[starts-with(.,"釣り")]/../..'].join('|');
var xpath3 = 'ancestor::*[local-name()="DIV" or local-name()="div"][1]';

var patrol = function(i){
    var fisher = document.evaluate(xpath1, document, null, 7, null);
    for(i=0; i<fisher.snapshotLength; i++)
        fisher.snapshotItem(i).style.visibility = 'hidden';
    var suspect = document.evaluate(xpath2, document, null, 7, null);
    for(i=0; i<suspect.snapshotLength; i++)
        if(!!~suspect.snapshotItem(i).textContent.indexOf('タイトルは釣り'))
            document.evaluate(xpath3, suspect.snapshotItem(i), null, 9, null).singleNodeValue.style.visibility = 'hidden';
};
patrol();

document.addEventListener('DOMNodeInserted', patrol, false);

特徴

  • コードをみじかく
  • AutoPagerizeに限らず動的コンテンツに対応
  • GM_系メソッドに非対応なブラウザのユーザースクリプトにしても動的コンテンツに対応*2

*1:Greasemonkeyアイコンの右クリックから「新規ユーザスクリプト」をえらびソースをコピー

*2:DOMNodeInsertedイベントをサポートしていれば