Wait For Selector

Waits for selectors to match newly added nodes

Verze ze dne 14. 09. 2021. Zobrazit nejnovější verzi.

Tento skript by neměl být instalován přímo. Jedná se o knihovnu, kterou by měly jiné skripty využívat pomocí meta příkazu // @require https://update.greasyfork.org/scripts/432418/970669/Wait%20For%20Selector.js

K instalaci tototo skriptu si budete muset nainstalovat rozšíření jako Tampermonkey, Greasemonkey nebo Violentmonkey.

You will need to install an extension such as Tampermonkey to install this script.

K instalaci tohoto skriptu si budete muset nainstalovat rozšíření jako Tampermonkey nebo Violentmonkey.

K instalaci tohoto skriptu si budete muset nainstalovat rozšíření jako Tampermonkey nebo Userscripts.

You will need to install an extension such as Tampermonkey to install this script.

K instalaci tohoto skriptu si budete muset nainstalovat manažer uživatelských skriptů.

(Už mám manažer uživatelských skriptů, nechte mě ho nainstalovat!)

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

(Už mám manažer uživatelských stylů, nechte mě ho nainstalovat!)

// ==UserScript==
// @name         Wait For Selector
// @version      0.1.0
// @description  Waits for selectors to match newly added nodes
// @author       Kumirei
// @include      *community.wanikani.com*
// @grant        none
// ==/UserScript==

(function($) {
    // Create new observer on body to monitor all DOM changes
    let observer = new MutationObserver(mutationHandler)
    observer.observe(document.getElementsByTagName('body')[0], {childList: true, subtree: true})

    // Interface for interacting with the library
    let interface = {
        version: GM_info.script.version,
        observer: observer,
        wait: waitForSelector,
        unwait: unwaitID,
        waits: {},
        waitsByID: {},
        nextID: 0
    }

    // Start
    installInterface()

    // Creates a new entry to search for whenever a new element is added to the DOM
    function waitForSelector(preSelector, selector, callback) {
        if (selector.match(`${preSelector}$`) === null) throw ('preSelector must match the end of the selector')
        if (!interface.waits[selector]) interface.waits[selector] = {}
        interface.waits[selector][interface.nextID] = callback
        interface.waits[selector].pre = preSelector
        interface.waitsByID[interface.nextID] = selector
        return interface.nextID++
    }

    // Deletes a previously registered selector
    function unwaitID(ID) {
        delete interface.waits[interface.waitsByID[ID]][ID]
    }

    // Makes sure that the public interface is the newest version and the same as the local one
    function installInterface() {
        let wfs = window.wkfe
        if (!wfs) window.wfs = interface
        else if (wfs.version < interface.version) {
            wfs.version = interface.version
            wfs.observer.disconnect()
            wfs.observer = interface.observer
            wfs.wait = interface.wait
            wfs.unwait = interface.unwait
        }
        interface = wfs || interface
    }

    // Searches the added nodes and matches them with the provided selectors. Calls the callback for every match.
    function mutationHandler(mutations) {
        for (let mutation of mutations) {
            let added = mutation.addedNodes
            for (let node of added) {
                if (node.nodeType === 1) {
                    let sibling = node.previousElementSibling
                    let target = sibling ? sibling : node.parentElement
                    for (let selector in interface.waits) {
                        let query = (sibling?'+ ':'> ')+interface.waits[selector].pre
                        $(target).find(query).each((i, e)=>{
                            $(selector).each((I, E)=>{
                                if (e.isSameNode(E)) {
                                    for (let callback of Object.values(interface.waits[selector])) {
                                        if (typeof callback === "function") callback(E)
                                    }
                                }
                            })
                        })
                    }
                }
            }
        }
    }
})(window.jQuery);