Greasy Fork

GGn Title and Screenshots Formatter

Formats title, sets alias if applicable and has buttons to undo. Removes screenshots until they are a multiple of 4

目前为 2023-11-27 提交的版本。查看 最新版本

// ==UserScript==
// @name         GGn Title and Screenshots Formatter
// @namespace    none
// @version      6
// @description  Formats title, sets alias if applicable and has buttons to undo. Removes screenshots until they are a multiple of 4
// @author       ingts
// @match        https://gazellegames.net/upload.php
// ==/UserScript==
let titleInput = document.getElementById('title')

// changing the category changes the form using a server request and the title input is replaced
document.getElementById('categories').addEventListener('change', () => {
    new MutationObserver((mutations, observer) => {
        titleInput = document.getElementById('title')
        observer.disconnect()
    }).observe(document.getElementById('upload_table'), {childList: true, subtree: true})
})

const tInterval = setInterval(() => {
    if (document.activeElement === titleInput || !titleInput.value)
        return
    // to allow upload scripts that use the title input's value to set the title before formatting
    setTimeout(() => {
        let origTitle = titleInput.value
        const aliases = document.getElementById('aliases')
        let origAlias = aliases.value

        const smallWords = /^(a|an|and|as|at|but|by|en|for|if|in|nor|of|on|or|per|the|to|v.?|vs.?|via)$/i
        const alphanumericPattern = /([A-Za-z0-9\u00C0-\u00FF])/
        const wordSeparators = /([ :–—-])/

        let titleAfterTitleCase = titleInput.value
            .replace(/\s/g, ' ')
            .replace(/ ~ /, ': ').replace(/ ~/, ': ').replace(/~$/, '').replace(/ ~$/, '').replace(/ - /, ': ').replace(/ -/, ': ').replace(/-$/, '')
            .trim().toLowerCase()
            .split(wordSeparators)
            .map(function (current, index, array) {
                if (
                    /* Check for small words */
                    current.search(smallWords) > -1 &&
                    /* Skip first and last word */
                    index !== 0 &&
                    index !== array.length - 1 &&
                    /* Ignore title end and subtitle start */
                    array[index - 3] !== ':' &&
                    array[index + 1] !== ':' &&
                    /* Ignore small words that start a hyphenated phrase */
                    (array[index + 1] !== '-' ||
                        (array[index - 1] === '-' && array[index + 1] === '-'))
                ) {
                    return current.toLowerCase()
                }
                /* Capitalize the first letter */
                return current.replace(alphanumericPattern, function (match) {
                    return match.toUpperCase()
                })
            })
            .join('')

        titleInput.value = titleAfterTitleCase

        if (document.getElementById('categories').value === 'Games') {
            const excludePattern = /[^a-zA-Z0-9 .?!@#$%^&*()_+\-=\[\]{};':"\\|,<>\/]+/g
            let excluded = titleInput.value.match(excludePattern)

            if (excluded && excluded.length === 1) {
                aliases.value ? aliases.value += ', ' + excluded.join('') : aliases.value = excluded.join('')
                titleInput.value = titleInput.value.replace(excludePattern, "").trim()
            } else if (excluded && excluded.length > 1) {
                aliases.value = titleInput.value
                titleInput.value = ''
                return
            }
        }

        if (titleAfterTitleCase !== origTitle || aliases.value !== origAlias) {
            document.querySelector("#title_tr > td.label").insertAdjacentHTML('beforeend', `<span style="color: #ebaf51;display: block;">Undo Title Formatter</span>
    <div id="tf-undo-buttons"></div>`)

            const buttonDiv = document.getElementById('tf-undo-buttons')

            if (titleAfterTitleCase !== origTitle) {
                const button1 = document.createElement('button')
                button1.textContent = 'Formatting'
                button1.type = 'button'
                button1.onclick = () => {
                    titleInput.value = origTitle
                }
                buttonDiv.append(button1)
            }
            if (aliases.value !== origAlias) {
                const button2 = document.createElement('button')
                button2.textContent = 'Alias'
                button2.type = 'button'
                button2.onclick = () => {
                    titleInput.value = titleAfterTitleCase
                    aliases.value = origAlias
                }
                buttonDiv.append(button2)
            }
        }
        clearInterval(tInterval)
    }, 2000)
}, 1000)

const screenshotInputs = document.getElementsByName('screens[]')
const removeButton = document.querySelector("#image_block > a:nth-child(3)")
const sInterval = setInterval(() => {
    for (let i = 0; i < screenshotInputs.length; i++) {
        if (!screenshotInputs[i].value) {
            return
        }
    }
    const number = screenshotInputs.length < 4 ? screenshotInputs.length : Math.min(Math.floor(screenshotInputs.length / 4) * 4, 20)
    while (screenshotInputs.length > number) {
        removeButton.click()
    }
    clearInterval(sInterval)
}, 1000)

document.querySelector("#image_block > a:nth-child(2)").addEventListener('click', () => {
    clearInterval(sInterval)
})