Wait For Selector

Waits for selectors to match newly added nodes

Stan na 14-09-2021. Zobacz najnowsza wersja.

Ten skrypt nie powinien być instalowany bezpośrednio. Jest to biblioteka dla innych skyptów do włączenia dyrektywą meta // @require https://update.greasyfork.org/scripts/432418/970669/Wait%20For%20Selector.js

Aby zainstalować ten skrypt, wymagana jest instalacje jednego z następujących rozszerzeń: Tampermonkey, Greasemonkey lub Violentmonkey.

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

Aby zainstalować ten skrypt, wymagana jest instalacje jednego z następujących rozszerzeń: Tampermonkey, Violentmonkey.

Aby zainstalować ten skrypt, wymagana będzie instalacja rozszerzenia Tampermonkey lub Userscripts.

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

Aby zainstalować ten skrypt, musisz zainstalować rozszerzenie menedżera skryptów użytkownika.

(Mam już menedżera skryptów użytkownika, pozwól mi to zainstalować!)

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.

Będziesz musiał zainstalować rozszerzenie menedżera stylów użytkownika, aby zainstalować ten styl.

Będziesz musiał zainstalować rozszerzenie menedżera stylów użytkownika, aby zainstalować ten styl.

Musisz zainstalować rozszerzenie menedżera stylów użytkownika, aby zainstalować ten styl.

(Mam już menedżera stylów użytkownika, pozwól mi to zainstalować!)

// ==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);