node-creation-observer

Callback binding for HTML Node creation events

Verzia zo dňa 21.05.2016. Pozri najnovšiu verziu.

Tento skript by nemal byť nainštalovaný priamo. Je to knižnica pre ďalšie skripty, ktorú by mali používať cez meta príkaz // @require https://updategreasyfork.deno.dev/scripts/19857/126895/node-creation-observer.js

/**
 * https://github.com/soufianesakhi/node-creation-observer-js
 * MIT licensed
 * Copyright (c) 2016 Soufiane Sakhi
 */

var NodeCreationObserver = function () {
    var mutationObserver = null;
    var observedNodeAttribute = "node-creation-observer";
    var listeners = {};
    var options = {
        childList: true,
        subtree: true
    };

    function ListenerContext(removeOnFirstMatch) {
        this.callbacks = [];
        this.removeOnFirstMatch = removeOnFirstMatch == undefined ? false : removeOnFirstMatch;
    }

    function onMutationCallback(mutationRecordArray) {
        Object.keys(listeners).forEach(function (selector) {
            invokeCallbacks(selector);
        });
    }

    function invokeCallbacks(selector) {
        var callbacks = listeners[selector].callbacks;
        var elements = document.querySelectorAll(selector);
        var newElements = filterNewElements(elements);
        if (newElements.length > 0) {
            if (listeners[selector].removeOnFirstMatch) {
                removeListener(selector);
            }
            newElements.forEach(function (element) {
                callbacks.forEach(function (callback) {
                    callback.call(element, element);
                });
            });
        }
    }

    function filterNewElements(elements) {
        var newElements = [];
        for (var i = 0; i < elements.length; i++) {
            var element = elements[i];
            var attr = element.getAttribute(observedNodeAttribute);
            if (attr == null) {
                element.setAttribute(observedNodeAttribute, 1);
                newElements.push(element);
            }
        };
        return newElements;
    }

    function observe() {
        if (mutationObserver == null) {
            mutationObserver = new MutationObserver(onMutationCallback);
            mutationObserver.observe(document.documentElement, options);
        }
    }

    function removeListener(selector) {
        delete listeners[selector];
        if (Object.keys(listeners).length == 0) {
            stopObserving();
        }
    }

    function stopObserving() {
        if (mutationObserver != null) {
            mutationObserver.disconnect();
            mutationObserver = null;
        }
    }

    return {
        onCreation: function (selector, callback, removeOnFirstMatch) {
            if (!listeners[selector]) {
                listeners[selector] = new ListenerContext(removeOnFirstMatch);
            }
            listeners[selector].callbacks.push(callback);
            observe();
            if (document.querySelector(selector) != null) {
                invokeCallbacks(selector);
            }
        },
        remove: removeListener,
        stop: function () {
            listeners = {};
            stopObserving();
        }
    };
} ();