Greasy Fork is available in English.

setMutationHandler

MutationObserver wrapper to wait for the specified CSS selector

< Feedback on setMutationHandler

Review: Good - script works

FFW
§
Posted: 2016-04-27
Edited: 2016-04-27

Catching every text node

Hi wOxxOm

Awhile back, I tried to use this library to catch every text node with * as a selector but didn't seem to do that, at least wouldn't catch all. Was that something expected or was I missing something? I was trying to have specific text replaced with another whenever it appears in a page.

Also would be cool to have an option in the library to return elements in jquery form for easy processing.

woxxomAuthor
§
Posted: 2016-04-27

It's a simple wrapper and it won't expand '*' to individual nodes because this selector also matches any container even if it has many sub-nodes. Currently you'll have to do it manually:

setMutationHandler(document, '*', function(nodes) {
    for (var i=0, len=nodes.length, node; i<len && (node=nodes[i]); i++) {
        if (!node.children.length) {
            if (node.textContent.indexOf('some text')) {
                node.textContent = node.textContent.replace('some text', 'another text');
            }
        } else {
            var subnodes = node.querySelectorAll('*');
            for (var j=0, len2=subnodes.length, n; j<len2 && (n=subnodes[j]); j++) {
                if (n.textContent.indexOf('some text')) {
                    n.textContent = n.textContent.replace('some text', 'another text');
                }
            }
        }
    }
    return true; // continue processing this mutation batch
});

I've used a plain for-loop because '*' matches a lot of nodes and array function callbacks are much slower as you can see on jsperf benchmarks. However if the page you're processing doesn't generate a lot of mutations and nodes you can use array functions, of course.

As for jQuery, this smallsize library doesn't use it by design.

FFW
§
Posted: 2016-04-27

Great, still haven't test it though. Also another question.. In general it seems like the mutation function would always run multiple time and repeat the process unless you have a switch like setting an attribute attr('DONE','true'). Is there a better solution for this?

woxxomAuthor
§
Posted: 2016-04-27

You can disconnect the observer, see the examples.

FFW
§
Posted: 2016-04-27
Edited: 2016-04-27

I want to keep the mutation running for new elements to come. An example to show what I mean..

setMutationHandler(document, '#vanilla_discussion_index', function(n) { console.log('TEST'); return true; });

console.log('TEST'); would run three times in here.

woxxomAuthor
§
Posted: 2016-04-27

The other two times it invokes are caused by text nodes being added to this element. See for yourself:

setMutationHandler(document, '#vanilla_discussion_index', function(n, mutation) {
    console.log("%O - %O", mutation.target, mutation.addedNodes[0]);
    return true;
});

I've added this behavior intentionally however now I understand it can cause problems... I'll think up some way of customizing it.

FFW
§
Posted: 2016-04-27

I can see it now, not that I fully get though. :neutral: :smiley:

Post reply

Sign in to post a reply.