WGSM - PluginParty

It's a plugin party! List all available WindowsGSM plugins on a single page and filter through them with a searchbar!

Voor het installeren van scripts heb je een extensie nodig, zoals Tampermonkey, Greasemonkey of Violentmonkey.

Voor het installeren van scripts heb je een extensie nodig, zoals {tampermonkey_link:Tampermonkey}.

Voor het installeren van scripts heb je een extensie nodig, zoals Tampermonkey of Violentmonkey.

Voor het installeren van scripts heb je een extensie nodig, zoals Tampermonkey of Userscripts.

Voor het installeren van scripts heb je een extensie nodig, zoals {tampermonkey_link:Tampermonkey}.

Voor het installeren van scripts heb je een gebruikersscriptbeheerder nodig.

(Ik heb al een user script manager, laat me het downloaden!)

Voor het installeren van gebruikersstijlen heb je een extensie nodig, zoals {stylus_link:Stylus}.

Voor het installeren van gebruikersstijlen heb je een extensie nodig, zoals {stylus_link:Stylus}.

Voor het installeren van gebruikersstijlen heb je een extensie nodig, zoals {stylus_link:Stylus}.

Voor het installeren van gebruikersstijlen heb je een gebruikersstijlbeheerder nodig.

Voor het installeren van gebruikersstijlen heb je een gebruikersstijlbeheerder nodig.

Voor het installeren van gebruikersstijlen heb je een gebruikersstijlbeheerder nodig.

(Ik heb al een beheerder - laat me doorgaan met de installatie!)

// ==UserScript==
// @name        WGSM - PluginParty
// @author      WirlyWirly
// @version     0.8
// @namespace   https://github.com/WirlyWirly

// @match       https://windowsgsm.com/*

// @icon        https://windowsgsm.com/favicon.ico
// @description It's a plugin party! List all available WindowsGSM plugins on a single page and filter through them with a searchbar!

// @homepage    https://gist.github.com/WirlyWirly/fb6fce9864eb8d1701cb226b6f83cb45/

// @grant       GM_xmlhttpRequest

// @run-at 		document-end
// ==/UserScript==

function pluginParty() {
    // The main pluginParty function; Load each plugins-page and then list all available plugins onto the current page
    
    let mainListElement = document.querySelector("main div.mx-auto")
    let navBarElement = mainListElement.querySelector("nav[aria-label='Page navigation']").parentElement

    // let pluginCount = mainListElement.childNodes[0].querySelector('span')
    let pluginCount = mainListElement.childNodes[0].querySelectorAll('span')[2].innerText
    mainListElement.childNodes[0].innerHTML = `<span class="font-semibold text-gray-900 dark:text-white"><a href="https://gist.github.com/WirlyWirly/fb6fce9864eb8d1701cb226b6f83cb45">PluginParty</a></span> [v${GM_info.script.version}] - Showing All <span class="font-semibold text-gray-900 dark:text-white">${pluginCount}</span> Plugins`

    // Clean the current page by removing all listed plugins
    mainListElement.querySelectorAll("a[target='_blank']").forEach((item) => item.remove())

    let pageElements = navBarElement.querySelectorAll("li a")
    for (let element of pageElements) {
        // Create a placeholder element so that page results are displayed in-order

        let pageNumber = element.innerText
        let placeholder = document.createElement('div')
        placeholder.id = `placeholder${pageNumber}`

        mainListElement.insertBefore(placeholder, navBarElement)
    }

    for (let element of pageElements) {
        // Asychronous: For each page, get and append its list of plugins into the current page

        let placeholder = mainListElement.querySelector(`#placeholder${element.innerText}`)

        GM_xmlhttpRequest({
            'url': element.href,
            'method': 'GET',
            'onload': function(response) {
                let pageDOM = response.responseXML
                
                // The plugin elements for each page
                let pluginElements = pageDOM.querySelectorAll("main div.mx-auto a[target='_blank']")

                // Insert the plugins into the current page, above their corresponding placeholder
                for (let item of pluginElements) {
                    try{
                        // Remove 'WindowsGSM.' from the plugin title
                        let cleanedTitle = item.querySelector('h2').innerText.match(/^WindowsGSM\.(.*)/i, '')
                        item.querySelector('h2').innerText = cleanedTitle[1]
                    } catch(error) {
                        // console.log(error, item)
                    }

                    // Set the matching 'searchterm' attribute now so that searches are faster later
                    item.setAttribute('data-searchterm', item.querySelector('h2').innerText.toLowerCase())

                    mainListElement.insertBefore(item, placeholder)
                }

                // pluginCount.innerText++
                placeholder.remove()
            }
        })

    }

    // Remove the pageNavBar so that users don't constantly load dupe pages
    navBarElement.remove()

    // Create and inject the search bar above the plugins listing
    let searchBar = document.createElement('input')
    searchBar.id = 'searchBar'
    searchBar.type = 'text'
    searchBar.className = 'mb-4 w-full dark:bg-gray-800 text-gray-500 dark:text-gray-400 rounded-lg dark:border-gray-700 hover:bg-gray-100 dark:hover:bg-gray-700'
    searchBar.placeholder = 'Search Plugins...'

    mainListElement.insertBefore(searchBar, mainListElement.childNodes[0].nextSibling)
    let pluginElements = searchBar.addEventListener('click', function() {
        // When the search bar is clicked into, collect a list of all available plugins
        return pluginElements = mainListElement.querySelectorAll("a[target='_blank']")
    })

    searchBar.addEventListener('keyup', function() {
        // When a key is entered, filter the results based on each plugin-elements 'searchterm' attribute
        let term = searchBar.value.toLowerCase()

        pluginElements.forEach((item) => {
            if (item.dataset['searchterm'].includes(term)) {
                item.hidden = false
            } else {
                item.hidden = true
            }
        })
    })
}

let observer = new MutationObserver(function(mutation) {
    // Code to run when page changes are detected

    if (document.URL.match(/.+windowsgsm-plugins.*/)) {
        // The current webpage IS the plugins page, so run pluginParty...
        pluginParty()
    } else {
        // The current webpage is NOT the plugins page, so do nothing...
        return
    }
})

// --------------- START ---------------

let target = document.querySelector('main')
let config = { childList: true }

if (document.URL.match(/.+windowsgsm-plugins.*/)) {
    // The current webpage IS the plugins page, so run pluginParty...
    pluginParty()
    observer.observe(target, config)
} else {
    // The current webpage is NOT the plugins page, so wait for changes...
    observer.observe(target, config)
}